diff --git a/util/test/demos/d3d11/d3d11_overlay_test.cpp b/util/test/demos/d3d11/d3d11_overlay_test.cpp index b2e083839..c61f8ab47 100644 --- a/util/test/demos/d3d11/d3d11_overlay_test.cpp +++ b/util/test/demos/d3d11/d3d11_overlay_test.cpp @@ -69,6 +69,34 @@ PixOut main(v2f IN) return OUT; } +)EOSHADER"; + + std::string discardPixel = R"EOSHADER( + +struct v2f +{ + float4 pos : SV_POSITION; + float4 col : COLOR0; + float2 uv : TEXCOORD0; +}; + +struct PixOut +{ + float4 colour : SV_Target0; +}; + +PixOut main(v2f IN) +{ + PixOut OUT; + OUT.colour = IN.col; + if ((IN.pos.x > 327.0) && (IN.pos.x < 339.0) && + (IN.pos.y > 38.0) && (IN.pos.y < 48.0)) + { + discard; + } + return OUT; +} + )EOSHADER"; int main() @@ -86,6 +114,7 @@ PixOut main(v2f IN) ID3D11PixelShaderPtr ps = CreatePS(psblob); ID3D11PixelShaderPtr whiteps = CreatePS(Compile(whitePixel, "main", "ps_4_0")); ID3D11PixelShaderPtr depthwriteps = CreatePS(Compile(depthWritePixel, "main", "ps_4_0")); + ID3D11PixelShaderPtr discardps = CreatePS(Compile(discardPixel, "main", "ps_4_0")); const DefaultA2V VBData[] = { // this triangle occludes in depth @@ -164,6 +193,11 @@ PixOut main(v2f IN) {Vec3f(+1.0f, -1.0f, 0.99f), Vec4f(0.2f, 0.2f, 0.2f, 1.0f), Vec2f(0.0f, 0.0f)}, {Vec3f(-1.0f, +1.0f, 0.99f), Vec4f(0.2f, 0.2f, 0.2f, 1.0f), Vec2f(0.0f, 0.0f)}, {Vec3f(+1.0f, +1.0f, 0.99f), Vec4f(0.2f, 0.2f, 0.2f, 1.0f), Vec2f(0.0f, 0.0f)}, + + // discard rectangle + {Vec3f(0.6f, +0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)}, + {Vec3f(0.7f, +0.9f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)}, + {Vec3f(0.8f, +0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)}, }; ID3D11BufferPtr vb = MakeBuffer().Vertex().Data(VBData); @@ -299,6 +333,11 @@ PixOut main(v2f IN) SetDepthState(depth); ctx->PSSetShader(depthwriteps, NULL, 0); ctx->Draw(24, 9); + + markerName = "Discard " + markerName; + setMarker(markerName); + ctx->PSSetShader(discardps, NULL, 0); + ctx->Draw(3, 42); ctx->PSSetShader(ps, NULL, 0); depth.StencilEnable = FALSE; diff --git a/util/test/demos/d3d12/d3d12_overlay_test.cpp b/util/test/demos/d3d12/d3d12_overlay_test.cpp index 4317b991b..8857b3784 100644 --- a/util/test/demos/d3d12/d3d12_overlay_test.cpp +++ b/util/test/demos/d3d12/d3d12_overlay_test.cpp @@ -110,6 +110,34 @@ PixOut main(v2f IN) else { OUT.depth = IN.pos.z; + } + return OUT; +} + +)EOSHADER"; + + std::string discardPixel = R"EOSHADER( + +struct v2f +{ + float4 col : COLOR0; + float2 uv : TEXCOORD0; + float4 pos : SV_POSITION; +}; + +struct PixOut +{ + float4 colour : SV_Target0; +}; + +PixOut main(v2f IN) +{ + PixOut OUT; + OUT.colour = IN.col; + if ((IN.pos.x > 327.0) && (IN.pos.x < 339.0) && + (IN.pos.y > 38.0) && (IN.pos.y < 48.0)) + { + discard; } return OUT; } @@ -126,6 +154,7 @@ PixOut main(v2f IN) ID3DBlobPtr psblob[3] = {}; ID3DBlobPtr whitepsblob[3] = {}; ID3DBlobPtr depthwritepsblob[3] = {}; + ID3DBlobPtr discardpsblob[3] = {}; { int i = 0; @@ -138,6 +167,7 @@ PixOut main(v2f IN) psblob[i] = Compile(vertexEndPosPixel, "main", "ps" + profile); whitepsblob[i] = Compile(whitePixel, "main", "ps" + profile); depthwritepsblob[i] = Compile(depthWritePixel, "main", "ps" + profile); + discardpsblob[i] = Compile(discardPixel, "main", "ps" + profile); i++; } } @@ -205,6 +235,11 @@ PixOut main(v2f IN) {Vec3f(-1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 0.0f)}, {Vec3f(0.0f, 1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 1.0f)}, {Vec3f(1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(1.0f, 0.0f)}, + + // discard rectangle + {Vec3f(0.6f, +0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)}, + {Vec3f(0.7f, +0.9f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)}, + {Vec3f(0.8f, +0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)}, }; ID3D12ResourcePtr vb = MakeBuffer().Data(VBData); @@ -228,6 +263,7 @@ PixOut main(v2f IN) ID3D12PipelineStatePtr backgroundPipe[3][countFmts][2]; ID3D12PipelineStatePtr pipe[3][countFmts][2]; ID3D12PipelineStatePtr depthWritePixelShaderPipe[3][countFmts][2]; + ID3D12PipelineStatePtr discardPixelShaderPipe[3][countFmts][2]; ID3D12PipelineStatePtr whitepipe[3]; ID3D12PipelineStatePtr sampleMaskPipe[3][countFmts]; @@ -307,6 +343,12 @@ PixOut main(v2f IN) creator.GraphicsDesc.SampleDesc = yesMSAA; depthWritePixelShaderPipe[i][f][1] = creator; + creator.PS(discardpsblob[i]); + creator.GraphicsDesc.SampleDesc = noMSAA; + discardPixelShaderPipe[i][f][0] = creator; + creator.GraphicsDesc.SampleDesc = yesMSAA; + discardPixelShaderPipe[i][f][1] = creator; + creator.PS(psblob[i]); creator.GraphicsDesc.SampleDesc = yesMSAA; sampleMaskPipe[i][f] = creator; @@ -446,6 +488,11 @@ PixOut main(v2f IN) cmd->SetPipelineState(depthWritePixelShaderPipe[pass][f][is_msaa ? 1 : 0]); cmd->DrawInstanced(24, 1, 9, 0); + + markerName = "Discard " + markerName; + setMarker(cmd, markerName); + cmd->SetPipelineState(discardPixelShaderPipe[pass][f][is_msaa ? 1 : 0]); + cmd->DrawInstanced(3, 1, 36, 0); cmd->SetPipelineState(pipe[pass][f][is_msaa ? 1 : 0]); if(!is_msaa) diff --git a/util/test/demos/gl/gl_overlay_test.cpp b/util/test/demos/gl/gl_overlay_test.cpp index 191e5e6e4..9ab60d6bb 100644 --- a/util/test/demos/gl/gl_overlay_test.cpp +++ b/util/test/demos/gl/gl_overlay_test.cpp @@ -106,6 +106,25 @@ void main() } } +)EOSHADER"; + + std::string discardpixel = R"EOSHADER( + +in v2f vertIn; + +layout(location = 0, index = 0) out vec4 Color; + +void main() +{ + Color = vertIn.col; + + if ((gl_FragCoord.x > 327.0) && (gl_FragCoord.x < 339.0) && + (gl_FragCoord.y > 252.0) && (gl_FragCoord.y < 262.0)) + { + discard; + } +} + )EOSHADER"; int main() @@ -182,6 +201,11 @@ void main() {Vec3f(-1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 0.0f)}, {Vec3f(0.0f, 1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 1.0f)}, {Vec3f(1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(1.0f, 0.0f)}, + + // discard rectangle + {Vec3f(0.6f, +0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)}, + {Vec3f(0.7f, +0.9f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)}, + {Vec3f(0.8f, +0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)}, }; GLuint vb = MakeBuffer(); @@ -200,6 +224,7 @@ void main() GLuint program = MakeProgram(common + vertex, common + pixel); GLuint whiteprogram = MakeProgram(common + vertex, whitepixel); GLuint fragdepthprogram = MakeProgram(common + vertex, common + fragdepthpixel); + GLuint discardprogram = MakeProgram(common + vertex, common + discardpixel); const char *fmtNames[] = {"D24_S8", "D32F_S8", "D16_S0", "D24_S0", "D32F_S0"}; GLenum fmts[] = {GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT16, @@ -354,6 +379,11 @@ void main() glStencilFunc(GL_GREATER, 0x55, 0xff); glUseProgram(fragdepthprogram); glDrawArrays(GL_TRIANGLES, 9, 24); + + markerName = "Discard " + markerName; + setMarker(markerName); + glUseProgram(discardprogram); + glDrawArrays(GL_TRIANGLES, 36, 3); glUseProgram(program); if(!is_msaa) diff --git a/util/test/demos/vk/vk_overlay_test.cpp b/util/test/demos/vk/vk_overlay_test.cpp index f8c008c3f..5d01c2651 100644 --- a/util/test/demos/vk/vk_overlay_test.cpp +++ b/util/test/demos/vk/vk_overlay_test.cpp @@ -144,6 +144,36 @@ void main() if(spec_canary != 1338) { Color = vec4(1.0, 0.0, 0.0, 1.0); return; } } +)EOSHADER"; + + std::string discardPixel = R"EOSHADER( + +layout(location = 0) in v2f vertIn; + +layout(location = 0, index = 0) out vec4 Color; + +layout(constant_id = 2) const int spec_canary = 0; + +layout(binding = 0) uniform texture2D tex[64]; + +void main() +{ + if(vertIn.uv.z > 100.0f) + { + Color += texelFetch(tex[uint(vertIn.uv.z) % 50], ivec2(vertIn.uv.xy * vec2(4,4)), 0) * 0.001f; + } + + Color = vertIn.col; + + if ((gl_FragCoord.x > 327.0) && (gl_FragCoord.x < 339.0) && + (gl_FragCoord.y > 38.0) && (gl_FragCoord.y < 48.0)) + { + discard; + } + + if(spec_canary != 1338) { Color = vec4(1.0, 0.0, 0.0, 1.0); return; } +} + )EOSHADER"; int main() @@ -246,6 +276,11 @@ void main() {Vec3f(+1.0f, -1.0f, 0.99f), Vec4f(0.2f, 0.2f, 0.2f, 1.0f), Vec2f(0.0f, 0.0f)}, {Vec3f(+1.0f, +1.0f, 0.99f), Vec4f(0.2f, 0.2f, 0.2f, 1.0f), Vec2f(0.0f, 0.0f)}, {Vec3f(-1.0f, +1.0f, 0.99f), Vec4f(0.2f, 0.2f, 0.2f, 1.0f), Vec2f(0.0f, 0.0f)}, + + // discard rectangle + {Vec3f(0.6f, -0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)}, + {Vec3f(0.7f, -0.9f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)}, + {Vec3f(0.8f, -0.7f, 0.5f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)}, }; // negate y if we're using negative viewport height @@ -430,6 +465,7 @@ void main() std::vector stencilClearPipes; std::vector backgroundPipes; std::vector depthWritePixelShaderPipes; + std::vector discardPixelShaderPipes; std::vector sampleMaskPipes; std::vector drawPipes; @@ -437,6 +473,8 @@ void main() CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"); VkPipelineShaderStageCreateInfo depthWriteFragShader = CompileShaderModule(common + depthWritePixel, ShaderLang::glsl, ShaderStage::frag, "main"); + VkPipelineShaderStageCreateInfo discardFragShader = + CompileShaderModule(common + discardPixel, ShaderLang::glsl, ShaderStage::frag, "main"); for(size_t f = 0; f < supportedFmts.size(); ++f) { @@ -515,6 +553,15 @@ void main() pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; pipeCreateInfo.renderPass = msaaRPs[f]; depthWritePixelShaderPipes.push_back(createGraphicsPipeline(pipeCreateInfo)); + + pipeCreateInfo.stages[1] = discardFragShader; + pipeCreateInfo.stages[1].pSpecializationInfo = &spec; + pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + pipeCreateInfo.renderPass = renderPasses[f]; + discardPixelShaderPipes.push_back(createGraphicsPipeline(pipeCreateInfo)); + pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; + pipeCreateInfo.renderPass = msaaRPs[f]; + discardPixelShaderPipes.push_back(createGraphicsPipeline(pipeCreateInfo)); } pipeCreateInfo.stages[1] = @@ -685,6 +732,11 @@ void main() vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, depthWritePixelShaderPipes[pipeIndex]); vkCmdDraw(cmd, 24, 1, 9, 0); + + markerName = "Discard " + markerName; + setMarker(cmd, markerName); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, discardPixelShaderPipes[pipeIndex]); + vkCmdDraw(cmd, 3, 1, 42, 0); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, drawPipes[pipeIndex]); if(!is_msaa) diff --git a/util/test/rdtest/shared/Overlay_Test.py b/util/test/rdtest/shared/Overlay_Test.py index 484711a8d..547b48a8a 100644 --- a/util/test/rdtest/shared/Overlay_Test.py +++ b/util/test/rdtest/shared/Overlay_Test.py @@ -421,6 +421,16 @@ class Overlay_Test(rdtest.TestCase): else: rdtest.log.success("All normal overlays are as expected Format {}".format(fmt)) + # Shader with discard + test_marker: rd.ActionDescription = self.find_action("Discard " + marker_name, base_event) + self.controller.SetFrameEvent(test_marker.next.eventId, True) + pipe: rd.PipeState = self.controller.GetPipelineState() + tex.overlay = rd.DebugOverlay.Depth + out.SetTextureDisplay(tex) + out.Display() + overlay_id: rd.ResourceId = out.GetDebugOverlayTexID() + self.check_pixel_value(overlay_id, 330, 40, [0.0, 1.0, 0.0, 1.0], eps=eps) + # Check the viewport overlay especially view_marker: rd.ActionDescription = self.find_action("Viewport Test " + fmt, base_event)