Replace the building and EnvCell detail replay with retail's exact single-pass stage result, including authored surface opacity, squared detail alpha, final-alpha clipping, and the original subset pipeline/order. Arm the ordered walk command in place to close #471, delete the replay pipelines/shaders, and advance prepared content to recipe 9. Mutation witnesses (each restored before commit): - X=a*qA: RetailDetailTextureContractTests.BothShaderFamiliesUseTheSharedOnePassSourceAndDebugPrecedesDetailSample line 174, missing materialAlpha * detail.a * detail.a. - X*=base alpha: same test line 175, forbidden baseTexel.a found. - CLIP against base alpha: EnvCellAlphaDrawSourceTests.ClipShaders_UseGreaterEqualForThePerRangeReference line 260, final-X conditional missing. - second detail draw: EnvCellAlphaDrawSourceTests.DetailOn_EveryEnvCellFamilyDrawsOnceInPlaceWithAuthoredOpacity line 105, Assert.Single saw 2 MDI calls. - straight-alpha substitution: WalkStaticStreamPopulatorTests.ImmediateBuildingDetail_RetainsOriginalFramebufferFamily line 1244, Additive first failed (only wb-mesh-alpha-1x recorded; InvAlpha also failed). - omit ordered arm: OrderPreservingSubmitterTests.PrepareThenDraw_OrdinaryBuildingClipBuildingOrdinary_ArmsOnePassInPlace line 305, expected (77,3.5), got (0,0). - omit atmospheric combine: RetailDetailTextureContractTests.BothShaderFamiliesUseTheSharedOnePassSourceAndDebugPrecedesDetailSample line 173, atmospheric shared include missing. - drop serialized opacity: ObjectMeshDataSerializerTests.SurfaceOpacity_RoundTripsBitExactlyAndDeterministically line 288, first reported 0.5 bits 1056964608 vs 1065353216. - stale detail arm: ordered adjacency test line 307, expected following ordinary (0,0), got (77,3.5). - per-frame surface map: EnvCellAlphaDrawSourceTests.ProductionWholeLeaf_WarmedScanSubmitRhiAndFilteredReplayDoNotAllocate line 178, expected 0 B, got 147456 B. Verification before commit: shader compiler 23/23; focused App 213/213; Content 75/75; Core Wb 10/10; launcher migration 6/6; Release solution build 0 warnings / 0 errors; git diff --check clean.
86 lines
3.5 KiB
C#
86 lines
3.5 KiB
C#
using System.Numerics;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace AcDream.App.Rendering.Gpu;
|
|
|
|
/// <summary>
|
|
/// The single push-constant block shared by every acdream pipeline — 96 of the
|
|
/// 128 bytes Vulkan guarantees, leaving 32 bytes of headroom for later slices.
|
|
///
|
|
/// One shared block (rather than a per-shader block) is what lets every world
|
|
/// pipeline share ONE pipeline layout, so switching pipelines mid-pass does not
|
|
/// invalidate bound descriptor sets or push constants. Shaders declare only the
|
|
/// fields they read; unused fields cost nothing.
|
|
///
|
|
/// The GL backend maps each field to the correspondingly named uniform and skips
|
|
/// any the program does not declare (location -1). The Vulkan backend writes the
|
|
/// struct verbatim with one <c>vkCmdPushConstants</c>.
|
|
///
|
|
/// Layout is asserted by <c>GpuContractTests</c>; changing it is a contract change
|
|
/// that must land together with the matching edit to the shared GLSL preamble.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
|
internal struct GpuPushConstants
|
|
{
|
|
/// <summary>
|
|
/// GLSL <c>uViewProjection</c>. acdream's cameras build this with
|
|
/// <c>Matrix4x4.CreatePerspectiveFieldOfView</c>, whose NDC z range is [0,1] —
|
|
/// already Vulkan's convention (see <c>PortalProjection.cs</c>). No projection
|
|
/// rework is needed for the migration, and Vulkan gains the half of the depth
|
|
/// range GL was discarding.
|
|
/// </summary>
|
|
public Matrix4x4 ViewProjection;
|
|
|
|
/// <summary>
|
|
/// GLSL <c>uDrawIDOffset</c>. Issue #52: the draw index resets to 0 at the
|
|
/// start of each multi-draw-indirect call, so a pass that begins partway into
|
|
/// the batch array must offset its lookup. Vulkan's <c>gl_DrawID</c> resets
|
|
/// identically per <c>vkCmdDrawIndexedIndirect</c>, so the pattern carries over
|
|
/// unchanged.
|
|
/// </summary>
|
|
public int DrawIdOffset;
|
|
|
|
/// <summary>GLSL <c>uLightingMode</c>: 0 = object (plain Lambert + sun), 1 = EnvCell (half-Lambert wrap, no sun).</summary>
|
|
public int LightingMode;
|
|
|
|
/// <summary>GLSL <c>uRenderPass</c>: 0 = opaque, 1 = translucent.</summary>
|
|
public int RenderPass;
|
|
|
|
/// <summary>GLSL <c>uLightDebug</c>: #176 stripe-hunt isolation modes; 0 = off.</summary>
|
|
public int LightDebug;
|
|
|
|
/// <summary>
|
|
/// GLSL <c>uTextureIndexA</c>. Primary texture-table slot for pipelines whose
|
|
/// texture is per-pass rather than per-batch — currently the terrain atlas.
|
|
/// </summary>
|
|
public uint TextureIndexA;
|
|
|
|
/// <summary>GLSL <c>uTextureIndexB</c>. Secondary per-pass slot; terrain
|
|
/// uses it for the alpha-mask array, while shared-pose world passes
|
|
/// carry the absolute transform-prefix instance count.</summary>
|
|
public uint TextureIndexB;
|
|
|
|
/// <summary>
|
|
/// GLSL <c>uParamA</c>. Spare scalar, claimed at slice V6e by
|
|
/// <c>particle_mesh</c> as the array layer its per-pass texture is sampled
|
|
/// from — a value the shader converted to float anyway.
|
|
/// </summary>
|
|
public float ParamA;
|
|
|
|
/// <summary>GLSL <c>uParamB</c>. Spare scalar; unclaimed at V0.</summary>
|
|
public float ParamB;
|
|
|
|
/// <summary>Neutral defaults: identity transform, opaque object lighting, no debug mode.</summary>
|
|
public static GpuPushConstants Default => new()
|
|
{
|
|
ViewProjection = Matrix4x4.Identity,
|
|
DrawIdOffset = 0,
|
|
LightingMode = 0,
|
|
RenderPass = 0,
|
|
LightDebug = 0,
|
|
TextureIndexA = 0,
|
|
TextureIndexB = 0,
|
|
ParamA = 0f,
|
|
ParamB = 0f,
|
|
};
|
|
}
|