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 is explicit: the application describes rendering upfront instead of relying on implicit OpenGL state. A render pass defines attachments, subpasses, and dependencies so the driver can optimize memory bandwidth before any draw call runs.
Core components:
A forward pass typically has one color attachment, one depth attachment, and one subpass drawing geometry.
A deferred pass has multiple color attachments (G-buffer: position, normal, albedo), one depth attachment, subpass 0 filling the G-buffer, and subpass 1 reading it for lighting.
Each attachment specifies:
cLoading…
For example, marking a G-buffer attachment DONT_CARE on store tells tile-based mobile GPUs they need not write intermediate data back to VRAM. CLEAR avoids reading uninitialized memory; DONT_CARE enables tile compression on ARM Mali and PowerVR.
You will model a Vulkan render pass with two subpasses for deferred rendering and print its configuration. This task asks you to define attachments with load/store ops and wire subpass dependencies. Explicit render passes are why deferred rendering is affordable on phones, not just desktop GPUs.
Model a Vulkan render pass the way a driver for a tile-based GPU sees it. You get:
Validate the structure. For a valid pass, compute the per-pixel on-chip tile memory and the DRAM traffic the load/store ops imply, compared with running each subpass as its own render pass. That comparison is the reason deferred renderers use subpasses on mobile.
# starts a comment.
cLoading…
Formats (bytes per pixel): RGBA8, BGRA8, RGB10A2 and R32F are 4; RGBA16F is 8; RGBA32F is 16. Depth formats: D32 and D24S8 are 4, D16 is 2. There are at most 8 attachments and 6 subpasses, and names must be unique.
analyze, in this order)error: NAME is transient but its contents are loaded or stored (transient requires load ≠ LOAD and store = DONT_CARE);warning: NAME is never used (neither read nor written by any subpass).error: subpass S: A has depth format F but is a color attachment;error: subpass S: A has color format F but is the depth attachment;error: subpass S reads and writes A (feedback loop) if S also writes A.
error: subpass S reads A before any subpass writes it (and it is not loaded), unless A has load=LOAD.error: missing dependency W -> S for A.invalid: N error(s) and stop. subpass S: reads A B; writes C D (depth). Omit the reads part without inputs, and print writes nothing if nothing is written. on-chip tile memory: N bytes per pixel sums every attachment's bytes per pixel.load=LOAD, else 0;store=STORE, else 0; (transient: no memory allocated); total: T bytes (X.Y MB) vs S bytes (X.Y MB) as separate render passes, with MB = 10⁶ bytes to 1 decimal, rounded half up.cLoading…
Command errors:
attachment: NAME FORMAT load=CLEAR|LOAD|DONT_CARE store=STORE|DONT_CARE [transient] (also for a duplicate name or a 9th attachment; the same goes for subpasses)attachment X: unknown format Fsubpass: NAME [color=A,B] [input=C] [depth=D], subpass S: unknown attachment Xdependency: SRC DST (subpass names or EXTERNAL), dependency A -> B: must go from an earlier subpass to a later oneanalyze: WIDTH HEIGHT (1-16384), analyze: no subpassesunknown command XInput:
cLoading…
Output:
cLoading…
VkSubpassDependency.Hidden tests cover transient misuse, depth/color format mix-ups, a missing dependency, a feedback loop, an input that is never written, an input with load=LOAD, an unused attachment, and command errors.