acdream/src/AcDream.App
Erik 30e94da607 feat(render): Campaign V slice V6f-3 - terrain's atlas reads cross the dialect
The last thing keeping terrain_modern out of SPIR-V was how it named its two
atlases:

    #define uTerrain sampler2DArray(ACDREAM_TEXTURE_HANDLE(uTextureIndexA))
    #define uAlpha   sampler2DArray(ACDREAM_TEXTURE_HANDLE(uTextureIndexB))

`sampler2DArray(handle)` is a GL_ARB_bindless_texture construction with no
Vulkan equivalent. Vulkan's table is an opaque descriptor array in set 2; there
is no handle, so there is nothing to construct a sampler from. The ten sample
sites now go through ACDREAM_SAMPLE_ARRAY, the dialect-neutral read V6e
introduced for mesh_modern, wrapped in two shader-local macros that keep the
call sites reading as "sample the terrain atlas" rather than "index the table".

They are SAMPLING macros, not sampler-returning ones, and that is not
cosmetic. Under Vulkan the expansion carries `nonuniformEXT` on the indexing
expression, and binding the result to a local sampler2DArray first is exactly
where an implementation may drop it. The old `#define uTerrain
sampler2DArray(...)` was textually that shape, so preserving it would have
reintroduced the hazard at every use site.

On GL nothing about the sampled result changes: the same slot resolves through
the same binding=9 table to the same handle to the same texel, and the macro
expands to the identical expression the shader wrote by hand.

With this, terrain_modern compiles for Vulkan and the manifest reads 8/9. The
remaining pair is `mesh`, which the campaign doc records as having no consumer
at all - so every production shader acdream actually draws with is now
Vulkan-expressible. That closes the obligation §5 recorded against V6e ("the one
production pair still not Vulkan-expressible after V6e is terrain_modern") and
it closes the shader half of V4d's parked content.

What this does NOT do is give the Vulkan backend a world to draw. That is
reported separately with the rest of slice V6f; the shaders were the part that
could be finished, gated and landed on GL today.

Gates. Release build clean. App tests 4,073 passed / 3 skipped over four
consecutive runs. A fifth run failed only
CurrentRenderSceneOracleTests.SurfaceOverrideFingerprint_DictionaryHotPathAllocatesNothing,
an allocation-counting test over a CPU dictionary path that touches nothing in
this diff; it passes in isolation and passed in every other full run. That is
the known #250 flake class on an otherwise unchanged tree. Offline pixel gate
against fac09407: 12 differing pixels of 563,200 compared (fraction 2.13e-05) -
below even the floor of the documented 15-23 pixel band. Cumulatively, across
all three V6f commits against 7faaaa34: 22 pixels (3.91e-05, maximumChannelDelta
52), which is the same number the first commit measured on its own. Three
changes to the shader terrain draws with, and the drift has not accumulated.

No divergence-register row: the sampled result is unchanged on GL and no
retail-facing behaviour moves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:14:37 +02:00
..
Audio Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Combat refactor(runtime): close simulation ownership 2026-07-26 15:53:31 +02:00
Composition feat(render): V6e — the sky's uniforms become a buffer and its texture a table slot 2026-07-28 09:54:13 +02:00
Diagnostics fix(diag): resolve the multisampled backbuffer before reading it 2026-07-28 00:54:59 +02:00
Input Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Interaction refactor(runtime): unify generation reset for direct hosts 2026-07-27 00:43:26 +02:00
Net feat(headless): hydrate isolated collision worlds 2026-07-27 09:25:58 +02:00
Physics Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Platform feat(linux): gate graphical backends and capabilities 2026-07-27 12:26:58 +02:00
Plugins Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Rendering feat(render): Campaign V slice V6f-3 - terrain's atlas reads cross the dialect 2026-07-28 10:14:37 +02:00
Runtime feat(headless): complete deterministic bot command parity 2026-07-27 08:23:36 +02:00
Settings feat(linux): add graphical platform services 2026-07-27 11:54:59 +02:00
Spells Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Streaming Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Studio Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UI feat(render): put the retained UI and debug lines on both backends 2026-07-28 08:51:32 +02:00
Update refactor(runtime): cut graphical host over to canonical root 2026-07-26 19:06:09 +02:00
World Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
AcDream.App.csproj feat(render): Campaign V slice V6c - SPIR-V, pipelines, passes, and a Vulkan frame that draws 2026-07-28 08:17:24 +02:00
GlobalUsings.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
Program.cs feat(linux): gate graphical backends and capabilities 2026-07-27 12:26:58 +02:00
RenderBackendKind.cs feat(render): Campaign V slice V5 - Vulkan bring-up, dark 2026-07-28 07:11:50 +02:00
RuntimeOptions.cs feat(render): Campaign V slice V5 - Vulkan bring-up, dark 2026-07-28 07:11:50 +02:00