gl_state: Remove program tracking
This commit is contained in:
		| @@ -99,14 +99,11 @@ void oglEnablei(GLenum cap, bool state, GLuint index) { | ||||
| } // Anonymous namespace | ||||
|  | ||||
| RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | ||||
|                                    ScreenInfo& info) | ||||
|                                    ScreenInfo& info, GLShader::ProgramManager& program_manager) | ||||
|     : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device}, | ||||
|       shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system}, | ||||
|       screen_info{info}, buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} { | ||||
|     shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | ||||
|     state.draw.shader_program = 0; | ||||
|     state.Apply(); | ||||
|  | ||||
|       screen_info{info}, program_manager{program_manager}, buffer_cache{*this, system, device, | ||||
|                                                                         STREAM_BUFFER_SIZE} { | ||||
|     CheckExtensions(); | ||||
| } | ||||
|  | ||||
| @@ -228,10 +225,10 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | ||||
|         if (!gpu.regs.IsShaderConfigEnabled(index)) { | ||||
|             switch (program) { | ||||
|             case Maxwell::ShaderProgram::Geometry: | ||||
|                 shader_program_manager->UseTrivialGeometryShader(); | ||||
|                 program_manager.UseGeometryShader(0); | ||||
|                 break; | ||||
|             case Maxwell::ShaderProgram::Fragment: | ||||
|                 shader_program_manager->UseTrivialFragmentShader(); | ||||
|                 program_manager.UseFragmentShader(0); | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
| @@ -262,13 +259,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | ||||
|         switch (program) { | ||||
|         case Maxwell::ShaderProgram::VertexA: | ||||
|         case Maxwell::ShaderProgram::VertexB: | ||||
|             shader_program_manager->UseProgrammableVertexShader(program_handle); | ||||
|             program_manager.UseVertexShader(program_handle); | ||||
|             break; | ||||
|         case Maxwell::ShaderProgram::Geometry: | ||||
|             shader_program_manager->UseProgrammableGeometryShader(program_handle); | ||||
|             program_manager.UseGeometryShader(program_handle); | ||||
|             break; | ||||
|         case Maxwell::ShaderProgram::Fragment: | ||||
|             shader_program_manager->UseProgrammableFragmentShader(program_handle); | ||||
|             program_manager.UseFragmentShader(program_handle); | ||||
|             break; | ||||
|         default: | ||||
|             UNIMPLEMENTED_MSG("Unimplemented shader index={}, enable={}, offset=0x{:08X}", index, | ||||
| @@ -550,7 +547,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | ||||
|     bind_ubo_pushbuffer.Bind(); | ||||
|     bind_ssbo_pushbuffer.Bind(); | ||||
|  | ||||
|     shader_program_manager->ApplyTo(state); | ||||
|     program_manager.Update(); | ||||
|     state.Apply(); | ||||
|  | ||||
|     if (texture_cache.TextureBarrier()) { | ||||
| @@ -613,8 +610,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { | ||||
|     const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y, | ||||
|                                  launch_desc.block_dim_z, launch_desc.shared_alloc, | ||||
|                                  launch_desc.local_pos_alloc); | ||||
|     state.draw.shader_program = kernel->GetHandle(variant); | ||||
|     state.draw.program_pipeline = 0; | ||||
|     glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT, | ||||
|                        kernel->GetHandle(variant)); | ||||
|  | ||||
|     const std::size_t buffer_size = | ||||
|         Tegra::Engines::KeplerCompute::NumConstBuffers * | ||||
| @@ -632,9 +629,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { | ||||
|     bind_ubo_pushbuffer.Bind(); | ||||
|     bind_ssbo_pushbuffer.Bind(); | ||||
|  | ||||
|     state.ApplyShaderProgram(); | ||||
|     state.ApplyProgramPipeline(); | ||||
|  | ||||
|     glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); | ||||
|     ++num_queued_commands; | ||||
| } | ||||
|   | ||||
| @@ -55,7 +55,7 @@ struct DrawParameters; | ||||
| class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { | ||||
| public: | ||||
|     explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | ||||
|                               ScreenInfo& info); | ||||
|                               ScreenInfo& info, GLShader::ProgramManager& program_manager); | ||||
|     ~RasterizerOpenGL() override; | ||||
|  | ||||
|     void Draw(bool is_indexed, bool is_instanced) override; | ||||
| @@ -218,8 +218,7 @@ private: | ||||
|  | ||||
|     Core::System& system; | ||||
|     ScreenInfo& screen_info; | ||||
|  | ||||
|     std::unique_ptr<GLShader::ProgramManager> shader_program_manager; | ||||
|     GLShader::ProgramManager& program_manager; | ||||
|  | ||||
|     static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; | ||||
|     OGLBufferCache buffer_cache; | ||||
|   | ||||
| @@ -123,7 +123,6 @@ void OGLProgram::Release() { | ||||
|  | ||||
|     MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); | ||||
|     glDeleteProgram(handle); | ||||
|     OpenGLState::GetCurState().ResetProgram(handle).Apply(); | ||||
|     handle = 0; | ||||
| } | ||||
|  | ||||
| @@ -141,7 +140,6 @@ void OGLPipeline::Release() { | ||||
|  | ||||
|     MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); | ||||
|     glDeleteProgramPipelines(1, &handle); | ||||
|     OpenGLState::GetCurState().ResetPipeline(handle).Apply(); | ||||
|     handle = 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -10,27 +10,21 @@ namespace OpenGL::GLShader { | ||||
|  | ||||
| using Tegra::Engines::Maxwell3D; | ||||
|  | ||||
| ProgramManager::ProgramManager() { | ||||
| ProgramManager::~ProgramManager() = default; | ||||
|  | ||||
| void ProgramManager::Create() { | ||||
|     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() { | ||||
| void ProgramManager::Update() { | ||||
|     // 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}; | ||||
|     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); | ||||
|   | ||||
| @@ -29,25 +29,26 @@ static_assert(sizeof(MaxwellUniformData) < 16384, | ||||
|  | ||||
| class ProgramManager { | ||||
| public: | ||||
|     explicit ProgramManager(); | ||||
|     ~ProgramManager(); | ||||
|  | ||||
|     void ApplyTo(OpenGLState& state); | ||||
|     void Create(); | ||||
|  | ||||
|     void UseProgrammableVertexShader(GLuint program) { | ||||
|     void Update(); | ||||
|  | ||||
|     void UseVertexShader(GLuint program) { | ||||
|         current_state.vertex_shader = program; | ||||
|     } | ||||
|  | ||||
|     void UseProgrammableGeometryShader(GLuint program) { | ||||
|     void UseGeometryShader(GLuint program) { | ||||
|         current_state.geometry_shader = program; | ||||
|     } | ||||
|  | ||||
|     void UseProgrammableFragmentShader(GLuint program) { | ||||
|     void UseFragmentShader(GLuint program) { | ||||
|         current_state.fragment_shader = program; | ||||
|     } | ||||
|  | ||||
|     void UseTrivialGeometryShader() { | ||||
|         current_state.geometry_shader = 0; | ||||
|     GLuint GetHandle() const { | ||||
|         return pipeline.handle; | ||||
|     } | ||||
|  | ||||
|     void UseTrivialFragmentShader() { | ||||
| @@ -70,8 +71,6 @@ private: | ||||
|         GLuint geometry_shader{}; | ||||
|     }; | ||||
|  | ||||
|     void UpdatePipeline(); | ||||
|  | ||||
|     OGLPipeline pipeline; | ||||
|     PipelineState current_state; | ||||
|     PipelineState old_state; | ||||
|   | ||||
| @@ -85,36 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { | ||||
|  | ||||
| OpenGLState::OpenGLState() = default; | ||||
|  | ||||
| void OpenGLState::ApplyShaderProgram() { | ||||
|     if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { | ||||
|         glUseProgram(draw.shader_program); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void OpenGLState::ApplyProgramPipeline() { | ||||
|     if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) { | ||||
|         glBindProgramPipeline(draw.program_pipeline); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void OpenGLState::Apply() { | ||||
|     MICROPROFILE_SCOPE(OpenGL_State); | ||||
|     ApplyShaderProgram(); | ||||
|     ApplyProgramPipeline(); | ||||
| } | ||||
|  | ||||
| OpenGLState& OpenGLState::ResetProgram(GLuint handle) { | ||||
|     if (draw.shader_program == handle) { | ||||
|         draw.shader_program = 0; | ||||
|     } | ||||
|     return *this; | ||||
| } | ||||
|  | ||||
| OpenGLState& OpenGLState::ResetPipeline(GLuint handle) { | ||||
|     if (draw.program_pipeline == handle) { | ||||
|         draw.program_pipeline = 0; | ||||
|     } | ||||
|     return *this; | ||||
| } | ||||
| void OpenGLState::Apply() {} | ||||
|  | ||||
| } // namespace OpenGL | ||||
|   | ||||
| @@ -13,11 +13,6 @@ namespace OpenGL { | ||||
|  | ||||
| class OpenGLState { | ||||
| public: | ||||
|     struct { | ||||
|         GLuint shader_program = 0;   // GL_CURRENT_PROGRAM | ||||
|         GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING | ||||
|     } draw; | ||||
|  | ||||
|     OpenGLState(); | ||||
|  | ||||
|     /// Get the currently active OpenGL state | ||||
| @@ -28,13 +23,6 @@ public: | ||||
|     /// Apply this state as the current OpenGL state | ||||
|     void Apply(); | ||||
|  | ||||
|     void ApplyShaderProgram(); | ||||
|     void ApplyProgramPipeline(); | ||||
|  | ||||
|     /// Resets any references to the given resource | ||||
|     OpenGLState& ResetProgram(GLuint handle); | ||||
|     OpenGLState& ResetPipeline(GLuint handle); | ||||
|  | ||||
| private: | ||||
|     static OpenGLState cur_state; | ||||
| }; | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
| #include "core/telemetry_session.h" | ||||
| #include "video_core/morton.h" | ||||
| #include "video_core/renderer_opengl/gl_rasterizer.h" | ||||
| #include "video_core/renderer_opengl/gl_shader_manager.h" | ||||
| #include "video_core/renderer_opengl/renderer_opengl.h" | ||||
|  | ||||
| namespace OpenGL { | ||||
| @@ -158,9 +159,13 @@ public: | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| constexpr char vertex_shader[] = R"( | ||||
| constexpr char VERTEX_SHADER[] = R"( | ||||
| #version 430 core | ||||
|  | ||||
| out gl_PerVertex { | ||||
|     vec4 gl_Position; | ||||
| }; | ||||
|  | ||||
| layout (location = 0) in vec2 vert_position; | ||||
| layout (location = 1) in vec2 vert_tex_coord; | ||||
| layout (location = 0) out vec2 frag_tex_coord; | ||||
| @@ -181,7 +186,7 @@ void main() { | ||||
| } | ||||
| )"; | ||||
|  | ||||
| constexpr char fragment_shader[] = R"( | ||||
| constexpr char FRAGMENT_SHADER[] = R"( | ||||
| #version 430 core | ||||
|  | ||||
| layout (location = 0) in vec2 frag_tex_coord; | ||||
| @@ -426,10 +431,19 @@ void RendererOpenGL::InitOpenGLObjects() { | ||||
|     glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, | ||||
|                  0.0f); | ||||
|  | ||||
|     // Link shaders and get variable locations | ||||
|     shader.CreateFromSource(vertex_shader, nullptr, fragment_shader); | ||||
|     state.draw.shader_program = shader.handle; | ||||
|     state.Apply(); | ||||
|     // Create shader programs | ||||
|     OGLShader vertex_shader; | ||||
|     vertex_shader.Create(VERTEX_SHADER, GL_VERTEX_SHADER); | ||||
|  | ||||
|     OGLShader fragment_shader; | ||||
|     fragment_shader.Create(FRAGMENT_SHADER, GL_FRAGMENT_SHADER); | ||||
|  | ||||
|     vertex_program.Create(true, false, vertex_shader.handle); | ||||
|     fragment_program.Create(true, false, fragment_shader.handle); | ||||
|  | ||||
|     // Create program pipeline | ||||
|     program_manager.Create(); | ||||
|     glBindProgramPipeline(program_manager.GetHandle()); | ||||
|  | ||||
|     // Generate VBO handle for drawing | ||||
|     vertex_buffer.Create(); | ||||
| @@ -468,7 +482,8 @@ void RendererOpenGL::CreateRasterizer() { | ||||
|     if (rasterizer) { | ||||
|         return; | ||||
|     } | ||||
|     rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info); | ||||
|     rasterizer = | ||||
|         std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info, program_manager); | ||||
| } | ||||
|  | ||||
| void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | ||||
| @@ -517,7 +532,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | ||||
|     // Set projection matrix | ||||
|     const std::array ortho_matrix = | ||||
|         MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); | ||||
|     glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data()); | ||||
|     glProgramUniformMatrix3x2fv(vertex_program.handle, ModelViewMatrixLocation, 1, GL_FALSE, | ||||
|                                 std::data(ortho_matrix)); | ||||
|  | ||||
|     const auto& texcoords = screen_info.display_texcoords; | ||||
|     auto left = texcoords.left; | ||||
| @@ -562,6 +578,11 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | ||||
|     state.Apply(); | ||||
|  | ||||
|     // TODO: Signal state tracker about these changes | ||||
|     program_manager.UseVertexShader(vertex_program.handle); | ||||
|     program_manager.UseGeometryShader(0); | ||||
|     program_manager.UseFragmentShader(fragment_program.handle); | ||||
|     program_manager.Update(); | ||||
|  | ||||
|     glEnable(GL_CULL_FACE); | ||||
|     if (screen_info.display_srgb) { | ||||
|         glEnable(GL_FRAMEBUFFER_SRGB); | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| #include "common/math_util.h" | ||||
| #include "video_core/renderer_base.h" | ||||
| #include "video_core/renderer_opengl/gl_resource_manager.h" | ||||
| #include "video_core/renderer_opengl/gl_shader_manager.h" | ||||
| #include "video_core/renderer_opengl/gl_state.h" | ||||
|  | ||||
| namespace Core { | ||||
| @@ -95,12 +96,16 @@ private: | ||||
|  | ||||
|     // OpenGL object IDs | ||||
|     OGLBuffer vertex_buffer; | ||||
|     OGLProgram shader; | ||||
|     OGLProgram vertex_program; | ||||
|     OGLProgram fragment_program; | ||||
|     OGLFramebuffer screenshot_framebuffer; | ||||
|  | ||||
|     /// Display information for Switch screen | ||||
|     ScreenInfo screen_info; | ||||
|  | ||||
|     /// Global dummy shader pipeline | ||||
|     GLShader::ProgramManager program_manager; | ||||
|  | ||||
|     /// OpenGL framebuffer data | ||||
|     std::vector<u8> gl_framebuffer_data; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user