summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp28
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h5
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp16
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h17
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp32
-rw-r--r--src/video_core/renderer_opengl/gl_state.h12
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp37
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h7
9 files changed, 62 insertions, 94 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index b826146fb..84c4d110c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -99,14 +99,11 @@ void oglEnablei(GLenum cap, bool state, GLuint index) {
99} // Anonymous namespace 99} // Anonymous namespace
100 100
101RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 101RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
102 ScreenInfo& info) 102 ScreenInfo& info, GLShader::ProgramManager& program_manager)
103 : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device}, 103 : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device},
104 shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system}, 104 shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system},
105 screen_info{info}, buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} { 105 screen_info{info}, program_manager{program_manager}, buffer_cache{*this, system, device,
106 shader_program_manager = std::make_unique<GLShader::ProgramManager>(); 106 STREAM_BUFFER_SIZE} {
107 state.draw.shader_program = 0;
108 state.Apply();
109
110 CheckExtensions(); 107 CheckExtensions();
111} 108}
112 109
@@ -228,10 +225,10 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
228 if (!gpu.regs.IsShaderConfigEnabled(index)) { 225 if (!gpu.regs.IsShaderConfigEnabled(index)) {
229 switch (program) { 226 switch (program) {
230 case Maxwell::ShaderProgram::Geometry: 227 case Maxwell::ShaderProgram::Geometry:
231 shader_program_manager->UseTrivialGeometryShader(); 228 program_manager.UseGeometryShader(0);
232 break; 229 break;
233 case Maxwell::ShaderProgram::Fragment: 230 case Maxwell::ShaderProgram::Fragment:
234 shader_program_manager->UseTrivialFragmentShader(); 231 program_manager.UseFragmentShader(0);
235 break; 232 break;
236 default: 233 default:
237 break; 234 break;
@@ -262,13 +259,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
262 switch (program) { 259 switch (program) {
263 case Maxwell::ShaderProgram::VertexA: 260 case Maxwell::ShaderProgram::VertexA:
264 case Maxwell::ShaderProgram::VertexB: 261 case Maxwell::ShaderProgram::VertexB:
265 shader_program_manager->UseProgrammableVertexShader(program_handle); 262 program_manager.UseVertexShader(program_handle);
266 break; 263 break;
267 case Maxwell::ShaderProgram::Geometry: 264 case Maxwell::ShaderProgram::Geometry:
268 shader_program_manager->UseProgrammableGeometryShader(program_handle); 265 program_manager.UseGeometryShader(program_handle);
269 break; 266 break;
270 case Maxwell::ShaderProgram::Fragment: 267 case Maxwell::ShaderProgram::Fragment:
271 shader_program_manager->UseProgrammableFragmentShader(program_handle); 268 program_manager.UseFragmentShader(program_handle);
272 break; 269 break;
273 default: 270 default:
274 UNIMPLEMENTED_MSG("Unimplemented shader index={}, enable={}, offset=0x{:08X}", index, 271 UNIMPLEMENTED_MSG("Unimplemented shader index={}, enable={}, offset=0x{:08X}", index,
@@ -550,7 +547,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
550 bind_ubo_pushbuffer.Bind(); 547 bind_ubo_pushbuffer.Bind();
551 bind_ssbo_pushbuffer.Bind(); 548 bind_ssbo_pushbuffer.Bind();
552 549
553 shader_program_manager->ApplyTo(state); 550 program_manager.Update();
554 state.Apply(); 551 state.Apply();
555 552
556 if (texture_cache.TextureBarrier()) { 553 if (texture_cache.TextureBarrier()) {
@@ -613,8 +610,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
613 const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y, 610 const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y,
614 launch_desc.block_dim_z, launch_desc.shared_alloc, 611 launch_desc.block_dim_z, launch_desc.shared_alloc,
615 launch_desc.local_pos_alloc); 612 launch_desc.local_pos_alloc);
616 state.draw.shader_program = kernel->GetHandle(variant); 613 glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT,
617 state.draw.program_pipeline = 0; 614 kernel->GetHandle(variant));
618 615
619 const std::size_t buffer_size = 616 const std::size_t buffer_size =
620 Tegra::Engines::KeplerCompute::NumConstBuffers * 617 Tegra::Engines::KeplerCompute::NumConstBuffers *
@@ -632,9 +629,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
632 bind_ubo_pushbuffer.Bind(); 629 bind_ubo_pushbuffer.Bind();
633 bind_ssbo_pushbuffer.Bind(); 630 bind_ssbo_pushbuffer.Bind();
634 631
635 state.ApplyShaderProgram();
636 state.ApplyProgramPipeline();
637
638 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); 632 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
639 ++num_queued_commands; 633 ++num_queued_commands;
640} 634}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index de21a3511..b8158c152 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -55,7 +55,7 @@ struct DrawParameters;
55class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { 55class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
56public: 56public:
57 explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 57 explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
58 ScreenInfo& info); 58 ScreenInfo& info, GLShader::ProgramManager& program_manager);
59 ~RasterizerOpenGL() override; 59 ~RasterizerOpenGL() override;
60 60
61 void Draw(bool is_indexed, bool is_instanced) override; 61 void Draw(bool is_indexed, bool is_instanced) override;
@@ -218,8 +218,7 @@ private:
218 218
219 Core::System& system; 219 Core::System& system;
220 ScreenInfo& screen_info; 220 ScreenInfo& screen_info;
221 221 GLShader::ProgramManager& program_manager;
222 std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
223 222
224 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 223 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
225 OGLBufferCache buffer_cache; 224 OGLBufferCache buffer_cache;
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
index 21ea6fde4..404fd6556 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -123,7 +123,6 @@ void OGLProgram::Release() {
123 123
124 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); 124 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
125 glDeleteProgram(handle); 125 glDeleteProgram(handle);
126 OpenGLState::GetCurState().ResetProgram(handle).Apply();
127 handle = 0; 126 handle = 0;
128} 127}
129 128
@@ -141,7 +140,6 @@ void OGLPipeline::Release() {
141 140
142 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); 141 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
143 glDeleteProgramPipelines(1, &handle); 142 glDeleteProgramPipelines(1, &handle);
144 OpenGLState::GetCurState().ResetPipeline(handle).Apply();
145 handle = 0; 143 handle = 0;
146} 144}
147 145
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 75d3fac04..15f3cd066 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -10,27 +10,21 @@ namespace OpenGL::GLShader {
10 10
11using Tegra::Engines::Maxwell3D; 11using Tegra::Engines::Maxwell3D;
12 12
13ProgramManager::ProgramManager() {
14 pipeline.Create();
15}
16
17ProgramManager::~ProgramManager() = default; 13ProgramManager::~ProgramManager() = default;
18 14
19void ProgramManager::ApplyTo(OpenGLState& state) { 15void ProgramManager::Create() {
20 UpdatePipeline(); 16 pipeline.Create();
21 state.draw.shader_program = 0;
22 state.draw.program_pipeline = pipeline.handle;
23} 17}
24 18
25void ProgramManager::UpdatePipeline() { 19void ProgramManager::Update() {
26 // Avoid updating the pipeline when values have no changed 20 // Avoid updating the pipeline when values have no changed
27 if (old_state == current_state) { 21 if (old_state == current_state) {
28 return; 22 return;
29 } 23 }
30 24
31 // Workaround for AMD bug 25 // Workaround for AMD bug
32 constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | 26 static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
33 GL_FRAGMENT_SHADER_BIT}; 27 GL_FRAGMENT_SHADER_BIT};
34 glUseProgramStages(pipeline.handle, all_used_stages, 0); 28 glUseProgramStages(pipeline.handle, all_used_stages, 0);
35 29
36 glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader); 30 glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 478c165ce..db23a27e8 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -29,25 +29,26 @@ static_assert(sizeof(MaxwellUniformData) < 16384,
29 29
30class ProgramManager { 30class ProgramManager {
31public: 31public:
32 explicit ProgramManager();
33 ~ProgramManager(); 32 ~ProgramManager();
34 33
35 void ApplyTo(OpenGLState& state); 34 void Create();
36 35
37 void UseProgrammableVertexShader(GLuint program) { 36 void Update();
37
38 void UseVertexShader(GLuint program) {
38 current_state.vertex_shader = program; 39 current_state.vertex_shader = program;
39 } 40 }
40 41
41 void UseProgrammableGeometryShader(GLuint program) { 42 void UseGeometryShader(GLuint program) {
42 current_state.geometry_shader = program; 43 current_state.geometry_shader = program;
43 } 44 }
44 45
45 void UseProgrammableFragmentShader(GLuint program) { 46 void UseFragmentShader(GLuint program) {
46 current_state.fragment_shader = program; 47 current_state.fragment_shader = program;
47 } 48 }
48 49
49 void UseTrivialGeometryShader() { 50 GLuint GetHandle() const {
50 current_state.geometry_shader = 0; 51 return pipeline.handle;
51 } 52 }
52 53
53 void UseTrivialFragmentShader() { 54 void UseTrivialFragmentShader() {
@@ -70,8 +71,6 @@ private:
70 GLuint geometry_shader{}; 71 GLuint geometry_shader{};
71 }; 72 };
72 73
73 void UpdatePipeline();
74
75 OGLPipeline pipeline; 74 OGLPipeline pipeline;
76 PipelineState current_state; 75 PipelineState current_state;
77 PipelineState old_state; 76 PipelineState old_state;
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index be4ca6bf0..e8a23d41d 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -85,36 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
85 85
86OpenGLState::OpenGLState() = default; 86OpenGLState::OpenGLState() = default;
87 87
88void OpenGLState::ApplyShaderProgram() { 88void OpenGLState::Apply() {}
89 if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
90 glUseProgram(draw.shader_program);
91 }
92}
93
94void OpenGLState::ApplyProgramPipeline() {
95 if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) {
96 glBindProgramPipeline(draw.program_pipeline);
97 }
98}
99
100void OpenGLState::Apply() {
101 MICROPROFILE_SCOPE(OpenGL_State);
102 ApplyShaderProgram();
103 ApplyProgramPipeline();
104}
105
106OpenGLState& OpenGLState::ResetProgram(GLuint handle) {
107 if (draw.shader_program == handle) {
108 draw.shader_program = 0;
109 }
110 return *this;
111}
112
113OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
114 if (draw.program_pipeline == handle) {
115 draw.program_pipeline = 0;
116 }
117 return *this;
118}
119 89
120} // namespace OpenGL 90} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index c9a839736..f62e2e2e1 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -13,11 +13,6 @@ namespace OpenGL {
13 13
14class OpenGLState { 14class OpenGLState {
15public: 15public:
16 struct {
17 GLuint shader_program = 0; // GL_CURRENT_PROGRAM
18 GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
19 } draw;
20
21 OpenGLState(); 16 OpenGLState();
22 17
23 /// Get the currently active OpenGL state 18 /// Get the currently active OpenGL state
@@ -28,13 +23,6 @@ public:
28 /// Apply this state as the current OpenGL state 23 /// Apply this state as the current OpenGL state
29 void Apply(); 24 void Apply();
30 25
31 void ApplyShaderProgram();
32 void ApplyProgramPipeline();
33
34 /// Resets any references to the given resource
35 OpenGLState& ResetProgram(GLuint handle);
36 OpenGLState& ResetPipeline(GLuint handle);
37
38private: 26private:
39 static OpenGLState cur_state; 27 static OpenGLState cur_state;
40}; 28};
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index da4b4bf34..ace3aec88 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -20,6 +20,7 @@
20#include "core/telemetry_session.h" 20#include "core/telemetry_session.h"
21#include "video_core/morton.h" 21#include "video_core/morton.h"
22#include "video_core/renderer_opengl/gl_rasterizer.h" 22#include "video_core/renderer_opengl/gl_rasterizer.h"
23#include "video_core/renderer_opengl/gl_shader_manager.h"
23#include "video_core/renderer_opengl/renderer_opengl.h" 24#include "video_core/renderer_opengl/renderer_opengl.h"
24 25
25namespace OpenGL { 26namespace OpenGL {
@@ -158,9 +159,13 @@ public:
158 159
159namespace { 160namespace {
160 161
161constexpr char vertex_shader[] = R"( 162constexpr char VERTEX_SHADER[] = R"(
162#version 430 core 163#version 430 core
163 164
165out gl_PerVertex {
166 vec4 gl_Position;
167};
168
164layout (location = 0) in vec2 vert_position; 169layout (location = 0) in vec2 vert_position;
165layout (location = 1) in vec2 vert_tex_coord; 170layout (location = 1) in vec2 vert_tex_coord;
166layout (location = 0) out vec2 frag_tex_coord; 171layout (location = 0) out vec2 frag_tex_coord;
@@ -181,7 +186,7 @@ void main() {
181} 186}
182)"; 187)";
183 188
184constexpr char fragment_shader[] = R"( 189constexpr char FRAGMENT_SHADER[] = R"(
185#version 430 core 190#version 430 core
186 191
187layout (location = 0) in vec2 frag_tex_coord; 192layout (location = 0) in vec2 frag_tex_coord;
@@ -426,10 +431,19 @@ void RendererOpenGL::InitOpenGLObjects() {
426 glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, 431 glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
427 0.0f); 432 0.0f);
428 433
429 // Link shaders and get variable locations 434 // Create shader programs
430 shader.CreateFromSource(vertex_shader, nullptr, fragment_shader); 435 OGLShader vertex_shader;
431 state.draw.shader_program = shader.handle; 436 vertex_shader.Create(VERTEX_SHADER, GL_VERTEX_SHADER);
432 state.Apply(); 437
438 OGLShader fragment_shader;
439 fragment_shader.Create(FRAGMENT_SHADER, GL_FRAGMENT_SHADER);
440
441 vertex_program.Create(true, false, vertex_shader.handle);
442 fragment_program.Create(true, false, fragment_shader.handle);
443
444 // Create program pipeline
445 program_manager.Create();
446 glBindProgramPipeline(program_manager.GetHandle());
433 447
434 // Generate VBO handle for drawing 448 // Generate VBO handle for drawing
435 vertex_buffer.Create(); 449 vertex_buffer.Create();
@@ -468,7 +482,8 @@ void RendererOpenGL::CreateRasterizer() {
468 if (rasterizer) { 482 if (rasterizer) {
469 return; 483 return;
470 } 484 }
471 rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info); 485 rasterizer =
486 std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info, program_manager);
472} 487}
473 488
474void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, 489void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
@@ -517,7 +532,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
517 // Set projection matrix 532 // Set projection matrix
518 const std::array ortho_matrix = 533 const std::array ortho_matrix =
519 MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); 534 MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
520 glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data()); 535 glProgramUniformMatrix3x2fv(vertex_program.handle, ModelViewMatrixLocation, 1, GL_FALSE,
536 std::data(ortho_matrix));
521 537
522 const auto& texcoords = screen_info.display_texcoords; 538 const auto& texcoords = screen_info.display_texcoords;
523 auto left = texcoords.left; 539 auto left = texcoords.left;
@@ -562,6 +578,11 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
562 state.Apply(); 578 state.Apply();
563 579
564 // TODO: Signal state tracker about these changes 580 // TODO: Signal state tracker about these changes
581 program_manager.UseVertexShader(vertex_program.handle);
582 program_manager.UseGeometryShader(0);
583 program_manager.UseFragmentShader(fragment_program.handle);
584 program_manager.Update();
585
565 glEnable(GL_CULL_FACE); 586 glEnable(GL_CULL_FACE);
566 if (screen_info.display_srgb) { 587 if (screen_info.display_srgb) {
567 glEnable(GL_FRAMEBUFFER_SRGB); 588 glEnable(GL_FRAMEBUFFER_SRGB);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 42a2141d8..f1225269f 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -10,6 +10,7 @@
10#include "common/math_util.h" 10#include "common/math_util.h"
11#include "video_core/renderer_base.h" 11#include "video_core/renderer_base.h"
12#include "video_core/renderer_opengl/gl_resource_manager.h" 12#include "video_core/renderer_opengl/gl_resource_manager.h"
13#include "video_core/renderer_opengl/gl_shader_manager.h"
13#include "video_core/renderer_opengl/gl_state.h" 14#include "video_core/renderer_opengl/gl_state.h"
14 15
15namespace Core { 16namespace Core {
@@ -95,12 +96,16 @@ private:
95 96
96 // OpenGL object IDs 97 // OpenGL object IDs
97 OGLBuffer vertex_buffer; 98 OGLBuffer vertex_buffer;
98 OGLProgram shader; 99 OGLProgram vertex_program;
100 OGLProgram fragment_program;
99 OGLFramebuffer screenshot_framebuffer; 101 OGLFramebuffer screenshot_framebuffer;
100 102
101 /// Display information for Switch screen 103 /// Display information for Switch screen
102 ScreenInfo screen_info; 104 ScreenInfo screen_info;
103 105
106 /// Global dummy shader pipeline
107 GLShader::ProgramManager program_manager;
108
104 /// OpenGL framebuffer data 109 /// OpenGL framebuffer data
105 std::vector<u8> gl_framebuffer_data; 110 std::vector<u8> gl_framebuffer_data;
106 111