Master the fundamental concepts of modern graphics apis (low level) through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksVulkan shaders do not access textures or buffers by name. Resources bind through descriptor sets: collections of descriptors, each specifying a type (uniform buffer, combined image sampler, storage buffer) and a GPU memory handle.
A descriptor set layout defines the schema: which bindings exist, their types, and array sizes. Multiple sets bind simultaneously, typically split by update frequency.
cLoading…
For example, set 0 updates once per frame, set 1 changes on material switch, set 2 changes every draw call. This split minimizes expensive rebinding. Unreal's Vulkan RHI and id Tech 7 use this pattern verbatim.
VK_ERROR_OUT_OF_POOL_MEMORYUNIFORM_BUFFER, COMBINED_IMAGE_SAMPLER, STORAGE_BUFFERDescriptor pools require upfront sizing because the driver allocates from a fixed pool. Pipeline layouts must match shader-declared bindings exactly.
You will model a descriptor set layout and calculate pool requirements for a multi-material renderer. This task asks you to count descriptors per type and print total pool allocation. Descriptor set design is one of the most expensive CPU-side operations in a Vulkan frame.
Model Vulkan's resource binding model:
VK_ERROR_OUT_OF_POOL_MEMORY when either budget runs out;# starts a comment.
cLoading…
Types: UNIFORM_BUFFER, STORAGE_BUFFER, COMBINED_IMAGE_SAMPLER, SAMPLED_IMAGE, SAMPLER, STORAGE_IMAGE. STAGES is free text (e.g. VERTEX|FRAGMENT), but it matters for compatibility.
end prints layout L: N binding(s). A repeated binding number gives layout L: binding N already defined, and a malformed line gives binding: N TYPE COUNT(1-8) STAGES.alloc S: VK_ERROR_OUT_OF_POOL_MEMORY (pool P is at maxSets M).alloc S: VK_ERROR_OUT_OF_POOL_MEMORY (needs N TYPE, pool P has K left).allocated S (layout L) from P: U of M sets used.write S: layout L has no binding B, write S: binding B is T, not U, write S: element E out of range (binding B has C);free (free S: pool P was not created with FREE_DESCRIPTOR_SET). It prints freed S and returns the budget. reset frees every set of the pool: reset P: freed N set(s).pool P: U/M sets, then , TYPE used/cap for each type the pool has.bind S: layout L is incompatible with set I of P (L2).draw P: set I is not bound, with (it was freed) if the bound set has since been freed;draw P: set I (S) binding B element E was never written;draw P: ok set 0 = S0, set 1 = S1.cLoading…
Command errors:
layout: NAME (unique)pool: NAME MAXSETS TYPE=COUNT... [free]alloc: SET POOL LAYOUT, alloc S: name in usewrite: SET BINDING ELEMENT TYPE RESOURCEfree: SET, reset: POOL, stats: POOLpipeline: NAME LAYOUT... (1-4 sets), pipeline P: unknown set layoutbind: PIPELINE SET_INDEX SET, draw: PIPELINEunknown command Xlayout L: missing end (at the end of input)Input:
cLoading…
Output:
cLoading…
Hidden tests cover the maxSets limit, a free-able versus a fixed pool, pool reset, type/element/binding write errors, compatibility between identical layouts with different names, an incompatible bind, a freed set still bound, and command errors.