Explorar o código

Use standard UBO and fix/stylize the code

FernandoS27 %!s(int64=7) %!d(string=hai) anos
pai
achega
59a004f915

+ 0 - 15
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -323,8 +323,6 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
         current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,
         current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,
                                                   primitive_mode, current_texture_bindpoint);
                                                   primitive_mode, current_texture_bindpoint);
 
 
-        SetupAlphaTesting(shader);
-
         // When VertexA is enabled, we have dual vertex shaders
         // When VertexA is enabled, we have dual vertex shaders
         if (program == Maxwell::ShaderProgram::VertexA) {
         if (program == Maxwell::ShaderProgram::VertexA) {
             // VertexB was combined with VertexA, so we skip the VertexB iteration
             // VertexB was combined with VertexA, so we skip the VertexB iteration
@@ -882,19 +880,6 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
     return current_unit + static_cast<u32>(entries.size());
     return current_unit + static_cast<u32>(entries.size());
 }
 }
 
 
-void RasterizerOpenGL::SetupAlphaTesting(Shader& shader) {
-    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
-
-    u32 func = static_cast<u32>(regs.alpha_test_func);
-    // Normalize the gl variants of opCompare to be the same as the normal variants
-    u32 op = static_cast<u32>(Tegra::Engines::Maxwell3D::Regs::ComparisonOp::Never);
-    if (func >= op) {
-        func = func - op + 1U;
-    }
-
-    shader->SetAlphaTesting(regs.alpha_test_enabled == 1, regs.alpha_test_ref, func);
-}
-
 void RasterizerOpenGL::SyncViewport() {
 void RasterizerOpenGL::SyncViewport() {
     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
     const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
     const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};

+ 0 - 3
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -132,9 +132,6 @@ private:
     u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader,
     u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader,
                       GLenum primitive_mode, u32 current_unit);
                       GLenum primitive_mode, u32 current_unit);
 
 
-    /// Syncs the alpha test state to match the guest state
-    void SetupAlphaTesting(Shader& shader);
-
     /// Syncs the viewport to match the guest state
     /// Syncs the viewport to match the guest state
     void SyncViewport();
     void SyncViewport();
 
 

+ 0 - 20
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -94,10 +94,6 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type)
         // Store shader's code to lazily build it on draw
         // Store shader's code to lazily build it on draw
         geometry_programs.code = program_result.first;
         geometry_programs.code = program_result.first;
     }
     }
-
-    if (program_type == Maxwell::ShaderProgram::Fragment) {
-        SaveAlphaTestingLocations();
-    }
 }
 }
 
 
 GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) {
 GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) {
@@ -138,22 +134,6 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program,
     return target_program.handle;
     return target_program.handle;
 };
 };
 
 
-void CachedShader::SetAlphaTesting(const bool enable, const float ref, const u32 func) {
-    if (program_type == Maxwell::ShaderProgram::Fragment) {
-        glProgramUniform1ui(program.handle, alpha_test.enable_loc,
-                            (enable ? 1 : 0));
-        glProgramUniform1f(program.handle, alpha_test.ref_loc,
-                           ref);
-        glProgramUniform1ui(program.handle, alpha_test.func_loc, func);
-    }
-}
-
-void CachedShader::SaveAlphaTestingLocations() {
-    alpha_test.enable_loc = glGetUniformLocation(program.handle, "alpha_testing_enable");
-    alpha_test.ref_loc = glGetUniformLocation(program.handle, "alpha_testing_ref");
-    alpha_test.func_loc = glGetUniformLocation(program.handle, "alpha_testing_func");
-}
-
 Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
 Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
     const VAddr program_addr{GetShaderAddress(program)};
     const VAddr program_addr{GetShaderAddress(program)};
 
 

+ 0 - 10
src/video_core/renderer_opengl/gl_shader_cache.h

@@ -73,15 +73,11 @@ public:
     /// Gets the GL uniform location for the specified resource, caching as needed
     /// Gets the GL uniform location for the specified resource, caching as needed
     GLint GetUniformLocation(const GLShader::SamplerEntry& sampler);
     GLint GetUniformLocation(const GLShader::SamplerEntry& sampler);
 
 
-    void SetAlphaTesting(const bool enable, const float ref, const u32 func);
-
 private:
 private:
     /// Generates a geometry shader or returns one that already exists.
     /// Generates a geometry shader or returns one that already exists.
     GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology,
     GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology,
                                const std::string& debug_name);
                                const std::string& debug_name);
 
 
-    void SaveAlphaTestingLocations();
-
     VAddr addr;
     VAddr addr;
     Maxwell::ShaderProgram program_type;
     Maxwell::ShaderProgram program_type;
     GLShader::ShaderSetup setup;
     GLShader::ShaderSetup setup;
@@ -102,12 +98,6 @@ private:
         OGLProgram triangles_adjacency;
         OGLProgram triangles_adjacency;
     } geometry_programs;
     } geometry_programs;
 
 
-    struct {
-        GLint enable_loc;
-        GLint ref_loc;
-        GLint func_loc;
-    } alpha_test;
-
     std::map<u32, GLuint> resource_cache;
     std::map<u32, GLuint> resource_cache;
     std::map<u32, GLint> uniform_cache;
     std::map<u32, GLint> uniform_cache;
 };
 };

+ 5 - 41
src/video_core/renderer_opengl/gl_shader_decompiler.cpp

@@ -643,13 +643,6 @@ private:
                                  ';');
                                  ';');
         }
         }
         declarations.AddNewLine();
         declarations.AddNewLine();
-
-        if (stage == Maxwell3D::Regs::ShaderStage::Fragment) {
-            declarations.AddLine("uniform bool alpha_testing_active;");
-            declarations.AddLine("uniform float alpha_testing_ref;");
-            declarations.AddLine("uniform uint alpha_testing_func;");
-        }
-        declarations.AddNewLine();
     }
     }
 
 
     /// Generates declarations used for geometry shaders.
     /// Generates declarations used for geometry shaders.
@@ -1271,17 +1264,20 @@ private:
 
 
         ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented");
         ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented");
 
 
-        shader.AddLine("if (alpha_testing_active) {");
+        shader.AddLine("if (alpha_test[0] != 0) {");
         ++shader.scope;
         ++shader.scope;
+        // We start on the register containing the alpha value in the first RT.
         u32 current_reg = 3;
         u32 current_reg = 3;
         for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets;
         for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets;
              ++render_target) {
              ++render_target) {
+            // TODO(Blinkhawk): verify the behavior of alpha testing on hardware when
+            // multiple render targets are used.
             if (header.ps.IsColorComponentOutputEnabled(render_target, 0) ||
             if (header.ps.IsColorComponentOutputEnabled(render_target, 0) ||
                 header.ps.IsColorComponentOutputEnabled(render_target, 1) ||
                 header.ps.IsColorComponentOutputEnabled(render_target, 1) ||
                 header.ps.IsColorComponentOutputEnabled(render_target, 2) ||
                 header.ps.IsColorComponentOutputEnabled(render_target, 2) ||
                 header.ps.IsColorComponentOutputEnabled(render_target, 3)) {
                 header.ps.IsColorComponentOutputEnabled(render_target, 3)) {
                 shader.AddLine(fmt::format(
                 shader.AddLine(fmt::format(
-                    "if (AlphaFunc({}, alpha_testing_ref, alpha_testing_func)) discard;",
+                    "if (AlphaFunc({})) discard;",
                     regs.GetRegisterAsFloat(current_reg)));
                     regs.GetRegisterAsFloat(current_reg)));
                 current_reg += 4;
                 current_reg += 4;
             }
             }
@@ -3506,38 +3502,6 @@ private:
             declarations.AddLine("bool " + pred + " = false;");
             declarations.AddLine("bool " + pred + " = false;");
         }
         }
         declarations.AddNewLine();
         declarations.AddNewLine();
-        GenerateFunctionDeclarations();
-    }
-
-    void GenerateFunctionDeclarations() {
-        if (stage == Maxwell3D::Regs::ShaderStage::Fragment) {
-            declarations.AddLine("bool AlphaFunc(in float value, in float ref, in uint func) {");
-            declarations.scope++;
-            declarations.AddLine("switch (func) {");
-            declarations.scope++;
-            declarations.AddLine("case 1:");
-            declarations.AddLine("return false;");
-            declarations.AddLine("case 2:");
-            declarations.AddLine("return value < ref;");
-            declarations.AddLine("case 3:");
-            declarations.AddLine("return value == ref;");
-            declarations.AddLine("case 4:");
-            declarations.AddLine("return value <= ref;");
-            declarations.AddLine("case 5:");
-            declarations.AddLine("return value > ref;");
-            declarations.AddLine("case 6:");
-            declarations.AddLine("return value != ref;");
-            declarations.AddLine("case 7:");
-            declarations.AddLine("return value >= ref;");
-            declarations.AddLine("case 8:");
-            declarations.AddLine("return true;");
-            declarations.AddLine("default:");
-            declarations.AddLine("return false;");
-            declarations.scope--;
-            declarations.AddLine('}');
-            declarations.scope--;
-            declarations.AddLine('}');
-        }
     }
     }
 
 
 private:
 private:

+ 28 - 1
src/video_core/renderer_opengl/gl_shader_gen.cpp

@@ -29,6 +29,7 @@ layout(std140) uniform vs_config {
     vec4 viewport_flip;
     vec4 viewport_flip;
     uvec4 instance_id;
     uvec4 instance_id;
     uvec4 flip_stage;
     uvec4 flip_stage;
+    uvec4 alpha_test;
 };
 };
 )";
 )";
 
 
@@ -105,6 +106,7 @@ layout (std140) uniform gs_config {
     vec4 viewport_flip;
     vec4 viewport_flip;
     uvec4 instance_id;
     uvec4 instance_id;
     uvec4 flip_stage;
     uvec4 flip_stage;
+    uvec4 alpha_test;
 };
 };
 
 
 void main() {
 void main() {
@@ -142,8 +144,33 @@ layout (std140) uniform fs_config {
     vec4 viewport_flip;
     vec4 viewport_flip;
     uvec4 instance_id;
     uvec4 instance_id;
     uvec4 flip_stage;
     uvec4 flip_stage;
+    uvec4 alpha_test;
 };
 };
 
 
+bool AlphaFunc(in float value) {
+    float ref = uintBitsToFloat(alpha_test[2]);
+    switch (alpha_test[1]) {
+        case 1:
+            return false;
+        case 2:
+            return value < ref;
+        case 3:
+            return value == ref;
+        case 4:
+            return value <= ref;
+        case 5:
+            return value > ref;
+        case 6:
+            return value != ref;
+        case 7:
+            return value >= ref;
+        case 8:
+            return true;
+        default:
+            return false;
+    }
+}
+
 void main() {
 void main() {
     exec_fragment();
     exec_fragment();
 }
 }
@@ -152,4 +179,4 @@ void main() {
     out += program.first;
     out += program.first;
     return {out, program.second};
     return {out, program.second};
 }
 }
-} // namespace OpenGL::GLShader
+} // namespace OpenGL::GLShader

+ 11 - 0
src/video_core/renderer_opengl/gl_shader_manager.cpp

@@ -16,6 +16,17 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh
     viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f;
     viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f;
     viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f;
     viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f;
 
 
+    u32 func = static_cast<u32>(regs.alpha_test_func);
+    // Normalize the gl variants of opCompare to be the same as the normal variants
+    u32 op_gl_variant_base = static_cast<u32>(Tegra::Engines::Maxwell3D::Regs::ComparisonOp::Never);
+    if (func >= op_gl_variant_base) {
+        func = func - op_gl_variant_base + 1U;
+    }
+
+    alpha_test.enabled = regs.alpha_test_enabled;
+    alpha_test.func = func;
+    alpha_test.ref = regs.alpha_test_ref;
+
     // We only assign the instance to the first component of the vector, the rest is just padding.
     // We only assign the instance to the first component of the vector, the rest is just padding.
     instance_id[0] = state.current_instance;
     instance_id[0] = state.current_instance;
 
 

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

@@ -22,8 +22,14 @@ struct MaxwellUniformData {
     alignas(16) GLvec4 viewport_flip;
     alignas(16) GLvec4 viewport_flip;
     alignas(16) GLuvec4 instance_id;
     alignas(16) GLuvec4 instance_id;
     alignas(16) GLuvec4 flip_stage;
     alignas(16) GLuvec4 flip_stage;
+    struct alignas(16) {
+        GLuint enabled;
+        GLuint func;
+        GLfloat ref;
+        GLuint padding;
+    } alpha_test;
 };
 };
-static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect");
+static_assert(sizeof(MaxwellUniformData) == 64, "MaxwellUniformData structure size is incorrect");
 static_assert(sizeof(MaxwellUniformData) < 16384,
 static_assert(sizeof(MaxwellUniformData) < 16384,
               "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");
               "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");