From 835790809954bb5962f8893320b8f5c3ad82d6a0 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 11 Mar 2020 01:03:01 -0300 Subject: 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. --- .../renderer_opengl/gl_shader_manager.cpp | 31 +++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_shader_manager.cpp') 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 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include + #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() = default; ProgramManager::~ProgramManager() = default; void ProgramManager::Create() { - pipeline.Create(); + graphics_pipeline.Create(); + glBindProgramPipeline(graphics_pipeline.handle); } -void ProgramManager::Update() { +void ProgramManager::BindGraphicsPipeline() { + if (!is_graphics_bound) { + is_graphics_bound = true; + glUseProgram(0); + } + // Avoid updating the pipeline when values have no changed if (old_state == current_state) { return; @@ -25,16 +33,21 @@ void ProgramManager::Update() { // Workaround for AMD bug static 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); + const GLuint handle = graphics_pipeline.handle; + glUseProgramStages(handle, all_used_stages, 0); + glUseProgramStages(handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader); + glUseProgramStages(handle, GL_GEOMETRY_SHADER_BIT, current_state.geometry_shader); + glUseProgramStages(handle, GL_FRAGMENT_SHADER_BIT, current_state.fragment_shader); old_state = current_state; } -void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell) { +void ProgramManager::BindComputeShader(GLuint program) { + is_graphics_bound = false; + glUseProgram(program); +} + +void MaxwellUniformData::SetFromRegs(const Tegra::Engines::Maxwell3D& maxwell) { const auto& regs = maxwell.regs; // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value. -- cgit v1.2.3