fix(rendering): carry retail SetSurface state to detail draws

Resolve exact SetSurface blend, alpha-test, and fog state once during extraction and preserve it through recipe-10 prepared payloads, Wb/EnvCell command data, Vulkan pipelines, push constants, and both ordinary/atmospheric one-pass shaders. Preserve AP-240 Wb pure-Clip immediate opaque/A2C while EnvCell uses retail premultiplied Clip; detail-off routing remains unchanged. Correct AP-232 and register the remaining detail-off state divergence.

Mutation first failures (all restored):
- raw Add->SRCALPHA/ONE: WalkStaticStreamPopulatorTests.ImmediateBuildingDetail_UsesExactResolvedSetSurfaceState line 1278, expected wb-mesh-raw-additive-1x.
- inverse-add->alpha-add: same test line 1278, expected wb-mesh-inverse-additive-1x.
- remove Env inverse: EnvCellAlphaDrawSourceTests.DetailOn_EveryEnvCellFamilyDrawsOnceInPlaceWithAuthoredOpacity line 132, expected envcell-inverse.
- raw IsAdditive precedence: same test line 132, Translucent|Clip|Additive expected envcell-alpha.
- Wb paletted ParamB=0: OrderPreservingSubmitterTests line 333, expected 0.392156869.
- Wb DDS ParamB=0.05: same test line 333, expected 0.784313738.
- disable Alpha+Clip test: WalkStaticStreamPopulatorTests line 1286, expected 0.784313738.
- always fog raw Add: same test line 1287, expected no-fog true.
- disable fog non-Add: same test line 1287, expected no-fog false.
- X=a*qA: RetailDetailTextureContractTests line 261, shared squared-alpha substring absent.
- X includes base alpha: same test line 262, forbidden baseTexel.a present.
- CLIP uses 0.05: EnvCellAlphaDrawSourceTests.ClipShaders_UseGreaterEqualForThePerRangeReference line 367.
- second detail draw: EnvCell detail-on line 131, collection contained 2 draws.
- straight-alpha substitute: Wb immediate line 1278, expected wb-mesh-additive-1x.
- omit ordered detail arm: OrderPreservingSubmitterTests line 318, expected (77,3.5), got (0,0).
- omit atmospheric combine: RetailDetailTextureContractTests line 260, shared include absent.
- drop serialized opacity: ObjectMeshDataSerializerTests line 292, expected opacity bits, got 1.0.
- stale detail arm: atmospheric adjacency line 402, expected slot 0, got 77.
- per-frame surface map: EnvCell warmed allocation line 285, expected 0 B, got 204800 B.
This commit is contained in:
Erik 2026-09-05 00:56:52 +02:00
parent 75664805f8
commit 15ed57a1e7
44 changed files with 1154 additions and 187 deletions

View file

@ -192,6 +192,10 @@ public class ObjectMeshDataSerializerTests {
Indices = new List<ushort> { 0, 1, 2 },
CullMode = CullMode.Clockwise,
Translucency = TranslucencyKind.Opaque,
MaterialState = new RetailSetSurfaceMaterialState(
RetailSetSurfaceBlend.InverseAdditive,
RetailSetSurfaceAlphaTest.Paletted,
FogEnabled: false),
IsTransparent = false,
IsAdditive = false,
HasWrappingUVs = false,
@ -290,6 +294,37 @@ public class ObjectMeshDataSerializerTests {
BitConverter.SingleToInt32Bits(read.SurfaceOpacity));
}
[Theory]
[InlineData(0, 0, true)]
[InlineData(1, 0, true)]
[InlineData(2, 1, true)]
[InlineData(3, 2, false)]
[InlineData(4, 0, true)]
[InlineData(5, 1, false)]
[InlineData(6, 2, true)]
public void SetSurfaceState_RoundTripsEveryPackedFieldDeterministically(
int blendValue,
int alphaTestValue,
bool fogEnabled) {
ObjectMeshData data = WithCellShellSubset();
TextureBatchData batch = Assert.Single(Assert.Single(data.TextureBatches).Value);
batch.MaterialState = new RetailSetSurfaceMaterialState(
(RetailSetSurfaceBlend)blendValue,
(RetailSetSurfaceAlphaTest)alphaTestValue,
fogEnabled);
using var first = new MemoryStream();
ObjectMeshDataSerializer.Write(data, first);
using var second = new MemoryStream();
ObjectMeshDataSerializer.Write(data, second);
Assert.Equal(first.ToArray(), second.ToArray());
TextureBatchData read = Assert.Single(Assert.Single(
ObjectMeshDataSerializer.Read(first.ToArray()).TextureBatches).Value);
Assert.Equal(batch.MaterialState, read.MaterialState);
Assert.Equal(batch.MaterialState.ToPackedByte(), read.MaterialState.ToPackedByte());
}
// ---- determinism -----------------------------------------------------
[Fact]