acdream/tests/AcDream.App.Tests
Erik fac0940711 feat(render): Campaign V slice V6f-2 - terrain's tiling table becomes a buffer
terrain_modern.frag declared `uniform float uTexTiling[36]` - the per-layer
tiling factors retail passes to TexMerge::CopyAndTile / TexMerge::Merge, one per
terrain atlas layer. Vulkan GLSL has no default uniform block, so a loose array
is unspellable there, and 144 bytes of payload cannot ride the pinned 96-byte
push-constant block. GpuBindingModel reserved UniformTerrainTiling (binding 3)
for exactly this at slice V4d. The array now lives in that block.

The ELEMENT TYPE is deliberately unchanged. std140 pads every array element out
to 16 bytes, so the block is 576 bytes rather than 144, and packing four values
per vec4 would be tighter - but it would also rewrite the accessor and every use
site, and this commit's whole value is that its pixel gate measures the move to
a uniform buffer and nothing else. `uTexTiling[int(layer)]` reads exactly as it
did.

That padding is the hazard the change introduces, so it is pinned twice. The CPU
writer walks TerrainTextureTilingTable.UniformElementStrideBytes and zero-fills
the dead words rather than blitting 36 packed floats, and a new test asserts the
stride is 16, the block is 576, and the two are consistent with LayerCapacity. A
tightly-packed writer would not crash or even look obviously wrong: the shader
would read layer 0's factor for layers 0-3, layer 4's for 4-7, and in a scene
where most layers tile at 1 the error stays invisible until a layer that does
not appears. Nothing else in the suite could see that.

The buffer is allocated once in the constructor, through the same
TrackedGlResource + ResourceCleanupGroup rollback path every other terrain
buffer uses, written on the first bound draw - preserving the upload-once
property the linked program's uniform had for free - and released through the
dispose ledger. It is REBOUND every draw rather than once: GL's uniform-buffer
binding points are global and shared with SceneLighting at 1 and the sky's
params at 4, so a renderer running between two terrain draws can take binding 3
out from under us. Self-contained render state, per the standing rule.

Gates. Release build clean. App tests 4,073 passed / 3 skipped - the baseline
4,072 plus the new layout test. Offline pixel gate against 5e13b45f: 21 differing
pixels of 563,200 compared (fraction 3.73e-05), inside the documented 15-23
pixel band and ~27x under the 0.001 threshold. This gate is a real test of the
layout rather than a formality: terrain blending, road overlays and the water
edge are most of the captured frame, and every one of those samples goes through
terrainTiling(), so a stride mismatch would have shown as a wholesale retexture
rather than as noise. The gate run's client log has zero exceptions and an empty
stderr.

Manifest regenerated in the same commit. terrain_modern's remaining Vulkan error
moved from `'uTexTiling' : undeclared identifier` to the frag's direct
`sampler2DArray(...)` construction, which is the same dialect migration V6e ran
for mesh_modern and which lands next. The pair count is unchanged at 7/9.

No divergence-register row: the tiling values, their source and their use are
unchanged, and no retail-facing behaviour moves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:11:00 +02:00
..
Audio fix(audio): keep unavailable world slots quiescent 2026-07-24 19:49:25 +02:00
Combat refactor(runtime): close simulation ownership 2026-07-26 15:53:31 +02:00
Composition Revert "feat(render): Campaign V slice V4d-2 - move terrain onto the RHI" 2026-07-27 22:38:02 +02:00
Diagnostics fix(diag): resolve the multisampled backbuffer before reading it 2026-07-28 00:54:59 +02:00
Input feat(headless): complete deterministic bot command parity 2026-07-27 08:23:36 +02:00
Interaction fix(interaction): restore retail loot placement and world-drop projection 2026-07-27 00:03:15 +02:00
Net refactor(runtime): unify generation reset for direct hosts 2026-07-27 00:43:26 +02:00
Physics fix(interaction): restore retail loot placement and world-drop projection 2026-07-27 00:03:15 +02:00
Platform feat(linux): gate graphical backends and capabilities 2026-07-27 12:26:58 +02:00
Plugins feat(D.2b): IUiRegistry plugin UI surface + buffered drain into UiHost 2026-06-14 17:46:37 +02:00
Rendering feat(render): Campaign V slice V6f-2 - terrain's tiling table becomes a buffer 2026-07-28 10:11:00 +02:00
Runtime feat(headless): complete deterministic bot command parity 2026-07-27 08:23:36 +02:00
Settings fix(rendering): survive display topology handoff 2026-07-25 13:15:24 +02:00
Spells feat(headless): share immutable gameplay content 2026-07-27 09:00:48 +02:00
Streaming refactor(runtime): unify generation reset for direct hosts 2026-07-27 00:43:26 +02:00
Studio Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
UI Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
World fix(interaction): restore retail loot placement and world-drop projection 2026-07-27 00:03:15 +02:00
AcDream.App.Tests.csproj refactor(runtime): own canonical action state 2026-07-26 10:44:09 +02:00
BoundedTestDatCollection.cs perf(content): remove exception-driven setup probes 2026-07-24 15:12:21 +02:00
FramePhaseTestDoubles.cs refactor(runtime): move session lifetime and ordered transport 2026-07-25 19:39:24 +02:00
FrameProfilerReportTests.cs perf(diag): complete trustworthy Slice A capture tooling 2026-07-24 12:46:51 +02:00
FrameStatsBufferTests.cs fix(pipeline): MP0 - profiler toggle-path hygiene + Max() seed (review follow-up) 2026-07-05 19:26:28 +02:00
GameRuntimeTestFactory.cs refactor(runtime): cut graphical host over to canonical root 2026-07-26 19:06:09 +02:00
GlobalUsings.cs Revert "Campaign V slice V4a" - it lost world multisampling 2026-07-27 18:29:28 +02:00
LiveEntityRuntimeFixture.cs refactor(runtime): own projectile simulation 2026-07-26 14:17:42 +02:00
RuntimeDatAccessArchitectureTests.cs feat(headless): share immutable process content 2026-07-27 08:37:24 +02:00
RuntimeDatCollectionFactoryTests.cs feat(headless): share immutable process content 2026-07-27 08:37:24 +02:00
RuntimeOptionsRetailUiTests.cs test(runtime): add deterministic world gate artifacts 2026-07-20 22:37:16 +02:00
RuntimeOptionsTests.cs feat(render): Campaign V slice V5 - Vulkan bring-up, dark 2026-07-28 07:11:50 +02:00
RuntimeWorldTransitTestDriver.cs refactor(runtime): own teleport destination correlation 2026-07-26 17:52:34 +02:00