summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-03-11 01:03:01 -0300
committerGravatar ReinUsesLisp2020-03-11 01:04:52 -0300
commit835790809954bb5962f8893320b8f5c3ad82d6a0 (patch)
tree30e258936c1282f31143f465f1c310563dd9acfa
parentMerge pull request #3301 from ReinUsesLisp/state-tracker (diff)
downloadyuzu-835790809954bb5962f8893320b8f5c3ad82d6a0.tar.gz
yuzu-835790809954bb5962f8893320b8f5c3ad82d6a0.tar.xz
yuzu-835790809954bb5962f8893320b8f5c3ad82d6a0.zip
gl_shader_manager: Fix interaction between graphics and compute
After a compute shader was set to the pipeline, no graphics shader was invoked again. To address this use glUseProgram to bind compute shaders (without state tracking) and call glUseProgram(0) when transitioning out of it back to the graphics pipeline.
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp31
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h29
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp3
4 files changed, 39 insertions, 29 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 55324e6d5..4e4138573 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -565,7 +565,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
565 bind_ubo_pushbuffer.Bind(); 565 bind_ubo_pushbuffer.Bind();
566 bind_ssbo_pushbuffer.Bind(); 566 bind_ssbo_pushbuffer.Bind();
567 567
568 program_manager.Update(); 568 program_manager.BindGraphicsPipeline();
569 569
570 if (texture_cache.TextureBarrier()) { 570 if (texture_cache.TextureBarrier()) {
571 glTextureBarrier(); 571 glTextureBarrier();
@@ -627,8 +627,7 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
627 const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y, 627 const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y,
628 launch_desc.block_dim_z, launch_desc.shared_alloc, 628 launch_desc.block_dim_z, launch_desc.shared_alloc,
629 launch_desc.local_pos_alloc); 629 launch_desc.local_pos_alloc);
630 glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT, 630 program_manager.BindComputeShader(kernel->GetHandle(variant));
631 kernel->GetHandle(variant));
632 631
633 const std::size_t buffer_size = 632 const std::size_t buffer_size =
634 Tegra::Engines::KeplerCompute::NumConstBuffers * 633 Tegra::Engines::KeplerCompute::NumConstBuffers *
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 15f3cd066..9c7b0adbd 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -2,21 +2,29 @@
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 <glad/glad.h>
6
5#include "common/common_types.h" 7#include "common/common_types.h"
6#include "video_core/engines/maxwell_3d.h" 8#include "video_core/engines/maxwell_3d.h"
7#include "video_core/renderer_opengl/gl_shader_manager.h" 9#include "video_core/renderer_opengl/gl_shader_manager.h"
8 10
9namespace OpenGL::GLShader { 11namespace OpenGL::GLShader {
10 12
11using Tegra::Engines::Maxwell3D; 13ProgramManager::ProgramManager() = default;
12 14
13ProgramManager::~ProgramManager() = default; 15ProgramManager::~ProgramManager() = default;
14 16
15void ProgramManager::Create() { 17void ProgramManager::Create() {
16 pipeline.Create(); 18 graphics_pipeline.Create();
19 glBindProgramPipeline(graphics_pipeline.handle);
17} 20}
18 21
19void ProgramManager::Update() { 22void ProgramManager::BindGraphicsPipeline() {
23 if (!is_graphics_bound) {
24 is_graphics_bound = true;
25 glUseProgram(0);
26 }
27
20 // Avoid updating the pipeline when values have no changed 28 // Avoid updating the pipeline when values have no changed
21 if (old_state == current_state) { 29 if (old_state == current_state) {
22 return; 30 return;
@@ -25,16 +33,21 @@ void ProgramManager::Update() {
25 // Workaround for AMD bug 33 // Workaround for AMD bug
26 static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | 34 static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
27 GL_FRAGMENT_SHADER_BIT}; 35 GL_FRAGMENT_SHADER_BIT};
28 glUseProgramStages(pipeline.handle, all_used_stages, 0); 36 const GLuint handle = graphics_pipeline.handle;
29 37 glUseProgramStages(handle, all_used_stages, 0);
30 glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader); 38 glUseProgramStages(handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
31 glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader); 39 glUseProgramStages(handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader);
32 glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader); 40 glUseProgramStages(handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader);
33 41
34 old_state = current_state; 42 old_state = current_state;
35} 43}
36 44
37void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell) { 45void ProgramManager::BindComputeShader(GLuint program) {
46 is_graphics_bound = false;
47 glUseProgram(program);
48}
49
50void MaxwellUniformData::SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell) {
38 const auto& regs = maxwell.regs; 51 const auto& regs = maxwell.regs;
39 52
40 // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value. 53 // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value.
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index e94cd75aa..d2e47f2a9 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -28,11 +28,16 @@ static_assert(sizeof(MaxwellUniformData) < 16384,
28 28
29class ProgramManager { 29class ProgramManager {
30public: 30public:
31 explicit ProgramManager();
31 ~ProgramManager(); 32 ~ProgramManager();
32 33
33 void Create(); 34 void Create();
34 35
35 void Update(); 36 /// Updates the graphics pipeline and binds it.
37 void BindGraphicsPipeline();
38
39 /// Binds a compute shader.
40 void BindComputeShader(GLuint program);
36 41
37 void UseVertexShader(GLuint program) { 42 void UseVertexShader(GLuint program) {
38 current_state.vertex_shader = program; 43 current_state.vertex_shader = program;
@@ -46,33 +51,27 @@ public:
46 current_state.fragment_shader = program; 51 current_state.fragment_shader = program;
47 } 52 }
48 53
49 GLuint GetHandle() const {
50 return pipeline.handle;
51 }
52
53 void UseTrivialFragmentShader() {
54 current_state.fragment_shader = 0;
55 }
56
57private: 54private:
58 struct PipelineState { 55 struct PipelineState {
59 bool operator==(const PipelineState& rhs) const { 56 bool operator==(const PipelineState& rhs) const noexcept {
60 return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader && 57 return vertex_shader == rhs.vertex_shader && fragment_shader == rhs.fragment_shader &&
61 geometry_shader == rhs.geometry_shader; 58 geometry_shader == rhs.geometry_shader;
62 } 59 }
63 60
64 bool operator!=(const PipelineState& rhs) const { 61 bool operator!=(const PipelineState& rhs) const noexcept {
65 return !operator==(rhs); 62 return !operator==(rhs);
66 } 63 }
67 64
68 GLuint vertex_shader{}; 65 GLuint vertex_shader = 0;
69 GLuint fragment_shader{}; 66 GLuint fragment_shader = 0;
70 GLuint geometry_shader{}; 67 GLuint geometry_shader = 0;
71 }; 68 };
72 69
73 OGLPipeline pipeline; 70 OGLPipeline graphics_pipeline;
71 OGLPipeline compute_pipeline;
74 PipelineState current_state; 72 PipelineState current_state;
75 PipelineState old_state; 73 PipelineState old_state;
74 bool is_graphics_bound = true;
76}; 75};
77 76
78} // namespace OpenGL::GLShader 77} // namespace OpenGL::GLShader
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index a51410660..c05677cd9 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -443,7 +443,6 @@ void RendererOpenGL::InitOpenGLObjects() {
443 443
444 // Create program pipeline 444 // Create program pipeline
445 program_manager.Create(); 445 program_manager.Create();
446 glBindProgramPipeline(program_manager.GetHandle());
447 446
448 // Generate VBO handle for drawing 447 // Generate VBO handle for drawing
449 vertex_buffer.Create(); 448 vertex_buffer.Create();
@@ -596,7 +595,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
596 program_manager.UseVertexShader(vertex_program.handle); 595 program_manager.UseVertexShader(vertex_program.handle);
597 program_manager.UseGeometryShader(0); 596 program_manager.UseGeometryShader(0);
598 program_manager.UseFragmentShader(fragment_program.handle); 597 program_manager.UseFragmentShader(fragment_program.handle);
599 program_manager.Update(); 598 program_manager.BindGraphicsPipeline();
600 599
601 glEnable(GL_CULL_FACE); 600 glEnable(GL_CULL_FACE);
602 if (screen_info.display_srgb) { 601 if (screen_info.display_srgb) {