summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-12-19 01:43:29 -0300
committerGravatar ReinUsesLisp2019-12-19 16:24:45 -0300
commit485c21eac3adbc29258da09a16cc8067aaa9b366 (patch)
tree50223386e64221071fc74f60b97eae7552359004 /src
parentvk_shader_decompiler: Update sirit and implement Texture AOFFI (diff)
downloadyuzu-485c21eac3adbc29258da09a16cc8067aaa9b366.tar.gz
yuzu-485c21eac3adbc29258da09a16cc8067aaa9b366.tar.xz
yuzu-485c21eac3adbc29258da09a16cc8067aaa9b366.zip
vk_shader_decompiler: Normalize output fragment attachments
Some games write from fragment shaders to an unexistant framebuffer attachment or they don't write to one when it exists in the framebuffer. Fix this by skipping writes or adding zeroes.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp21
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h3
2 files changed, 12 insertions, 12 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 93e2704b4..c84f9e4be 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -543,7 +543,7 @@ private:
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>(frag_colors.size()); ++rt) {
546 if (!IsRenderTargetUsed(rt)) { 546 if (!specialization.enabled_rendertargets[rt]) {
547 continue; 547 continue;
548 } 548 }
549 549
@@ -1868,12 +1868,18 @@ private:
1868 // rendertargets/components are skipped in the register assignment. 1868 // rendertargets/components are skipped in the register assignment.
1869 u32 current_reg = 0; 1869 u32 current_reg = 0;
1870 for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) { 1870 for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) {
1871 if (!specialization.enabled_rendertargets[rt]) {
1872 // Skip rendertargets that are not enabled
1873 continue;
1874 }
1871 // TODO(Subv): Figure out how dual-source blending is configured in the Switch. 1875 // TODO(Subv): Figure out how dual-source blending is configured in the Switch.
1872 for (u32 component = 0; component < 4; ++component) { 1876 for (u32 component = 0; component < 4; ++component) {
1877 const Id pointer = AccessElement(t_out_float, frag_colors.at(rt), component);
1873 if (header.ps.IsColorComponentOutputEnabled(rt, component)) { 1878 if (header.ps.IsColorComponentOutputEnabled(rt, component)) {
1874 OpStore(AccessElement(t_out_float, frag_colors.at(rt), component), 1879 OpStore(pointer, SafeGetRegister(current_reg));
1875 SafeGetRegister(current_reg));
1876 ++current_reg; 1880 ++current_reg;
1881 } else {
1882 OpStore(pointer, component == 3 ? v_float_one : v_float_zero);
1877 } 1883 }
1878 } 1884 }
1879 } 1885 }
@@ -2003,15 +2009,6 @@ private:
2003 return DeclareBuiltIn(builtin, spv::StorageClass::Input, type, std::move(name)); 2009 return DeclareBuiltIn(builtin, spv::StorageClass::Input, type, std::move(name));
2004 } 2010 }
2005 2011
2006 bool IsRenderTargetUsed(u32 rt) const {
2007 for (u32 component = 0; component < 4; ++component) {
2008 if (header.ps.IsColorComponentOutputEnabled(rt, component)) {
2009 return true;
2010 }
2011 }
2012 return false;
2013 }
2014
2015 template <typename... Args> 2012 template <typename... Args>
2016 Id AccessElement(Id pointer_type, Id composite, Args... elements_) { 2013 Id AccessElement(Id pointer_type, Id composite, Args... elements_) {
2017 std::vector<Id> members; 2014 std::vector<Id> members;
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index 2b01321b6..415801b6c 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -101,6 +101,9 @@ struct Specialization final {
101 Maxwell::TessellationSpacing spacing{}; 101 Maxwell::TessellationSpacing spacing{};
102 bool clockwise{}; 102 bool clockwise{};
103 } tessellation; 103 } tessellation;
104
105 // Fragment specific
106 std::bitset<8> enabled_rendertargets;
104}; 107};
105// Old gcc versions don't consider this trivially copyable. 108// Old gcc versions don't consider this trivially copyable.
106// static_assert(std::is_trivially_copyable_v<Specialization>); 109// static_assert(std::is_trivially_copyable_v<Specialization>);