docs(render): measure the terrain clip block's set, and close the shader audit

Slice V6i-1 recorded terrain_modern.vert's TerrainClip block as landing in the
wrong descriptor set under the Vulkan dialect. That was reasoning from the
missing ACDREAM_UBO_SET macro; it is now measured. Disassembling the committed
spv/terrain_modern.vert.spv shows the block as OpVariable ... Uniform decorated
DescriptorSet 0 / Binding 2, where set 0's layout declares a storage buffer.

The audit the section asked for is also done rather than deferred. Every
compiled .spv was disassembled: mesh_modern.vert's nine set-0 entries are all
StorageBuffer, correctly, and every other uniform block in every other shader
already carries the macro. terrain_modern.vert is the only one. sky.vert is the
precedent - it declares the SAME shared clip block as ACDREAM_UBO_SET binding =
2 - so there is no numbering question for the world arm to settle, only a
one-word omission to fix, plus declaring set 1 bindings 2 and 4 in the uniform
set layout. Binding 4 is section 5.5.8's still-open UniformSkyParams, which
sky.vert and sky.frag both declare.

Documentation only; no source, shader or .spv is touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-28 13:19:13 +02:00
parent df6e2a7918
commit 0ca802cd7f

View file

@ -1552,16 +1552,28 @@ one this slice measured:
needs, so the missing piece is an `ITextureArray` implementation over needs, so the missing piece is an `ITextureArray` implementation over
`IGpuTexture`, not a codec. `IGpuTexture`, not a codec.
2. **`terrain_modern.vert`'s `TerrainClip` block is in the wrong set for Vulkan, 2. **`terrain_modern.vert`'s `TerrainClip` block is in the wrong descriptor set,
and it is the same class of gap §5.5.8 recorded for `UniformSkyParams`.** It measured on the committed SPIR-V.** It is declared
is declared `layout(std140, binding = 2) uniform TerrainClip` with **no `layout(std140, binding = 2) uniform TerrainClip` with **no
`ACDREAM_UBO_SET`**, so under the Vulkan dialect it lands at set 0 binding 2 — `ACDREAM_UBO_SET`**, so under the Vulkan dialect it lands in set 0.
which set 0's layout declares as a STORAGE buffer. GL is unaffected (the macro Disassembling `spv/terrain_modern.vert.spv` confirms it rather than infers it:
expands to nothing and the UBO namespace is separate), and nothing has caught the block is `OpVariable ... Uniform` decorated `DescriptorSet 0` / `Binding
it because no terrain pipeline has ever been created on Vulkan. Whoever draws 2`, and set 0's layout declares binding 2 as a STORAGE buffer. A terrain
terrain must add the macro, declare binding 2 in the uniform set layout, and pipeline built against the shared layout is therefore malformed. GL is
raise `DynamicUniformBindingCount` to 3 — still far under the guaranteed 8. unaffected — the macro expands to nothing and GL's UBO namespace is separate —
Worth auditing every remaining shader for the same omission in the same pass. and nothing has caught it because no terrain pipeline has ever been created on
Vulkan.
**The audit is done and this is the only one.** Every compiled `.spv` was
disassembled: `mesh_modern.vert`'s nine set-0 entries are all
`StorageBuffer`, correctly; every other uniform block in every other shader
already carries the macro. `sky.vert` is the precedent — it declares the SAME
block as `ACDREAM_UBO_SET binding = 2` — so there is no numbering question to
settle, only a one-word omission to fix. The fix is that word plus declaring
bindings 2 and 4 in `VulkanPipelineLayouts.CreateUniformSetLayout` (4 is
§5.5.8's still-open `UniformSkyParams`, which `sky.vert` and `sky.frag` both
declare) and raising `DynamicUniformBindingCount` accordingly — still far
under Vulkan's guaranteed 8.
3. **The flat-versus-PView question decides how much of the world arm is one 3. **The flat-versus-PView question decides how much of the world arm is one
slice.** `WorldSceneRenderer` is already backend-neutral — it takes slice.** `WorldSceneRenderer` is already backend-neutral — it takes