From f23cb756334c7c49a99aa45c1fd15e467d35f32d Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 5 Jan 2023 14:31:05 +0000 Subject: [PATCH] Make sure sample mask does not affect normal texture overlays --- renderdoc/driver/gl/gl_overlay.cpp | 3 ++ renderdoc/driver/vulkan/vk_overlay.cpp | 16 ++++++++++ util/test/demos/d3d11/d3d11_overlay_test.cpp | 10 ++++++ util/test/demos/d3d12/d3d12_overlay_test.cpp | 15 +++++++++ util/test/demos/gl/gl_overlay_test.cpp | 13 ++++++++ util/test/demos/vk/vk_overlay_test.cpp | 22 ++++++++++++++ util/test/rdtest/shared/Overlay_Test.py | 32 ++++++++++++++++++++ 7 files changed, 111 insertions(+) diff --git a/renderdoc/driver/gl/gl_overlay.cpp b/renderdoc/driver/gl/gl_overlay.cpp index 26024501e..cfa25d803 100644 --- a/renderdoc/driver/gl/gl_overlay.cpp +++ b/renderdoc/driver/gl/gl_overlay.cpp @@ -677,6 +677,9 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug drv.glEnable(eGL_DEPTH_CLAMP); } + if(HasExt[ARB_texture_multisample_no_array] || HasExt[ARB_texture_multisample]) + drv.glDisable(eGL_SAMPLE_MASK); + if(HasExt[ARB_viewport_array]) { for(size_t s = 0; s < ARRAY_COUNT(rs.Scissors); s++) diff --git a/renderdoc/driver/vulkan/vk_overlay.cpp b/renderdoc/driver/vulkan/vk_overlay.cpp index 2d3e493ce..c268d26b9 100644 --- a/renderdoc/driver/vulkan/vk_overlay.cpp +++ b/renderdoc/driver/vulkan/vk_overlay.cpp @@ -852,6 +852,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D rs->cullMode = VK_CULL_MODE_NONE; rs->rasterizerDiscardEnable = false; + VkPipelineMultisampleStateCreateInfo *msaa = + (VkPipelineMultisampleStateCreateInfo *)pipeCreateInfo.pMultisampleState; + msaa->pSampleMask = NULL; + // disable tests in dynamic state too state.depthTestEnable = VK_FALSE; state.depthWriteEnable = VK_FALSE; @@ -1145,6 +1149,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D rs->cullMode = VK_CULL_MODE_NONE; // first render without any culling rs->rasterizerDiscardEnable = false; + VkPipelineMultisampleStateCreateInfo *msaa = + (VkPipelineMultisampleStateCreateInfo *)pipeCreateInfo.pMultisampleState; + msaa->pSampleMask = NULL; + // disable tests in dynamic state too state.depthTestEnable = VK_FALSE; state.depthWriteEnable = VK_FALSE; @@ -1439,6 +1447,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D rs->cullMode = VK_CULL_MODE_NONE; // first render without any culling rs->rasterizerDiscardEnable = false; + VkPipelineMultisampleStateCreateInfo *msaa = + (VkPipelineMultisampleStateCreateInfo *)pipeCreateInfo.pMultisampleState; + msaa->pSampleMask = NULL; + if(m_pDriver->GetDeviceEnabledFeatures().depthClamp) rs->depthClampEnable = true; @@ -1732,6 +1744,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D ds->stencilTestEnable = false; ds->depthBoundsTestEnable = false; + VkPipelineMultisampleStateCreateInfo *msaa = + (VkPipelineMultisampleStateCreateInfo *)pipeCreateInfo.pMultisampleState; + msaa->pSampleMask = NULL; + VkPipelineColorBlendStateCreateInfo *cb = (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; cb->logicOpEnable = false; diff --git a/util/test/demos/d3d11/d3d11_overlay_test.cpp b/util/test/demos/d3d11/d3d11_overlay_test.cpp index 3fe0da768..7ff809665 100644 --- a/util/test/demos/d3d11/d3d11_overlay_test.cpp +++ b/util/test/demos/d3d11/d3d11_overlay_test.cpp @@ -222,6 +222,16 @@ float4 main() : SV_Target0 RSSetScissor({24, 24, 76, 76}); ctx->Draw(3, 33); } + + if(rtv == msaartv) + { + setMarker("Sample Mask Test"); + RSSetViewport({0.0f, 0.0f, 80.0f, 80.0f, 0.0f, 1.0f}); + RSSetScissor({0, 0, 80, 80}); + ctx->OMSetBlendState(NULL, NULL, 0x2); + ctx->Draw(3, 6); + ctx->OMSetBlendState(NULL, NULL, ~0U); + } } ctx->PSSetShader(whiteps, NULL, 0); diff --git a/util/test/demos/d3d12/d3d12_overlay_test.cpp b/util/test/demos/d3d12/d3d12_overlay_test.cpp index d1942dd86..28063714a 100644 --- a/util/test/demos/d3d12/d3d12_overlay_test.cpp +++ b/util/test/demos/d3d12/d3d12_overlay_test.cpp @@ -201,6 +201,7 @@ float4 main() : SV_Target0 ID3D12PipelineStatePtr backgroundPipe[3][2]; ID3D12PipelineStatePtr pipe[3][2]; ID3D12PipelineStatePtr whitepipe[3]; + ID3D12PipelineStatePtr sampleMaskPipe[3]; for(int i = 0; i < 3; i++) { @@ -252,6 +253,10 @@ float4 main() : SV_Target0 creator.GraphicsDesc.SampleDesc = yesMSAA; pipe[i][1] = creator; + creator.GraphicsDesc.SampleMask = 0x2; + sampleMaskPipe[i] = creator; + creator.GraphicsDesc.SampleMask = 0xFFFFFFFF; + creator.GraphicsDesc.DepthStencilState.StencilEnable = FALSE; creator.GraphicsDesc.DepthStencilState.DepthEnable = FALSE; creator.GraphicsDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS; @@ -351,6 +356,16 @@ float4 main() : SV_Target0 cmd->SetPipelineState(backgroundPipe[pass][0]); cmd->DrawInstanced(3, 1, 33, 0); } + + if(is_msaa) + { + setMarker(cmd, "Sample Mask Test"); + + RSSetViewport(cmd, {0.0f, 0.0f, 80.0f, 80.0f, 0.0f, 1.0f}); + RSSetScissorRect(cmd, {0, 0, 80, 80}); + cmd->SetPipelineState(sampleMaskPipe[pass]); + cmd->DrawInstanced(3, 1, 6, 0); + } } D3D12_CPU_DESCRIPTOR_HANDLE subrtv = MakeRTV(subtex) diff --git a/util/test/demos/gl/gl_overlay_test.cpp b/util/test/demos/gl/gl_overlay_test.cpp index b275e3063..817118c52 100644 --- a/util/test/demos/gl/gl_overlay_test.cpp +++ b/util/test/demos/gl/gl_overlay_test.cpp @@ -294,6 +294,19 @@ void main() glDrawArrays(GL_TRIANGLES, 33, 3); } + if(fb == msaafbo) + { + setMarker("Sample Mask Test"); + glDisable(GL_STENCIL_TEST); + glEnable(GL_SAMPLE_MASK); + glSampleMaski(0, 0x2); + glViewport(0, screenHeight - 80, 80, 80); + glScissor(0, screenHeight - 80, 80, 80); + glDrawArrays(GL_TRIANGLES, 6, 3); + glSampleMaski(0, ~0U); + glDisable(GL_SAMPLE_MASK); + } + glScissor(0, 0, screenWidth, screenHeight); } diff --git a/util/test/demos/vk/vk_overlay_test.cpp b/util/test/demos/vk/vk_overlay_test.cpp index b79233e80..98ddd60c4 100644 --- a/util/test/demos/vk/vk_overlay_test.cpp +++ b/util/test/demos/vk/vk_overlay_test.cpp @@ -339,6 +339,12 @@ void main() pipeCreateInfo.renderPass = msaaRP; pipe[1] = createGraphicsPipeline(pipeCreateInfo); + VkPipeline sampleMaskPipe; + const uint32_t sampleMask = 0x2; + pipeCreateInfo.multisampleState.pSampleMask = &sampleMask; + sampleMaskPipe = createGraphicsPipeline(pipeCreateInfo); + pipeCreateInfo.multisampleState.pSampleMask = NULL; + pipeCreateInfo.stages[1] = CompileShaderModule(whitepixel, ShaderLang::glsl, ShaderStage::frag, "main"); pipeCreateInfo.stages[1].pSpecializationInfo = &spec; @@ -514,6 +520,22 @@ void main() vkCmdDraw(cmd, 3, 1, 33, 0); } + if(is_msaa) + { + setMarker(cmd, "Sample Mask Test"); + v = {0.0f, 0.0f, 80.0f, 80.0f, 0.0f, 1.0f}; + if(KHR_maintenance1) + { + v.y += v.height; + v.height = -v.height; + } + s = {{0, 0}, {80, 80}}; + vkCmdSetViewport(cmd, 0, 1, &v); + vkCmdSetScissor(cmd, 0, 1, &s); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, sampleMaskPipe); + vkCmdDraw(cmd, 3, 1, 6, 0); + } + vkCmdEndRenderPass(cmd); } diff --git a/util/test/rdtest/shared/Overlay_Test.py b/util/test/rdtest/shared/Overlay_Test.py index cd03b3f34..6e3b32b18 100644 --- a/util/test/rdtest/shared/Overlay_Test.py +++ b/util/test/rdtest/shared/Overlay_Test.py @@ -506,11 +506,43 @@ class Overlay_Test(rdtest.TestCase): rdtest.log.success("Overlays are as expected around viewport/scissor behaviour") + # Check the sample mask test + mask_marker: rd.ActionDescription = self.find_action("Sample Mask Test", base_event) + + self.controller.SetFrameEvent(mask_marker.next.eventId, True) + + col_tex: rd.ResourceId = pipe.GetOutputTargets()[0].resourceId + + # Check just highlight drawcall to make sure it renders on sample 0 + tex.resourceId = col_tex + tex.overlay = rd.DebugOverlay.Drawcall + out.SetTextureDisplay(tex) + out.Display() + + overlay_id: rd.ResourceId = out.GetDebugOverlayTexID() + + save_data = rd.TextureSave() + save_data.resourceId = overlay_id + save_data.destType = rd.FileType.PNG + + self.controller.SaveTexture(save_data, rdtest.get_tmp_path('overlay.png')) + + eps = 1.0/256.0 + + self.check_pixel_value(overlay_id, 40, 15, [0.8, 0.1, 0.8, 1.0], eps=eps) + self.check_pixel_value(overlay_id, 40, 70, [0.8, 0.1, 0.8, 1.0], eps=eps) + self.check_pixel_value(overlay_id, 40, 1, [0.0, 0.0, 0.0, 0.5], eps=eps) + self.check_pixel_value(overlay_id, 40, 90, [0.0, 0.0, 0.0, 0.5], eps=eps) + + rdtest.log.success("Overlays are as expected around sample mask behaviour") + test_marker: rd.ActionDescription = self.find_action("Normal Test", base_event) # Now check clear-before-X by hand, for colour and for depth self.controller.SetFrameEvent(test_marker.next.eventId, True) + col_tex: rd.ResourceId = pipe.GetOutputTargets()[0].resourceId + depth_tex: rd.ResourceId = pipe.GetDepthTarget().resourceId eps = 1.0/256.0