From 8e7988dc109f8bf4dce669a2384574996048cb24 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sun, 22 Dec 2024 17:48:22 -0800 Subject: [PATCH 1/2] renderer_vulkan: Simplify depth pipeline state and move stencil to dynamic state. --- .../renderer_vulkan/vk_graphics_pipeline.cpp | 33 ++++--------------- .../renderer_vulkan/vk_graphics_pipeline.h | 9 +++-- .../renderer_vulkan/vk_pipeline_cache.cpp | 14 ++++---- .../renderer_vulkan/vk_rasterizer.cpp | 28 ++++++++++++++++ 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 3cba7a7e45..265c7bd3d2 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -123,7 +123,7 @@ GraphicsPipeline::GraphicsPipeline( .frontFace = key.front_face == Liverpool::FrontFace::Clockwise ? vk::FrontFace::eClockwise : vk::FrontFace::eCounterClockwise, - .depthBiasEnable = bool(key.depth_bias_enable), + .depthBiasEnable = key.depth_bias_enable, .lineWidth = 1.0f, }; @@ -164,6 +164,7 @@ GraphicsPipeline::GraphicsPipeline( vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthBounds, vk::DynamicState::eDepthBias, vk::DynamicState::eStencilReference, vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, + vk::DynamicState::eStencilOpEXT, }; if (instance.IsColorWriteEnableSupported()) { @@ -182,31 +183,11 @@ GraphicsPipeline::GraphicsPipeline( }; const vk::PipelineDepthStencilStateCreateInfo depth_info = { - .depthTestEnable = key.depth_stencil.depth_enable, - .depthWriteEnable = key.depth_stencil.depth_write_enable, - .depthCompareOp = LiverpoolToVK::CompareOp(key.depth_stencil.depth_func), - .depthBoundsTestEnable = key.depth_stencil.depth_bounds_enable, - .stencilTestEnable = key.depth_stencil.stencil_enable, - .front{ - .failOp = LiverpoolToVK::StencilOp(key.stencil.stencil_fail_front), - .passOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zpass_front), - .depthFailOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zfail_front), - .compareOp = LiverpoolToVK::CompareOp(key.depth_stencil.stencil_ref_func), - }, - .back{ - .failOp = LiverpoolToVK::StencilOp(key.depth_stencil.backface_enable - ? key.stencil.stencil_fail_back.Value() - : key.stencil.stencil_fail_front.Value()), - .passOp = LiverpoolToVK::StencilOp(key.depth_stencil.backface_enable - ? key.stencil.stencil_zpass_back.Value() - : key.stencil.stencil_zpass_front.Value()), - .depthFailOp = LiverpoolToVK::StencilOp(key.depth_stencil.backface_enable - ? key.stencil.stencil_zfail_back.Value() - : key.stencil.stencil_zfail_front.Value()), - .compareOp = LiverpoolToVK::CompareOp(key.depth_stencil.backface_enable - ? key.depth_stencil.stencil_bf_func.Value() - : key.depth_stencil.stencil_ref_func.Value()), - }, + .depthTestEnable = key.depth_test_enable, + .depthWriteEnable = key.depth_write_enable, + .depthCompareOp = key.depth_compare_op, + .depthBoundsTestEnable = key.depth_bounds_test_enable, + .stencilTestEnable = key.stencil_test_enable, }; boost::container::static_vector diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 5a1e3c27f2..b565c9b8d0 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -36,11 +36,14 @@ struct GraphicsPipelineKey { vk::Format depth_format; vk::Format stencil_format; - Liverpool::DepthControl depth_stencil; - u32 depth_bias_enable; + bool depth_test_enable; + bool depth_write_enable; + bool depth_bounds_test_enable; + bool depth_bias_enable; + vk::CompareOp depth_compare_op; + bool stencil_test_enable; u32 num_samples; u32 mrt_mask; - Liverpool::StencilControl stencil; AmdGpu::PrimitiveType prim_type; u32 enable_primitive_restart; u32 primitive_restart_index; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a7d7866880..e774b1d42c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -258,11 +258,13 @@ bool PipelineCache::RefreshGraphicsKey() { auto& regs = liverpool->regs; auto& key = graphics_key; - key.depth_stencil = regs.depth_control; - key.stencil = regs.stencil_control; - key.depth_stencil.depth_write_enable.Assign(regs.depth_control.depth_write_enable.Value() && - !regs.depth_render_control.depth_clear_enable); + key.depth_test_enable = regs.depth_control.depth_enable; + key.depth_write_enable = + regs.depth_control.depth_write_enable && !regs.depth_render_control.depth_clear_enable; + key.depth_bounds_test_enable = regs.depth_control.depth_bounds_enable; key.depth_bias_enable = regs.polygon_control.NeedsBias(); + key.depth_compare_op = LiverpoolToVK::CompareOp(regs.depth_control.depth_func); + key.stencil_test_enable = regs.depth_control.stencil_enable; const auto depth_format = instance.GetSupportedFormat( LiverpoolToVK::DepthFormat(regs.depth_buffer.z_info.format, @@ -272,13 +274,13 @@ bool PipelineCache::RefreshGraphicsKey() { key.depth_format = depth_format; } else { key.depth_format = vk::Format::eUndefined; - key.depth_stencil.depth_enable.Assign(false); + key.depth_test_enable = false; } if (regs.depth_buffer.StencilValid()) { key.stencil_format = depth_format; } else { key.stencil_format = vk::Format::eUndefined; - key.depth_stencil.stencil_enable.Assign(false); + key.stencil_test_enable = false; } key.prim_type = regs.primitive_type; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 44772b4c49..55f8610131 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -963,7 +963,33 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) { cmdbuf.setDepthBias(regs.poly_offset.back_offset, regs.poly_offset.depth_bias, regs.poly_offset.back_scale / 16.f); } + if (regs.depth_control.stencil_enable) { + const auto front_fail_op = + LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_front); + const auto front_pass_op = + LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_front); + const auto front_depth_fail_op = + LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_front); + const auto front_compare_op = LiverpoolToVK::CompareOp(regs.depth_control.stencil_ref_func); + if (regs.depth_control.backface_enable) { + const auto back_fail_op = + LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_back); + const auto back_pass_op = + LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_back); + const auto back_depth_fail_op = + LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_back); + const auto back_compare_op = + LiverpoolToVK::CompareOp(regs.depth_control.stencil_bf_func); + cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFront, front_fail_op, front_pass_op, + front_depth_fail_op, front_compare_op); + cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eBack, back_fail_op, back_pass_op, + back_depth_fail_op, back_compare_op); + } else { + cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFrontAndBack, front_fail_op, + front_pass_op, front_depth_fail_op, front_compare_op); + } + const auto front = regs.stencil_ref_front; const auto back = regs.stencil_ref_back; if (front.stencil_test_val == back.stencil_test_val) { @@ -973,6 +999,7 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) { cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFront, front.stencil_test_val); cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eBack, back.stencil_test_val); } + if (front.stencil_write_mask == back.stencil_write_mask) { cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, front.stencil_write_mask); @@ -980,6 +1007,7 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) { cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFront, front.stencil_write_mask); cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eBack, back.stencil_write_mask); } + if (front.stencil_mask == back.stencil_mask) { cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack, front.stencil_mask); From e8533207cd24ad6c57748e323b4f42f3fb17761d Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Tue, 24 Dec 2024 03:39:14 -0800 Subject: [PATCH 2/2] Change graphics key depth-stencil flags to bitfields. --- .../renderer_vulkan/vk_graphics_pipeline.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index b565c9b8d0..ee8afa3e6c 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -36,12 +36,17 @@ struct GraphicsPipelineKey { vk::Format depth_format; vk::Format stencil_format; - bool depth_test_enable; - bool depth_write_enable; - bool depth_bounds_test_enable; - bool depth_bias_enable; + struct { + bool depth_test_enable : 1; + bool depth_write_enable : 1; + bool depth_bounds_test_enable : 1; + bool depth_bias_enable : 1; + bool stencil_test_enable : 1; + // Must be named to be zero-initialized. + u8 _unused : 3; + }; vk::CompareOp depth_compare_op; - bool stencil_test_enable; + u32 num_samples; u32 mrt_mask; AmdGpu::PrimitiveType prim_type;