summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/shader_header.h24
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp25
2 files changed, 18 insertions, 31 deletions
diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h
index 4663377ed..a885ee3cf 100644
--- a/src/video_core/engines/shader_header.h
+++ b/src/video_core/engines/shader_header.h
@@ -5,8 +5,8 @@
5#pragma once 5#pragma once
6 6
7#include "common/bit_field.h" 7#include "common/bit_field.h"
8#include "common/common_types.h"
9#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "common/common_types.h"
10 10
11namespace Tegra::Shader { 11namespace Tegra::Shader {
12 12
@@ -72,7 +72,7 @@ struct Header {
72 INSERT_PADDING_BYTES(2); // OmapSystemValuesC 72 INSERT_PADDING_BYTES(2); // OmapSystemValuesC
73 INSERT_PADDING_BYTES(5); // OmapFixedFncTexture[10] 73 INSERT_PADDING_BYTES(5); // OmapFixedFncTexture[10]
74 INSERT_PADDING_BYTES(1); // OmapReserved 74 INSERT_PADDING_BYTES(1); // OmapReserved
75 } ps; 75 } vtg;
76 76
77 struct { 77 struct {
78 INSERT_PADDING_BYTES(3); // ImapSystemValuesA 78 INSERT_PADDING_BYTES(3); // ImapSystemValuesA
@@ -82,14 +82,20 @@ struct Header {
82 INSERT_PADDING_BYTES(2); // ImapSystemValuesC 82 INSERT_PADDING_BYTES(2); // ImapSystemValuesC
83 INSERT_PADDING_BYTES(10); // ImapFixedFncTexture[10] 83 INSERT_PADDING_BYTES(10); // ImapFixedFncTexture[10]
84 INSERT_PADDING_BYTES(2); // ImapReserved 84 INSERT_PADDING_BYTES(2); // ImapReserved
85 INSERT_PADDING_BYTES(4); // OmapTarget[8] 85 struct {
86 union { 86 u32 target;
87 BitField<0, 1, u32> omap_sample_mask; 87 union {
88 BitField<1, 1, u32> omap_depth; 88 BitField<0, 1, u32> sample_mask;
89 BitField<2, 30, u32> omap_reserved; 89 BitField<1, 1, u32> depth;
90 BitField<2, 30, u32> reserved;
91 };
90 } omap; 92 } omap;
91 } vtg; 93 bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const {
92 } sph; 94 const u32 bit = render_target * 4 + component;
95 return omap.target & (1 << bit);
96 }
97 } ps;
98 };
93}; 99};
94 100
95static_assert(sizeof(Header) == 0x50, "Incorrect structure size"); 101static_assert(sizeof(Header) == 0x50, "Incorrect structure size");
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index d826d98eb..434faf9d4 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -689,23 +689,6 @@ public:
689 } 689 }
690 690
691private: 691private:
692 // Shader program header for a Fragment Shader.
693 struct FragmentHeader {
694 INSERT_PADDING_WORDS(5);
695 INSERT_PADDING_WORDS(13);
696 u32 enabled_color_outputs;
697 union {
698 BitField<0, 1, u32> writes_samplemask;
699 BitField<1, 1, u32> writes_depth;
700 };
701
702 bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const {
703 const u32 bit = render_target * 4 + component;
704 return enabled_color_outputs & (1 << bit);
705 }
706 };
707 static_assert(sizeof(FragmentHeader) == PROGRAM_HEADER_SIZE, "FragmentHeader size is wrong");
708
709 /// Gets the Subroutine object corresponding to the specified address. 692 /// Gets the Subroutine object corresponding to the specified address.
710 const Subroutine& GetSubroutine(u32 begin, u32 end) const { 693 const Subroutine& GetSubroutine(u32 begin, u32 end) const {
711 const auto iter = subroutines.find(Subroutine{begin, end, suffix}); 694 const auto iter = subroutines.find(Subroutine{begin, end, suffix});
@@ -1011,10 +994,8 @@ private:
1011 /// Writes the output values from a fragment shader to the corresponding GLSL output variables. 994 /// Writes the output values from a fragment shader to the corresponding GLSL output variables.
1012 void EmitFragmentOutputsWrite() { 995 void EmitFragmentOutputsWrite() {
1013 ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment); 996 ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment);
1014 FragmentHeader header;
1015 std::memcpy(&header, program_code.data(), PROGRAM_HEADER_SIZE);
1016 997
1017 ASSERT_MSG(header.writes_samplemask == 0, "Samplemask write is unimplemented"); 998 ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented");
1018 999
1019 // Write the color outputs using the data in the shader registers, disabled 1000 // Write the color outputs using the data in the shader registers, disabled
1020 // rendertargets/components are skipped in the register assignment. 1001 // rendertargets/components are skipped in the register assignment.
@@ -1023,7 +1004,7 @@ private:
1023 ++render_target) { 1004 ++render_target) {
1024 // TODO(Subv): Figure out how dual-source blending is configured in the Switch. 1005 // TODO(Subv): Figure out how dual-source blending is configured in the Switch.
1025 for (u32 component = 0; component < 4; ++component) { 1006 for (u32 component = 0; component < 4; ++component) {
1026 if (header.IsColorComponentOutputEnabled(render_target, component)) { 1007 if (header.ps.IsColorComponentOutputEnabled(render_target, component)) {
1027 shader.AddLine(fmt::format("FragColor{}[{}] = {};", render_target, component, 1008 shader.AddLine(fmt::format("FragColor{}[{}] = {};", render_target, component,
1028 regs.GetRegisterAsFloat(current_reg))); 1009 regs.GetRegisterAsFloat(current_reg)));
1029 ++current_reg; 1010 ++current_reg;
@@ -1031,7 +1012,7 @@ private:
1031 } 1012 }
1032 } 1013 }
1033 1014
1034 if (header.writes_depth) { 1015 if (header.ps.omap.depth) {
1035 // The depth output is always 2 registers after the last color output, and current_reg 1016 // The depth output is always 2 registers after the last color output, and current_reg
1036 // already contains one past the last color register. 1017 // already contains one past the last color register.
1037 1018