From 7fab6ea3767882bf9c606a62f5bc17acad0912d9 Mon Sep 17 00:00:00 2001 From: myT <> Date: Thu, 18 Jan 2024 03:16:35 +0100 Subject: [PATCH] simplified world shader trace and fixed its VSync support --- code/renderer/crp_opaque.cpp | 4 ++-- code/renderer/crp_transp_draw.cpp | 2 +- code/renderer/grp_local.h | 2 +- code/renderer/grp_world.cpp | 2 +- code/renderer/shaders/crp/oit.h.hlsli | 2 +- code/renderer/shaders/crp/opaque.hlsl | 17 ++++++----------- code/renderer/shaders/crp/transp_resolve.hlsl | 18 ++++++++++++------ code/renderer/shaders/grp/uber_shader.hlsl | 7 +++---- code/renderer/srp_main.cpp | 10 +++++----- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/code/renderer/crp_opaque.cpp b/code/renderer/crp_opaque.cpp index 8f4cf16..de19b40 100644 --- a/code/renderer/crp_opaque.cpp +++ b/code/renderer/crp_opaque.cpp @@ -41,7 +41,7 @@ struct OpaquePixelRC float greyscale; // shader trace - uint32_t shaderTrace; // shader index: 14 - frame index: 2 - enable: 1 + uint32_t shaderTrace; // shader index: 14 - enable: 1 uint16_t centerPixelX; uint16_t centerPixelY; }; @@ -319,7 +319,7 @@ void WorldOpaque::EndBatch() pixelRC.shaderIndexBufferIndex = bufferIndex; pixelRC.alphaTest = alphaTest; pixelRC.greyscale = tess.greyscale; - pixelRC.shaderTrace = ((uint32_t)shader->index << 3) | (RHI::GetFrameIndex() << 1) | enableShaderTrace; + pixelRC.shaderTrace = ((uint32_t)shader->index << 1) | enableShaderTrace; pixelRC.centerPixelX = glConfig.vidWidth / 2; pixelRC.centerPixelY = glConfig.vidHeight / 2; CmdSetGraphicsRootConstants(sizeof(vertexRC), sizeof(pixelRC), &pixelRC); diff --git a/code/renderer/crp_transp_draw.cpp b/code/renderer/crp_transp_draw.cpp index 8e03e3d..91ac17c 100644 --- a/code/renderer/crp_transp_draw.cpp +++ b/code/renderer/crp_transp_draw.cpp @@ -333,7 +333,7 @@ void WorldTransp::EndBatch() pixelRC.samplerIndex = sampIdx; pixelRC.stateBits = GetFixedStageBits(stage->stateBits, s); pixelRC.textureIndex = texIdx; - pixelRC.shaderTrace = ((uint32_t)shader->index << 3) | (RHI::GetFrameIndex() << 1) | enableShaderTrace; + pixelRC.shaderTrace = ((uint32_t)shader->index << 1) | enableShaderTrace; pixelRC.hFadeDistance = f32tof16(shader->dfInvDist); pixelRC.hFadeOffset = f32tof16(shader->dfBias); pixelRC.depthFadeScaleBias = (enableDepthFade << 8) | (uint32_t)r_depthFadeScaleAndBias[shader->dfType]; diff --git a/code/renderer/grp_local.h b/code/renderer/grp_local.h index bb2413b..74f8239 100644 --- a/code/renderer/grp_local.h +++ b/code/renderer/grp_local.h @@ -43,7 +43,7 @@ struct WorldPixelRC float greyscale; // r_shaderTrace - dynamically enabled - uint32_t shaderTrace; // shader index: 14 - frame index: 2 - enable: 1 + uint32_t shaderTrace; // shader index: 14 - enable: 1 uint16_t centerPixelX; uint16_t centerPixelY; diff --git a/code/renderer/grp_world.cpp b/code/renderer/grp_world.cpp index 1174d87..0672803 100644 --- a/code/renderer/grp_world.cpp +++ b/code/renderer/grp_world.cpp @@ -663,7 +663,7 @@ void World::EndBatch() pixelRC.hNoiseScale = f32tof16(r_ditherStrength->value); pixelRC.hInvGamma = f32tof16(1.0f / r_gamma->value); pixelRC.hInvBrightness = f32tof16(1.0f / r_brightness->value); - pixelRC.shaderTrace = (uint32_t)!!tr.traceWorldShader | (RHI::GetFrameIndex() << 1) | ((uint32_t)shader->index << 3); + pixelRC.shaderTrace = ((uint32_t)shader->index << 1) | (uint32_t)(tr.traceWorldShader ? 1 : 0); pixelRC.centerPixelX = glConfig.vidWidth / 2; pixelRC.centerPixelY = glConfig.vidHeight / 2; pixelRC.hFadeDistance = f32tof16(tess.shader->dfInvDist); diff --git a/code/renderer/shaders/crp/oit.h.hlsli b/code/renderer/shaders/crp/oit.h.hlsli index 261fec0..fe12ff0 100644 --- a/code/renderer/shaders/crp/oit.h.hlsli +++ b/code/renderer/shaders/crp/oit.h.hlsli @@ -45,7 +45,7 @@ struct OIT_Fragment float depth; // higher is further away from the camera uint stateBits; // GLS_* stage bits + stage index uint next; - uint shaderTrace; // shader index: 14 - frame index: 2 - enable: 1 + uint shaderTrace; // shader index: 14 - enable: 1 uint depthFadeDistOffset; // offset: fp16 - distance: fp16 uint depthFadeScaleBias; // enable: 1 - color bias: 4 - color scale: 4 // @TODO: move the 9 bits from depthFadeScaleBias into shaderTrace diff --git a/code/renderer/shaders/crp/opaque.hlsl b/code/renderer/shaders/crp/opaque.hlsl index 0811d89..624bb21 100644 --- a/code/renderer/shaders/crp/opaque.hlsl +++ b/code/renderer/shaders/crp/opaque.hlsl @@ -41,11 +41,8 @@ cbuffer RootConstants float greyscale; // shader trace - uint shaderTrace; // shader index: 14 - frame index: 2 - enable: 1 + uint shaderTrace; // shader index: 14 - enable: 1 uint centerPixel; // y: 16 - x: 16 - - // @TODO: dither - // @TODO: Voronoi tiling }; struct VIn @@ -63,8 +60,6 @@ struct VOut float2 texCoords : TEXCOORD0; float4 color : COLOR0; float clipDist : SV_ClipDistance0; - float2 proj2232 : PROJ; - float depthVS : DEPTHVS; }; VOut vs(VIn input) @@ -77,12 +72,13 @@ VOut vs(VIn input) output.texCoords = input.texCoords; output.color = input.color; output.clipDist = dot(positionVS, clipPlane); - output.proj2232 = float2(-projectionMatrix[2][2], projectionMatrix[2][3]); - output.depthVS = -positionVS.z; return output; } +// @TODO: enable early-Z here once the full pre-pass is implemented +// this will prevent fragments failing the depth test from writing to the shader ID buffer +//[earlydepthstencil] float4 ps(VOut input) : SV_Target { // @TODO: Voronoi tiling @@ -106,9 +102,8 @@ float4 ps(VOut input) : SV_Target if(all(fragmentCoords == centerCoords)) { RWByteAddressBuffer shaderIndexBuffer = ResourceDescriptorHeap[shaderIndexBufferIndex]; - uint frameIndex = (shaderTrace >> 1) & 3; - uint shaderIndex = shaderTrace >> 3; - shaderIndexBuffer.Store(frameIndex * 4, shaderIndex); + uint shaderIndex = shaderTrace >> 1; + shaderIndexBuffer.Store(0, shaderIndex); } } diff --git a/code/renderer/shaders/crp/transp_resolve.hlsl b/code/renderer/shaders/crp/transp_resolve.hlsl index 8bfc1f6..6894e10 100644 --- a/code/renderer/shaders/crp/transp_resolve.hlsl +++ b/code/renderer/shaders/crp/transp_resolve.hlsl @@ -145,6 +145,7 @@ float4 ps(VOut input) : SV_Target } // blend the results + int lastFragmentIndex = -1; float storedDepthZW = depthTex.Load(int3(input.position.xy, 0)).x; // stored depth, z/w float dstDepth = 1.0; for(i = 0; i < fragmentCount; ++i) @@ -159,6 +160,7 @@ float4 ps(VOut input) : SV_Target } float4 fragColor = UnpackColor(frag.color); + float4 prevColor = color; fragColor = DepthFadeFragmentColor(fragColor, frag, storedDepthZW); color = Blend(fragColor, color, frag.stateBits); if((stateBits & GLS_DEPTHMASK_TRUE) != 0u && @@ -166,12 +168,17 @@ float4 ps(VOut input) : SV_Target { dstDepth = fragDepth; } + + // we have to not include the alpha channel in this test for it to be correct + if(any(color.rgb != prevColor.rgb)) + { + lastFragmentIndex = (int)i; + } } - // write out the fragment shader ID of the closest fragment of the center pixel - if(fragmentCount > 0) + // write out the fragment shader ID of the closest visible fragment of the center pixel + if(lastFragmentIndex >= 0) { - uint lastFragmentIndex = fragmentCount - 1; OIT_Fragment closest = sorted[lastFragmentIndex]; uint shaderTrace = closest.shaderTrace; if(shaderTrace & 1) @@ -181,9 +188,8 @@ float4 ps(VOut input) : SV_Target if(all(fragmentCoords == centerCoords)) { RWByteAddressBuffer shaderIdBuf = ResourceDescriptorHeap[shaderIndexBuffer]; - uint frameIndex = (shaderTrace >> 1) & 3; - uint shaderId = shaderTrace >> 3; - shaderIdBuf.Store(frameIndex * 4, shaderId); + uint shaderIndex = shaderTrace >> 1; + shaderIdBuf.Store(0, shaderIndex); } } } diff --git a/code/renderer/shaders/grp/uber_shader.hlsl b/code/renderer/shaders/grp/uber_shader.hlsl index fb85994..e597cee 100644 --- a/code/renderer/shaders/grp/uber_shader.hlsl +++ b/code/renderer/shaders/grp/uber_shader.hlsl @@ -177,7 +177,7 @@ cbuffer RootConstants float greyscale; // shader trace - uint shaderTrace; // shader index: 14 - frame index: 2 - enable: 1 + uint shaderTrace; // shader index: 14 - enable: 1 uint centerPixel; // y: 16 - x: 16 // depth fade @@ -281,9 +281,8 @@ float4 ps(VOut input) : SV_Target uint2 centerCoords = uint2(centerPixel & 0xFFFF, centerPixel >> 16); if(all(fragmentCoords == centerCoords)) { - uint frameIndex = (shaderTrace >> 1) & 3; - uint shaderIndex = shaderTrace >> 3; - shaderIndexBuffer.Store(frameIndex * 4, shaderIndex); + uint shaderIndex = shaderTrace >> 1; + shaderIndexBuffer.Store(0, shaderIndex); } } diff --git a/code/renderer/srp_main.cpp b/code/renderer/srp_main.cpp index 7b92746..57f8d17 100644 --- a/code/renderer/srp_main.cpp +++ b/code/renderer/srp_main.cpp @@ -496,9 +496,9 @@ void SRP::EndFrame() CmdBufferBarrier(traceRenderBuffer, ResourceStates::UnorderedAccessBit); CmdEndBarrier(); - // grab last frame's result - uint32_t* shaderIndices = (uint32_t*)MapBuffer(traceReadbackBuffer); - const uint32_t shaderIndex = shaderIndices[RHI::GetFrameIndex() ^ 1]; + // grab the currently available result + uint32_t* const shaderIndices = (uint32_t*)MapBuffer(traceReadbackBuffer); + const uint32_t shaderIndex = *shaderIndices; UnmapBuffer(traceReadbackBuffer); if(shaderIndex < (uint32_t)tr.numShaders) { @@ -527,12 +527,12 @@ void SRP::EndFrame() void SRP::CreateShaderTraceBuffers() { { - BufferDesc desc("shader trace opaque", 2 * sizeof(uint32_t), ResourceStates::UnorderedAccessBit); + BufferDesc desc("shader trace render", sizeof(uint32_t), ResourceStates::UnorderedAccessBit); traceRenderBuffer = CreateBuffer(desc); } { - BufferDesc desc("shader trace opaque readback", 2 * sizeof(uint32_t), ResourceStates::Common); + BufferDesc desc("shader trace readback", sizeof(uint32_t), ResourceStates::Common); desc.memoryUsage = MemoryUsage::Readback; traceReadbackBuffer = CreateBuffer(desc); }