D859 - A primitive's layer picks the slice it is drawn into

Status: decided Date: 2026-10-14 known_by: published

A primitive shader that exports pos1 with its third channel enabled names the render-target layer of each vertex there: bits 10:0, with the viewport index in 19:16 (Mesa ac_nir_prerast_utils.c 381-392, for GFX9 and later). Where PA_CL_VS_OUT_CNTL.USE_VTX_RENDER_TARGET_INDX (bit 18) is set, the primitive is drawn into slice SLICE_START + layer of each colour target, CB_COLORn_VIEW giving SLICE_START; where it is clear, the export is ignored and every primitive goes to SLICE_START. radeonsi and RADV set that bit exactly when the shader writes the layer (si_state_shaders.cpp 996, radv_shader.c 1697).

A colour target is the slice SLICE_START names: its base moves by that many slices, each slice a whole mip chain (SurfaceLayout::chain_bytes), as a sampled cube's faces lie.

The draw runs once per slice its view spans. Each pass has one slice as its target, and its draw data carries the layer it draws (DRAW_DATA_LAYER_WORD); the mesh module stages each vertex's layer and culls every primitive whose layer is not that one (CullPrimitiveEXT). A draw that does not use the layer carries u32::MAX there and culls nothing.

Why: PPSA21564's first draw is a full-screen triangle whose primitive shader exports the layer from v8, the instance id, so an instanced draw fills one slice per instance - the usual way to clear or copy every slice of an array. Culling against the pass's layer draws each primitive into the slice its own shader named, whatever it computed, and keeps the single-slice targets, write-back and pipelines every other draw uses. A primitive's layer is its first vertex's: GL leaves a primitive whose vertices disagree undefined, and the shaders that write it give every vertex of a primitive the same one.

Assumed:

Rejected: