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:
parent
75664805f8
commit
15ed57a1e7
44 changed files with 1154 additions and 187 deletions
|
|
@ -14,6 +14,45 @@ public sealed class RetailDetailTextureContractTests
|
|||
private static readonly Vector4 Detail = new(0.91f, 0.23f, 0.49f, 0.62f);
|
||||
private static readonly Vector4 Destination = new(0.17f, 0.37f, 0.71f, 0.29f);
|
||||
|
||||
public static TheoryData<SurfaceType, bool, RetailSetSurfaceBlend,
|
||||
RetailSetSurfaceAlphaTest, bool> ResolvedRows() => new()
|
||||
{
|
||||
{ SurfaceType.Base1Image, false, RetailSetSurfaceBlend.Opaque, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.Alpha, false, RetailSetSurfaceBlend.StraightAlpha, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.Alpha | SurfaceType.Additive, false, RetailSetSurfaceBlend.AlphaAdditive, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
{ SurfaceType.Additive, false, RetailSetSurfaceBlend.Additive, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
{ SurfaceType.InvAlpha, false, RetailSetSurfaceBlend.InverseAlpha, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.InvAlpha | SurfaceType.Additive, false, RetailSetSurfaceBlend.InverseAdditive, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
{ SurfaceType.Base1ClipMap, false, RetailSetSurfaceBlend.Clip, RetailSetSurfaceAlphaTest.Dds, true },
|
||||
{ SurfaceType.Base1ClipMap, true, RetailSetSurfaceBlend.Clip, RetailSetSurfaceAlphaTest.Paletted, true },
|
||||
{ SurfaceType.Alpha | SurfaceType.Base1ClipMap, true, RetailSetSurfaceBlend.StraightAlpha, RetailSetSurfaceAlphaTest.Paletted, true },
|
||||
{ SurfaceType.InvAlpha | SurfaceType.Additive | SurfaceType.Base1ClipMap, false, RetailSetSurfaceBlend.InverseAdditive, RetailSetSurfaceAlphaTest.Dds, false },
|
||||
{ SurfaceType.Translucent, false, RetailSetSurfaceBlend.StraightAlpha, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.Translucent | SurfaceType.Additive, false, RetailSetSurfaceBlend.Additive, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
{ SurfaceType.Translucent | SurfaceType.InvAlpha, false, RetailSetSurfaceBlend.InverseAlpha, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.Translucent | SurfaceType.Base1ClipMap | SurfaceType.Additive, true, RetailSetSurfaceBlend.StraightAlpha, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ResolvedRows))]
|
||||
public void SetSurfaceResolver_PreservesEveryRawFamilyClipAndLateOverride(
|
||||
SurfaceType type,
|
||||
bool paletted,
|
||||
RetailSetSurfaceBlend expectedBlend,
|
||||
RetailSetSurfaceAlphaTest expectedAlphaTest,
|
||||
bool expectedFog)
|
||||
{
|
||||
RetailSetSurfaceMaterialState state = RetailSetSurfaceMaterialState.Resolve(
|
||||
type,
|
||||
texturePresent: true,
|
||||
textureHasPalette: paletted);
|
||||
|
||||
Assert.Equal(expectedBlend, state.Blend);
|
||||
Assert.Equal(expectedAlphaTest, state.AlphaTest);
|
||||
Assert.Equal(expectedFog, state.FogEnabled);
|
||||
Assert.Equal(state, RetailSetSurfaceMaterialState.FromPackedByte(state.ToPackedByte()));
|
||||
}
|
||||
|
||||
public static TheoryData<string, SurfaceType, bool, bool, TranslucencyKind, int, float> PolicyRows()
|
||||
{
|
||||
var rows = new TheoryData<string, SurfaceType, bool, bool, TranslucencyKind, int, float>();
|
||||
|
|
@ -65,27 +104,22 @@ public sealed class RetailDetailTextureContractTests
|
|||
Assert.Equal(["source-subset"], PhysicalDrawSequence(detailEnabled));
|
||||
|
||||
PipelineState state = ExpectedPipelineState(
|
||||
consumer, expectedKind, paletted, expectedReference);
|
||||
Assert.Equal(expectedReference, state.AlphaReference);
|
||||
Assert.Equal(
|
||||
expectedKind == TranslucencyKind.ClipMap
|
||||
? paletted ? 100f / 255f : 200f / 255f
|
||||
: 0.05f,
|
||||
state.AlphaReference);
|
||||
Assert.True(state.AlphaTest);
|
||||
Assert.Equal(expectedKind is TranslucencyKind.Opaque or TranslucencyKind.ClipMap,
|
||||
state.DepthWrite);
|
||||
Assert.Equal(expectedKind switch
|
||||
consumer, surfaceType, expectedKind, paletted, detailEnabled);
|
||||
RetailSetSurfaceMaterialState resolved = RetailSetSurfaceMaterialState.Resolve(
|
||||
surfaceType,
|
||||
texturePresent: true,
|
||||
textureHasPalette: paletted);
|
||||
if (detailEnabled)
|
||||
{
|
||||
TranslucencyKind.Opaque => GpuBlendMode.None,
|
||||
TranslucencyKind.AlphaBlend => GpuBlendMode.StraightAlpha,
|
||||
TranslucencyKind.Additive => GpuBlendMode.Additive,
|
||||
TranslucencyKind.InvAlpha => GpuBlendMode.InverseAlpha,
|
||||
TranslucencyKind.ClipMap when consumer == "EnvCell" =>
|
||||
GpuBlendMode.PremultipliedAlpha,
|
||||
TranslucencyKind.ClipMap => GpuBlendMode.None,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(expectedKind)),
|
||||
}, state.Blend);
|
||||
Assert.Equal(resolved.AlphaTestReference, state.AlphaReference);
|
||||
Assert.Equal(resolved.AlphaTestEnabled, state.AlphaTest);
|
||||
Assert.Equal(resolved.FogEnabled, state.FogEnabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(expectedReference, state.AlphaReference);
|
||||
Assert.True(state.AlphaTest);
|
||||
}
|
||||
Assert.Equal(detailEnabled, DetailIsArmed(detailEnabled));
|
||||
if (consumer == "Building" && expectedKind == TranslucencyKind.ClipMap)
|
||||
Assert.Equal("AP-240 immediate A2C", state.Placement);
|
||||
|
|
@ -263,11 +297,38 @@ public sealed class RetailDetailTextureContractTests
|
|||
|
||||
private static PipelineState ExpectedPipelineState(
|
||||
string consumer,
|
||||
SurfaceType surfaceType,
|
||||
TranslucencyKind kind,
|
||||
bool paletted,
|
||||
float reference)
|
||||
bool detailEnabled)
|
||||
{
|
||||
_ = paletted;
|
||||
RetailSetSurfaceMaterialState resolved = RetailSetSurfaceMaterialState.Resolve(
|
||||
surfaceType,
|
||||
texturePresent: true,
|
||||
textureHasPalette: paletted);
|
||||
if (detailEnabled)
|
||||
{
|
||||
GpuBlendMode exactBlend = resolved.Blend switch
|
||||
{
|
||||
RetailSetSurfaceBlend.Opaque => GpuBlendMode.None,
|
||||
RetailSetSurfaceBlend.StraightAlpha => GpuBlendMode.StraightAlpha,
|
||||
RetailSetSurfaceBlend.AlphaAdditive => GpuBlendMode.Additive,
|
||||
RetailSetSurfaceBlend.Additive => GpuBlendMode.RawAdditive,
|
||||
RetailSetSurfaceBlend.InverseAlpha => GpuBlendMode.InverseAlpha,
|
||||
RetailSetSurfaceBlend.InverseAdditive => GpuBlendMode.InverseAdditive,
|
||||
RetailSetSurfaceBlend.Clip => GpuBlendMode.PremultipliedAlpha,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
return new PipelineState(
|
||||
exactBlend,
|
||||
resolved.Blend is RetailSetSurfaceBlend.Opaque or RetailSetSurfaceBlend.Clip,
|
||||
resolved.AlphaTestEnabled,
|
||||
resolved.AlphaTestReference,
|
||||
resolved.FogEnabled,
|
||||
consumer == "Building" && kind == TranslucencyKind.ClipMap
|
||||
? "AP-240 immediate A2C"
|
||||
: "source FIFO position");
|
||||
}
|
||||
GpuBlendMode blend = kind switch
|
||||
{
|
||||
TranslucencyKind.Opaque => GpuBlendMode.None,
|
||||
|
|
@ -283,7 +344,10 @@ public sealed class RetailDetailTextureContractTests
|
|||
blend,
|
||||
kind is TranslucencyKind.Opaque or TranslucencyKind.ClipMap,
|
||||
AlphaTest: true,
|
||||
reference,
|
||||
kind == TranslucencyKind.ClipMap
|
||||
? paletted ? 100f / 255f : 200f / 255f
|
||||
: 0.05f,
|
||||
FogEnabled: true,
|
||||
consumer == "Building" && kind == TranslucencyKind.ClipMap
|
||||
? "AP-240 immediate A2C"
|
||||
: "source FIFO position");
|
||||
|
|
@ -310,6 +374,7 @@ public sealed class RetailDetailTextureContractTests
|
|||
bool DepthWrite,
|
||||
bool AlphaTest,
|
||||
float AlphaReference,
|
||||
bool FogEnabled,
|
||||
string Placement);
|
||||
|
||||
private static Vector4 IndependentComposite(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue