diff options
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.h | 9 |
5 files changed, 26 insertions, 16 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 4f137e693..0c403e16a 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -728,6 +728,7 @@ public: | |||
| 728 | u32 frag_color_clamp; | 728 | u32 frag_color_clamp; |
| 729 | 729 | ||
| 730 | union { | 730 | union { |
| 731 | BitField<0, 1, u32> y_negate; | ||
| 731 | BitField<4, 1, u32> triangle_rast_flip; | 732 | BitField<4, 1, u32> triangle_rast_flip; |
| 732 | } screen_y_control; | 733 | } screen_y_control; |
| 733 | 734 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 97b9028c5..a9d29501f 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -845,7 +845,8 @@ private: | |||
| 845 | // vertex shader, and what's the value of the fourth element when inside a Tess Eval | 845 | // vertex shader, and what's the value of the fourth element when inside a Tess Eval |
| 846 | // shader. | 846 | // shader. |
| 847 | ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); | 847 | ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); |
| 848 | return "vec4(0, 0, uintBitsToFloat(instance_id.x), uintBitsToFloat(gl_VertexID))"; | 848 | // Config pack's first value is instance_id. |
| 849 | return "vec4(0, 0, uintBitsToFloat(config_pack[0]), uintBitsToFloat(gl_VertexID))"; | ||
| 849 | case Attribute::Index::FrontFacing: | 850 | case Attribute::Index::FrontFacing: |
| 850 | // TODO(Subv): Find out what the values are for the other elements. | 851 | // TODO(Subv): Find out what the values are for the other elements. |
| 851 | ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment); | 852 | ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment); |
| @@ -3507,6 +3508,11 @@ private: | |||
| 3507 | regs.SetRegisterToInteger(instr.gpr0, false, 0, "0u", 1, 1); | 3508 | regs.SetRegisterToInteger(instr.gpr0, false, 0, "0u", 1, 1); |
| 3508 | break; | 3509 | break; |
| 3509 | } | 3510 | } |
| 3511 | case Tegra::Shader::SystemVariable::Ydirection: { | ||
| 3512 | // Config pack's third value is Y_NEGATE's state. | ||
| 3513 | regs.SetRegisterToFloat(instr.gpr0, 0, "uintBitsToFloat(config_pack[2])", 1, 1); | ||
| 3514 | break; | ||
| 3515 | } | ||
| 3510 | default: { | 3516 | default: { |
| 3511 | UNIMPLEMENTED_MSG("Unhandled system move: {}", | 3517 | UNIMPLEMENTED_MSG("Unhandled system move: {}", |
| 3512 | static_cast<u32>(instr.sys20.Value())); | 3518 | static_cast<u32>(instr.sys20.Value())); |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index eea090e52..23ed91e27 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -24,8 +24,7 @@ layout (location = 0) out vec4 position; | |||
| 24 | 24 | ||
| 25 | layout(std140) uniform vs_config { | 25 | layout(std140) uniform vs_config { |
| 26 | vec4 viewport_flip; | 26 | vec4 viewport_flip; |
| 27 | uvec4 instance_id; | 27 | uvec4 config_pack; // instance_id, flip_stage, y_direction, padding |
| 28 | uvec4 flip_stage; | ||
| 29 | uvec4 alpha_test; | 28 | uvec4 alpha_test; |
| 30 | }; | 29 | }; |
| 31 | )"; | 30 | )"; |
| @@ -63,7 +62,8 @@ void main() { | |||
| 63 | out += R"( | 62 | out += R"( |
| 64 | 63 | ||
| 65 | // Check if the flip stage is VertexB | 64 | // Check if the flip stage is VertexB |
| 66 | if (flip_stage[0] == 1) { | 65 | // Config pack's second value is flip_stage |
| 66 | if (config_pack[1] == 1) { | ||
| 67 | // Viewport can be flipped, which is unsupported by glViewport | 67 | // Viewport can be flipped, which is unsupported by glViewport |
| 68 | position.xy *= viewport_flip.xy; | 68 | position.xy *= viewport_flip.xy; |
| 69 | } | 69 | } |
| @@ -71,7 +71,7 @@ void main() { | |||
| 71 | 71 | ||
| 72 | // TODO(bunnei): This is likely a hack, position.w should be interpolated as 1.0 | 72 | // TODO(bunnei): This is likely a hack, position.w should be interpolated as 1.0 |
| 73 | // For now, this is here to bring order in lieu of proper emulation | 73 | // For now, this is here to bring order in lieu of proper emulation |
| 74 | if (flip_stage[0] == 1) { | 74 | if (config_pack[1] == 1) { |
| 75 | position.w = 1.0; | 75 | position.w = 1.0; |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| @@ -101,8 +101,7 @@ layout (location = 0) out vec4 position; | |||
| 101 | 101 | ||
| 102 | layout (std140) uniform gs_config { | 102 | layout (std140) uniform gs_config { |
| 103 | vec4 viewport_flip; | 103 | vec4 viewport_flip; |
| 104 | uvec4 instance_id; | 104 | uvec4 config_pack; // instance_id, flip_stage, y_direction, padding |
| 105 | uvec4 flip_stage; | ||
| 106 | uvec4 alpha_test; | 105 | uvec4 alpha_test; |
| 107 | }; | 106 | }; |
| 108 | 107 | ||
| @@ -139,8 +138,7 @@ layout (location = 0) in vec4 position; | |||
| 139 | 138 | ||
| 140 | layout (std140) uniform fs_config { | 139 | layout (std140) uniform fs_config { |
| 141 | vec4 viewport_flip; | 140 | vec4 viewport_flip; |
| 142 | uvec4 instance_id; | 141 | uvec4 config_pack; // instance_id, flip_stage, y_direction, padding |
| 143 | uvec4 flip_stage; | ||
| 144 | uvec4 alpha_test; | 142 | uvec4 alpha_test; |
| 145 | }; | 143 | }; |
| 146 | 144 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 8b8869ecb..6a30c28d2 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp | |||
| @@ -27,16 +27,18 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh | |||
| 27 | alpha_test.func = func; | 27 | alpha_test.func = func; |
| 28 | alpha_test.ref = regs.alpha_test_ref; | 28 | alpha_test.ref = regs.alpha_test_ref; |
| 29 | 29 | ||
| 30 | // We only assign the instance to the first component of the vector, the rest is just padding. | 30 | instance_id = state.current_instance; |
| 31 | instance_id[0] = state.current_instance; | ||
| 32 | 31 | ||
| 33 | // Assign in which stage the position has to be flipped | 32 | // Assign in which stage the position has to be flipped |
| 34 | // (the last stage before the fragment shader). | 33 | // (the last stage before the fragment shader). |
| 35 | if (gpu.regs.shader_config[static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry)].enable) { | 34 | if (gpu.regs.shader_config[static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry)].enable) { |
| 36 | flip_stage[0] = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry); | 35 | flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry); |
| 37 | } else { | 36 | } else { |
| 38 | flip_stage[0] = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::VertexB); | 37 | flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::VertexB); |
| 39 | } | 38 | } |
| 39 | |||
| 40 | // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value. | ||
| 41 | y_direction = regs.screen_y_control.y_negate == 0 ? 1.f : -1.f; | ||
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | } // namespace OpenGL::GLShader | 44 | } // namespace OpenGL::GLShader |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 9a5d7e289..b757f5f44 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -21,8 +21,11 @@ using Tegra::Engines::Maxwell3D; | |||
| 21 | struct MaxwellUniformData { | 21 | struct MaxwellUniformData { |
| 22 | void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); | 22 | void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); |
| 23 | alignas(16) GLvec4 viewport_flip; | 23 | alignas(16) GLvec4 viewport_flip; |
| 24 | alignas(16) GLuvec4 instance_id; | 24 | struct alignas(16) { |
| 25 | alignas(16) GLuvec4 flip_stage; | 25 | GLuint instance_id; |
| 26 | GLuint flip_stage; | ||
| 27 | GLfloat y_direction; | ||
| 28 | }; | ||
| 26 | struct alignas(16) { | 29 | struct alignas(16) { |
| 27 | GLuint enabled; | 30 | GLuint enabled; |
| 28 | GLuint func; | 31 | GLuint func; |
| @@ -30,7 +33,7 @@ struct MaxwellUniformData { | |||
| 30 | GLuint padding; | 33 | GLuint padding; |
| 31 | } alpha_test; | 34 | } alpha_test; |
| 32 | }; | 35 | }; |
| 33 | static_assert(sizeof(MaxwellUniformData) == 64, "MaxwellUniformData structure size is incorrect"); | 36 | static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect"); |
| 34 | static_assert(sizeof(MaxwellUniformData) < 16384, | 37 | static_assert(sizeof(MaxwellUniformData) < 16384, |
| 35 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); | 38 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); |
| 36 | 39 | ||