summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando S2023-08-19 17:28:28 +0200
committerGravatar GitHub2023-08-19 17:28:28 +0200
commit6a5db5679b61d3d73244e42682f1b34d401e7736 (patch)
tree5390c22be68674fd964b49a745c495f13cf71e0d /src
parentMerge pull request #11278 from Kelebek1/dma_sync (diff)
parentMasked depthstencil clears (diff)
downloadyuzu-6a5db5679b61d3d73244e42682f1b34d401e7736.tar.gz
yuzu-6a5db5679b61d3d73244e42682f1b34d401e7736.tar.xz
yuzu-6a5db5679b61d3d73244e42682f1b34d401e7736.zip
Merge pull request #11320 from Kelebek1/mask_depthstencil_clear
Support masked depthstencil clears
Diffstat (limited to 'src')
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt1
-rw-r--r--src/video_core/host_shaders/vulkan_depthstencil_clear.frag12
-rw-r--r--src/video_core/renderer_vulkan/blit_image.cpp79
-rw-r--r--src/video_core/renderer_vulkan/blit_image.h19
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp30
5 files changed, 132 insertions, 9 deletions
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt
index e61d9af80..c4d459077 100644
--- a/src/video_core/host_shaders/CMakeLists.txt
+++ b/src/video_core/host_shaders/CMakeLists.txt
@@ -50,6 +50,7 @@ set(SHADER_FILES
50 vulkan_blit_depth_stencil.frag 50 vulkan_blit_depth_stencil.frag
51 vulkan_color_clear.frag 51 vulkan_color_clear.frag
52 vulkan_color_clear.vert 52 vulkan_color_clear.vert
53 vulkan_depthstencil_clear.frag
53 vulkan_fidelityfx_fsr_easu_fp16.comp 54 vulkan_fidelityfx_fsr_easu_fp16.comp
54 vulkan_fidelityfx_fsr_easu_fp32.comp 55 vulkan_fidelityfx_fsr_easu_fp32.comp
55 vulkan_fidelityfx_fsr_rcas_fp16.comp 56 vulkan_fidelityfx_fsr_rcas_fp16.comp
diff --git a/src/video_core/host_shaders/vulkan_depthstencil_clear.frag b/src/video_core/host_shaders/vulkan_depthstencil_clear.frag
new file mode 100644
index 000000000..1ac177c7e
--- /dev/null
+++ b/src/video_core/host_shaders/vulkan_depthstencil_clear.frag
@@ -0,0 +1,12 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#version 460 core
5
6layout (push_constant) uniform PushConstants {
7 vec4 clear_depth;
8};
9
10void main() {
11 gl_FragDepth = clear_depth.x;
12}
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp
index f74ae972e..1032c9d12 100644
--- a/src/video_core/renderer_vulkan/blit_image.cpp
+++ b/src/video_core/renderer_vulkan/blit_image.cpp
@@ -16,6 +16,7 @@
16#include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" 16#include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h"
17#include "video_core/host_shaders/vulkan_color_clear_frag_spv.h" 17#include "video_core/host_shaders/vulkan_color_clear_frag_spv.h"
18#include "video_core/host_shaders/vulkan_color_clear_vert_spv.h" 18#include "video_core/host_shaders/vulkan_color_clear_vert_spv.h"
19#include "video_core/host_shaders/vulkan_depthstencil_clear_frag_spv.h"
19#include "video_core/renderer_vulkan/blit_image.h" 20#include "video_core/renderer_vulkan/blit_image.h"
20#include "video_core/renderer_vulkan/maxwell_to_vk.h" 21#include "video_core/renderer_vulkan/maxwell_to_vk.h"
21#include "video_core/renderer_vulkan/vk_scheduler.h" 22#include "video_core/renderer_vulkan/vk_scheduler.h"
@@ -428,6 +429,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
428 blit_depth_stencil_frag(BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV)), 429 blit_depth_stencil_frag(BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV)),
429 clear_color_vert(BuildShader(device, VULKAN_COLOR_CLEAR_VERT_SPV)), 430 clear_color_vert(BuildShader(device, VULKAN_COLOR_CLEAR_VERT_SPV)),
430 clear_color_frag(BuildShader(device, VULKAN_COLOR_CLEAR_FRAG_SPV)), 431 clear_color_frag(BuildShader(device, VULKAN_COLOR_CLEAR_FRAG_SPV)),
432 clear_stencil_frag(BuildShader(device, VULKAN_DEPTHSTENCIL_CLEAR_FRAG_SPV)),
431 convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), 433 convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)),
432 convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), 434 convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)),
433 convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), 435 convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)),
@@ -593,6 +595,28 @@ void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u8 color_ma
593 scheduler.InvalidateState(); 595 scheduler.InvalidateState();
594} 596}
595 597
598void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool depth_clear,
599 f32 clear_depth, u8 stencil_mask, u32 stencil_ref,
600 u32 stencil_compare_mask, const Region2D& dst_region) {
601 const BlitDepthStencilPipelineKey key{
602 .renderpass = dst_framebuffer->RenderPass(),
603 .depth_clear = depth_clear,
604 .stencil_mask = stencil_mask,
605 .stencil_compare_mask = stencil_compare_mask,
606 .stencil_ref = stencil_ref,
607 };
608 const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key);
609 const VkPipelineLayout layout = *clear_color_pipeline_layout;
610 scheduler.RequestRenderpass(dst_framebuffer);
611 scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) {
612 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
613 BindBlitState(cmdbuf, dst_region);
614 cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_depth);
615 cmdbuf.Draw(3, 1, 0, 0);
616 });
617 scheduler.InvalidateState();
618}
619
596void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, 620void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
597 const ImageView& src_image_view) { 621 const ImageView& src_image_view) {
598 const VkPipelineLayout layout = *one_texture_pipeline_layout; 622 const VkPipelineLayout layout = *one_texture_pipeline_layout;
@@ -820,6 +844,61 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel
820 return *clear_color_pipelines.back(); 844 return *clear_color_pipelines.back();
821} 845}
822 846
847VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
848 const BlitDepthStencilPipelineKey& key) {
849 const auto it = std::ranges::find(clear_stencil_keys, key);
850 if (it != clear_stencil_keys.end()) {
851 return *clear_stencil_pipelines[std::distance(clear_stencil_keys.begin(), it)];
852 }
853 clear_stencil_keys.push_back(key);
854 const std::array stages = MakeStages(*clear_color_vert, *clear_stencil_frag);
855 const auto stencil = VkStencilOpState{
856 .failOp = VK_STENCIL_OP_KEEP,
857 .passOp = VK_STENCIL_OP_REPLACE,
858 .depthFailOp = VK_STENCIL_OP_KEEP,
859 .compareOp = VK_COMPARE_OP_ALWAYS,
860 .compareMask = key.stencil_compare_mask,
861 .writeMask = key.stencil_mask,
862 .reference = key.stencil_ref,
863 };
864 const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{
865 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
866 .pNext = nullptr,
867 .flags = 0,
868 .depthTestEnable = VK_FALSE,
869 .depthWriteEnable = key.depth_clear,
870 .depthCompareOp = VK_COMPARE_OP_ALWAYS,
871 .depthBoundsTestEnable = VK_FALSE,
872 .stencilTestEnable = VK_TRUE,
873 .front = stencil,
874 .back = stencil,
875 .minDepthBounds = 0.0f,
876 .maxDepthBounds = 0.0f,
877 };
878 clear_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
879 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
880 .pNext = nullptr,
881 .flags = 0,
882 .stageCount = static_cast<u32>(stages.size()),
883 .pStages = stages.data(),
884 .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
885 .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
886 .pTessellationState = nullptr,
887 .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
888 .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
889 .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
890 .pDepthStencilState = &depth_stencil_ci,
891 .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
892 .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
893 .layout = *clear_color_pipeline_layout,
894 .renderPass = key.renderpass,
895 .subpass = 0,
896 .basePipelineHandle = VK_NULL_HANDLE,
897 .basePipelineIndex = 0,
898 }));
899 return *clear_stencil_pipelines.back();
900}
901
823void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, 902void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass,
824 bool is_target_depth) { 903 bool is_target_depth) {
825 if (pipeline) { 904 if (pipeline) {
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h
index 2976a7d91..dcfe217aa 100644
--- a/src/video_core/renderer_vulkan/blit_image.h
+++ b/src/video_core/renderer_vulkan/blit_image.h
@@ -27,6 +27,16 @@ struct BlitImagePipelineKey {
27 Tegra::Engines::Fermi2D::Operation operation; 27 Tegra::Engines::Fermi2D::Operation operation;
28}; 28};
29 29
30struct BlitDepthStencilPipelineKey {
31 constexpr auto operator<=>(const BlitDepthStencilPipelineKey&) const noexcept = default;
32
33 VkRenderPass renderpass;
34 bool depth_clear;
35 u8 stencil_mask;
36 u32 stencil_compare_mask;
37 u32 stencil_ref;
38};
39
30class BlitImageHelper { 40class BlitImageHelper {
31public: 41public:
32 explicit BlitImageHelper(const Device& device, Scheduler& scheduler, 42 explicit BlitImageHelper(const Device& device, Scheduler& scheduler,
@@ -64,6 +74,10 @@ public:
64 void ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask, 74 void ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask,
65 const std::array<f32, 4>& clear_color, const Region2D& dst_region); 75 const std::array<f32, 4>& clear_color, const Region2D& dst_region);
66 76
77 void ClearDepthStencil(const Framebuffer* dst_framebuffer, bool depth_clear, f32 clear_depth,
78 u8 stencil_mask, u32 stencil_ref, u32 stencil_compare_mask,
79 const Region2D& dst_region);
80
67private: 81private:
68 void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, 82 void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
69 const ImageView& src_image_view); 83 const ImageView& src_image_view);
@@ -76,6 +90,8 @@ private:
76 [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); 90 [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key);
77 91
78 [[nodiscard]] VkPipeline FindOrEmplaceClearColorPipeline(const BlitImagePipelineKey& key); 92 [[nodiscard]] VkPipeline FindOrEmplaceClearColorPipeline(const BlitImagePipelineKey& key);
93 [[nodiscard]] VkPipeline FindOrEmplaceClearStencilPipeline(
94 const BlitDepthStencilPipelineKey& key);
79 95
80 void ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, bool is_target_depth); 96 void ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, bool is_target_depth);
81 97
@@ -108,6 +124,7 @@ private:
108 vk::ShaderModule blit_depth_stencil_frag; 124 vk::ShaderModule blit_depth_stencil_frag;
109 vk::ShaderModule clear_color_vert; 125 vk::ShaderModule clear_color_vert;
110 vk::ShaderModule clear_color_frag; 126 vk::ShaderModule clear_color_frag;
127 vk::ShaderModule clear_stencil_frag;
111 vk::ShaderModule convert_depth_to_float_frag; 128 vk::ShaderModule convert_depth_to_float_frag;
112 vk::ShaderModule convert_float_to_depth_frag; 129 vk::ShaderModule convert_float_to_depth_frag;
113 vk::ShaderModule convert_abgr8_to_d24s8_frag; 130 vk::ShaderModule convert_abgr8_to_d24s8_frag;
@@ -122,6 +139,8 @@ private:
122 std::vector<vk::Pipeline> blit_depth_stencil_pipelines; 139 std::vector<vk::Pipeline> blit_depth_stencil_pipelines;
123 std::vector<BlitImagePipelineKey> clear_color_keys; 140 std::vector<BlitImagePipelineKey> clear_color_keys;
124 std::vector<vk::Pipeline> clear_color_pipelines; 141 std::vector<vk::Pipeline> clear_color_pipelines;
142 std::vector<BlitDepthStencilPipelineKey> clear_stencil_keys;
143 std::vector<vk::Pipeline> clear_stencil_pipelines;
125 vk::Pipeline convert_d32_to_r32_pipeline; 144 vk::Pipeline convert_d32_to_r32_pipeline;
126 vk::Pipeline convert_r32_to_d32_pipeline; 145 vk::Pipeline convert_r32_to_d32_pipeline;
127 vk::Pipeline convert_d16_to_r16_pipeline; 146 vk::Pipeline convert_d16_to_r16_pipeline;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 89aa243d2..032f694bc 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -428,15 +428,27 @@ void RasterizerVulkan::Clear(u32 layer_count) {
428 if (aspect_flags == 0) { 428 if (aspect_flags == 0) {
429 return; 429 return;
430 } 430 }
431 scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil, 431
432 clear_rect, aspect_flags](vk::CommandBuffer cmdbuf) { 432 if (use_stencil && regs.stencil_front_mask != 0xFF && regs.stencil_front_mask != 0) {
433 VkClearAttachment attachment; 433 Region2D dst_region = {
434 attachment.aspectMask = aspect_flags; 434 Offset2D{.x = clear_rect.rect.offset.x, .y = clear_rect.rect.offset.y},
435 attachment.colorAttachment = 0; 435 Offset2D{.x = clear_rect.rect.offset.x + static_cast<s32>(clear_rect.rect.extent.width),
436 attachment.clearValue.depthStencil.depth = clear_depth; 436 .y = clear_rect.rect.offset.y +
437 attachment.clearValue.depthStencil.stencil = clear_stencil; 437 static_cast<s32>(clear_rect.rect.extent.height)}};
438 cmdbuf.ClearAttachments(attachment, clear_rect); 438 blit_image.ClearDepthStencil(framebuffer, use_depth, regs.clear_depth,
439 }); 439 static_cast<u8>(regs.stencil_front_mask), regs.clear_stencil,
440 regs.stencil_front_func_mask, dst_region);
441 } else {
442 scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil,
443 clear_rect, aspect_flags](vk::CommandBuffer cmdbuf) {
444 VkClearAttachment attachment;
445 attachment.aspectMask = aspect_flags;
446 attachment.colorAttachment = 0;
447 attachment.clearValue.depthStencil.depth = clear_depth;
448 attachment.clearValue.depthStencil.stencil = clear_stencil;
449 cmdbuf.ClearAttachments(attachment, clear_rect);
450 });
451 }
440} 452}
441 453
442void RasterizerVulkan::DispatchCompute() { 454void RasterizerVulkan::DispatchCompute() {