Преглед изворни кода

gl_shader_gen: Support vertical/horizontal viewport flipping. (#347)

* gl_shader_gen: Support vertical/horizontal viewport flipping.

* fixup! gl_shader_gen: Support vertical/horizontal viewport flipping.
bunnei пре 8 година
родитељ
комит
ce4f159b1c

+ 10 - 1
src/video_core/engines/maxwell_3d.h

@@ -319,7 +319,15 @@ public:
                     }
                 } rt[NumRenderTargets];
 
-                INSERT_PADDING_WORDS(0x80);
+                struct {
+                    f32 scale_x;
+                    f32 scale_y;
+                    f32 scale_z;
+                    u32 translate_x;
+                    u32 translate_y;
+                    u32 translate_z;
+                    INSERT_PADDING_WORDS(2);
+                } viewport_transform[NumViewports];
 
                 struct {
                     union {
@@ -649,6 +657,7 @@ private:
                   "Field " #field_name " has invalid position")
 
 ASSERT_REG_POSITION(rt, 0x200);
+ASSERT_REG_POSITION(viewport_transform[0], 0x280);
 ASSERT_REG_POSITION(viewport, 0x300);
 ASSERT_REG_POSITION(vertex_buffer, 0x35D);
 ASSERT_REG_POSITION(zeta, 0x3F8);

+ 10 - 0
src/video_core/renderer_opengl/gl_shader_gen.cpp

@@ -29,9 +29,15 @@ out gl_PerVertex {
 
 out vec4 position;
 
+layout (std140) uniform vs_config {
+    vec4 viewport_flip;
+};
+
 void main() {
     exec_shader();
 
+    // Viewport can be flipped, which is unsupported by glViewport
+    position.xy *= viewport_flip.xy;
     gl_Position = position;
 }
 )";
@@ -52,6 +58,10 @@ ProgramResult GenerateFragmentShader(const ShaderSetup& setup, const MaxwellFSCo
 in vec4 position;
 out vec4 color;
 
+layout (std140) uniform fs_config {
+    vec4 viewport_flip;
+};
+
 uniform sampler2D tex[32];
 
 void main() {

+ 7 - 1
src/video_core/renderer_opengl/gl_shader_manager.cpp

@@ -53,6 +53,12 @@ void SetShaderSamplerBindings(GLuint shader) {
 
 } // namespace Impl
 
-void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) {}
+void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) {
+    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+
+    // TODO(bunnei): Support more than one viewport
+    viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0 : 1.0;
+    viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0 : 1.0;
+}
 
 } // namespace GLShader

+ 2 - 3
src/video_core/renderer_opengl/gl_shader_manager.h

@@ -30,10 +30,9 @@ void SetShaderSamplerBindings(GLuint shader);
 //       Not following that rule will cause problems on some AMD drivers.
 struct MaxwellUniformData {
     void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage);
-    // TODO(Subv): Use this for something.
+    alignas(16) GLvec4 viewport_flip;
 };
-// static_assert(sizeof(MaxwellUniformData) == 1024, "MaxwellUniformData structure size is
-// incorrect");
+static_assert(sizeof(MaxwellUniformData) == 16, "MaxwellUniformData structure size is incorrect");
 static_assert(sizeof(MaxwellUniformData) < 16384,
               "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");