diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/engines/shader_header.h | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 25 |
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 | ||
| 11 | namespace Tegra::Shader { | 11 | namespace 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 | ||
| 95 | static_assert(sizeof(Header) == 0x50, "Incorrect structure size"); | 101 | static_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 | ||
| 691 | private: | 691 | private: |
| 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 | ||