Przeglądaj źródła

gl_shader_manager: Move code to source file and minor clean up

ReinUsesLisp 7 lat temu
rodzic
commit
93af663683

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

@@ -2,12 +2,44 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include "common/common_types.h"
+#include "video_core/engines/maxwell_3d.h"
 #include "video_core/renderer_opengl/gl_shader_manager.h"
 
 namespace OpenGL::GLShader {
 
 using Tegra::Engines::Maxwell3D;
 
+ProgramManager::ProgramManager() {
+    pipeline.Create();
+}
+
+ProgramManager::~ProgramManager() = default;
+
+void ProgramManager::ApplyTo(OpenGLState& state) {
+    UpdatePipeline();
+    state.draw.shader_program = 0;
+    state.draw.program_pipeline = pipeline.handle;
+}
+
+void ProgramManager::UpdatePipeline() {
+    // Avoid updating the pipeline when values have no changed
+    if (old_state == current_state) {
+        return;
+    }
+
+    // Workaround for AMD bug
+    constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
+                                     GL_FRAGMENT_SHADER_BIT};
+    glUseProgramStages(pipeline.handle, all_used_stages, 0);
+
+    glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
+    glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader);
+    glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader);
+
+    old_state = current_state;
+}
+
 void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shader_stage) {
     const auto& regs = maxwell.regs;
     const auto& state = maxwell.state;
@@ -16,7 +48,7 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shade
     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;
 
-    u32 func = static_cast<u32>(regs.alpha_test_func);
+    auto func{static_cast<u32>(regs.alpha_test_func)};
     // Normalize the gl variants of opCompare to be the same as the normal variants
     const u32 op_gl_variant_base = static_cast<u32>(Maxwell3D::Regs::ComparisonOp::Never);
     if (func >= op_gl_variant_base) {

+ 28 - 33
src/video_core/renderer_opengl/gl_shader_manager.h

@@ -4,6 +4,8 @@
 
 #pragma once
 
+#include <cstddef>
+
 #include <glad/glad.h>
 
 #include "video_core/renderer_opengl/gl_resource_manager.h"
@@ -38,55 +40,48 @@ static_assert(sizeof(MaxwellUniformData) < 16384,
 
 class ProgramManager {
 public:
-    ProgramManager() {
-        pipeline.Create();
-    }
+    explicit ProgramManager();
+    ~ProgramManager();
+
+    void ApplyTo(OpenGLState& state);
 
     void UseProgrammableVertexShader(GLuint program) {
-        vs = program;
+        current_state.vertex_shader = program;
     }
 
     void UseProgrammableGeometryShader(GLuint program) {
-        gs = program;
+        current_state.geometry_shader = program;
     }
 
     void UseProgrammableFragmentShader(GLuint program) {
-        fs = program;
+        current_state.fragment_shader = program;
     }
 
     void UseTrivialGeometryShader() {
-        gs = 0;
-    }
-
-    void ApplyTo(OpenGLState& state) {
-        UpdatePipeline();
-        state.draw.shader_program = 0;
-        state.draw.program_pipeline = pipeline.handle;
+        current_state.geometry_shader = 0;
     }
 
 private:
-    void UpdatePipeline() {
-        // Avoid updating the pipeline when values have no changed
-        if (old_vs == vs && old_fs == fs && old_gs == gs)
-            return;
-        // Workaround for AMD bug
-        glUseProgramStages(pipeline.handle,
-                           GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | GL_FRAGMENT_SHADER_BIT,
-                           0);
-
-        glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, vs);
-        glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, gs);
-        glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fs);
-
-        // Update the old values
-        old_vs = vs;
-        old_fs = fs;
-        old_gs = gs;
-    }
+    struct PipelineState {
+        bool operator==(const PipelineState& rhs) const {
+            return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader &&
+                   geometry_shader == rhs.geometry_shader;
+        }
+
+        bool operator!=(const PipelineState& rhs) const {
+            return !operator==(rhs);
+        }
+
+        GLuint vertex_shader{};
+        GLuint fragment_shader{};
+        GLuint geometry_shader{};
+    };
+
+    void UpdatePipeline();
 
     OGLPipeline pipeline;
-    GLuint vs{}, fs{}, gs{};
-    GLuint old_vs{}, old_fs{}, old_gs{};
+    PipelineState current_state;
+    PipelineState old_state;
 };
 
 } // namespace OpenGL::GLShader