diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.h | 3 |
3 files changed, 16 insertions, 19 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 48e23d4cd..7ddf7d3ee 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -325,9 +325,6 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | |||
| 325 | specialization.tessellation.primitive = fixed_state.tessellation.primitive; | 325 | specialization.tessellation.primitive = fixed_state.tessellation.primitive; |
| 326 | specialization.tessellation.spacing = fixed_state.tessellation.spacing; | 326 | specialization.tessellation.spacing = fixed_state.tessellation.spacing; |
| 327 | specialization.tessellation.clockwise = fixed_state.tessellation.clockwise; | 327 | specialization.tessellation.clockwise = fixed_state.tessellation.clockwise; |
| 328 | for (const auto& rt : key.renderpass_params.color_attachments) { | ||
| 329 | specialization.enabled_rendertargets.set(rt.index); | ||
| 330 | } | ||
| 331 | 328 | ||
| 332 | SPIRVProgram program; | 329 | SPIRVProgram program; |
| 333 | std::vector<vk::DescriptorSetLayoutBinding> bindings; | 330 | std::vector<vk::DescriptorSetLayoutBinding> bindings; |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index dd6d2ef03..b53078721 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -542,11 +542,10 @@ private: | |||
| 542 | return; | 542 | return; |
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | for (u32 rt = 0; rt < static_cast<u32>(frag_colors.size()); ++rt) { | 545 | for (u32 rt = 0; rt < static_cast<u32>(std::size(frag_colors)); ++rt) { |
| 546 | if (!specialization.enabled_rendertargets[rt]) { | 546 | if (!IsRenderTargetEnabled(rt)) { |
| 547 | continue; | 547 | continue; |
| 548 | } | 548 | } |
| 549 | |||
| 550 | const Id id = AddGlobalVariable(OpVariable(t_out_float4, spv::StorageClass::Output)); | 549 | const Id id = AddGlobalVariable(OpVariable(t_out_float4, spv::StorageClass::Output)); |
| 551 | Name(id, fmt::format("frag_color{}", rt)); | 550 | Name(id, fmt::format("frag_color{}", rt)); |
| 552 | Decorate(id, spv::Decoration::Location, rt); | 551 | Decorate(id, spv::Decoration::Location, rt); |
| @@ -852,6 +851,15 @@ private: | |||
| 852 | return binding; | 851 | return binding; |
| 853 | } | 852 | } |
| 854 | 853 | ||
| 854 | bool IsRenderTargetEnabled(u32 rt) const { | ||
| 855 | for (u32 component = 0; component < 4; ++component) { | ||
| 856 | if (header.ps.IsColorComponentOutputEnabled(rt, component)) { | ||
| 857 | return true; | ||
| 858 | } | ||
| 859 | } | ||
| 860 | return false; | ||
| 861 | } | ||
| 862 | |||
| 855 | bool IsInputAttributeArray() const { | 863 | bool IsInputAttributeArray() const { |
| 856 | return stage == ShaderType::TesselationControl || stage == ShaderType::TesselationEval || | 864 | return stage == ShaderType::TesselationControl || stage == ShaderType::TesselationEval || |
| 857 | stage == ShaderType::Geometry; | 865 | stage == ShaderType::Geometry; |
| @@ -1889,19 +1897,14 @@ private: | |||
| 1889 | // rendertargets/components are skipped in the register assignment. | 1897 | // rendertargets/components are skipped in the register assignment. |
| 1890 | u32 current_reg = 0; | 1898 | u32 current_reg = 0; |
| 1891 | for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) { | 1899 | for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) { |
| 1892 | if (!specialization.enabled_rendertargets[rt]) { | ||
| 1893 | // Skip rendertargets that are not enabled | ||
| 1894 | continue; | ||
| 1895 | } | ||
| 1896 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. | 1900 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. |
| 1897 | for (u32 component = 0; component < 4; ++component) { | 1901 | for (u32 component = 0; component < 4; ++component) { |
| 1898 | const Id pointer = AccessElement(t_out_float, frag_colors.at(rt), component); | 1902 | if (!header.ps.IsColorComponentOutputEnabled(rt, component)) { |
| 1899 | if (header.ps.IsColorComponentOutputEnabled(rt, component)) { | 1903 | continue; |
| 1900 | OpStore(pointer, SafeGetRegister(current_reg)); | ||
| 1901 | ++current_reg; | ||
| 1902 | } else { | ||
| 1903 | OpStore(pointer, component == 3 ? v_float_one : v_float_zero); | ||
| 1904 | } | 1904 | } |
| 1905 | const Id pointer = AccessElement(t_out_float, frag_colors[rt], component); | ||
| 1906 | OpStore(pointer, SafeGetRegister(current_reg)); | ||
| 1907 | ++current_reg; | ||
| 1905 | } | 1908 | } |
| 1906 | } | 1909 | } |
| 1907 | if (header.ps.omap.depth) { | 1910 | if (header.ps.omap.depth) { |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h index 10794be1c..f5dc14d9e 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h | |||
| @@ -102,9 +102,6 @@ struct Specialization final { | |||
| 102 | Maxwell::TessellationSpacing spacing{}; | 102 | Maxwell::TessellationSpacing spacing{}; |
| 103 | bool clockwise{}; | 103 | bool clockwise{}; |
| 104 | } tessellation; | 104 | } tessellation; |
| 105 | |||
| 106 | // Fragment specific | ||
| 107 | std::bitset<8> enabled_rendertargets; | ||
| 108 | }; | 105 | }; |
| 109 | // Old gcc versions don't consider this trivially copyable. | 106 | // Old gcc versions don't consider this trivially copyable. |
| 110 | // static_assert(std::is_trivially_copyable_v<Specialization>); | 107 | // static_assert(std::is_trivially_copyable_v<Specialization>); |