summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp34
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h61
2 files changed, 61 insertions, 34 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index eaf3e03a0..05ab01dcb 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -2,12 +2,44 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/common_types.h"
6#include "video_core/engines/maxwell_3d.h"
5#include "video_core/renderer_opengl/gl_shader_manager.h" 7#include "video_core/renderer_opengl/gl_shader_manager.h"
6 8
7namespace OpenGL::GLShader { 9namespace OpenGL::GLShader {
8 10
9using Tegra::Engines::Maxwell3D; 11using Tegra::Engines::Maxwell3D;
10 12
13ProgramManager::ProgramManager() {
14 pipeline.Create();
15}
16
17ProgramManager::~ProgramManager() = default;
18
19void ProgramManager::ApplyTo(OpenGLState& state) {
20 UpdatePipeline();
21 state.draw.shader_program = 0;
22 state.draw.program_pipeline = pipeline.handle;
23}
24
25void ProgramManager::UpdatePipeline() {
26 // Avoid updating the pipeline when values have no changed
27 if (old_state == current_state) {
28 return;
29 }
30
31 // Workaround for AMD bug
32 constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
33 GL_FRAGMENT_SHADER_BIT};
34 glUseProgramStages(pipeline.handle, all_used_stages, 0);
35
36 glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
37 glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader);
38 glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader);
39
40 old_state = current_state;
41}
42
11void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shader_stage) { 43void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shader_stage) {
12 const auto& regs = maxwell.regs; 44 const auto& regs = maxwell.regs;
13 const auto& state = maxwell.state; 45 const auto& state = maxwell.state;
@@ -16,7 +48,7 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shade
16 viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; 48 viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f;
17 viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; 49 viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f;
18 50
19 u32 func = static_cast<u32>(regs.alpha_test_func); 51 auto func{static_cast<u32>(regs.alpha_test_func)};
20 // Normalize the gl variants of opCompare to be the same as the normal variants 52 // Normalize the gl variants of opCompare to be the same as the normal variants
21 const u32 op_gl_variant_base = static_cast<u32>(Maxwell3D::Regs::ComparisonOp::Never); 53 const u32 op_gl_variant_base = static_cast<u32>(Maxwell3D::Regs::ComparisonOp::Never);
22 if (func >= op_gl_variant_base) { 54 if (func >= op_gl_variant_base) {
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 37dcfefdb..cec18a832 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -4,6 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <cstddef>
8
7#include <glad/glad.h> 9#include <glad/glad.h>
8 10
9#include "video_core/renderer_opengl/gl_resource_manager.h" 11#include "video_core/renderer_opengl/gl_resource_manager.h"
@@ -38,55 +40,48 @@ static_assert(sizeof(MaxwellUniformData) < 16384,
38 40
39class ProgramManager { 41class ProgramManager {
40public: 42public:
41 ProgramManager() { 43 explicit ProgramManager();
42 pipeline.Create(); 44 ~ProgramManager();
43 } 45
46 void ApplyTo(OpenGLState& state);
44 47
45 void UseProgrammableVertexShader(GLuint program) { 48 void UseProgrammableVertexShader(GLuint program) {
46 vs = program; 49 current_state.vertex_shader = program;
47 } 50 }
48 51
49 void UseProgrammableGeometryShader(GLuint program) { 52 void UseProgrammableGeometryShader(GLuint program) {
50 gs = program; 53 current_state.geometry_shader = program;
51 } 54 }
52 55
53 void UseProgrammableFragmentShader(GLuint program) { 56 void UseProgrammableFragmentShader(GLuint program) {
54 fs = program; 57 current_state.fragment_shader = program;
55 } 58 }
56 59
57 void UseTrivialGeometryShader() { 60 void UseTrivialGeometryShader() {
58 gs = 0; 61 current_state.geometry_shader = 0;
59 }
60
61 void ApplyTo(OpenGLState& state) {
62 UpdatePipeline();
63 state.draw.shader_program = 0;
64 state.draw.program_pipeline = pipeline.handle;
65 } 62 }
66 63
67private: 64private:
68 void UpdatePipeline() { 65 struct PipelineState {
69 // Avoid updating the pipeline when values have no changed 66 bool operator==(const PipelineState& rhs) const {
70 if (old_vs == vs && old_fs == fs && old_gs == gs) 67 return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader &&
71 return; 68 geometry_shader == rhs.geometry_shader;
72 // Workaround for AMD bug 69 }
73 glUseProgramStages(pipeline.handle, 70
74 GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, 71 bool operator!=(const PipelineState& rhs) const {
75 0); 72 return !operator==(rhs);
76 73 }
77 glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, vs); 74
78 glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, gs); 75 GLuint vertex_shader{};
79 glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fs); 76 GLuint fragment_shader{};
80 77 GLuint geometry_shader{};
81 // Update the old values 78 };
82 old_vs = vs; 79
83 old_fs = fs; 80 void UpdatePipeline();
84 old_gs = gs;
85 }
86 81
87 OGLPipeline pipeline; 82 OGLPipeline pipeline;
88 GLuint vs{}, fs{}, gs{}; 83 PipelineState current_state;
89 GLuint old_vs{}, old_fs{}, old_gs{}; 84 PipelineState old_state;
90}; 85};
91 86
92} // namespace OpenGL::GLShader 87} // namespace OpenGL::GLShader