diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_program.cpp | 27 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_program.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.h | 51 |
3 files changed, 56 insertions, 23 deletions
diff --git a/src/video_core/renderer_opengl/gl_graphics_program.cpp b/src/video_core/renderer_opengl/gl_graphics_program.cpp index 4ac026502..b5d75aa13 100644 --- a/src/video_core/renderer_opengl/gl_graphics_program.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_program.cpp | |||
| @@ -42,6 +42,9 @@ GraphicsProgram::GraphicsProgram(TextureCache& texture_cache_, BufferCache& buff | |||
| 42 | std::ranges::transform(infos, stage_infos.begin(), | 42 | std::ranges::transform(infos, stage_infos.begin(), |
| 43 | [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); | 43 | [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); |
| 44 | 44 | ||
| 45 | for (size_t stage = 0; stage < 5; ++stage) { | ||
| 46 | enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage; | ||
| 47 | } | ||
| 45 | u32 num_textures{}; | 48 | u32 num_textures{}; |
| 46 | u32 num_images{}; | 49 | u32 num_images{}; |
| 47 | for (size_t stage = 0; stage < base_uniform_bindings.size() - 1; ++stage) { | 50 | for (size_t stage = 0; stage < base_uniform_bindings.size() - 1; ++stage) { |
| @@ -182,6 +185,9 @@ void GraphicsProgram::Configure(bool is_indexed) { | |||
| 182 | const std::span indices_span(image_view_indices.data(), image_view_index); | 185 | const std::span indices_span(image_view_indices.data(), image_view_index); |
| 183 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | 186 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); |
| 184 | 187 | ||
| 188 | texture_cache.UpdateRenderTargets(false); | ||
| 189 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); | ||
| 190 | |||
| 185 | ImageId* texture_buffer_index{image_view_ids.data()}; | 191 | ImageId* texture_buffer_index{image_view_ids.data()}; |
| 186 | const auto bind_stage_info{[&](size_t stage) { | 192 | const auto bind_stage_info{[&](size_t stage) { |
| 187 | size_t index{}; | 193 | size_t index{}; |
| @@ -240,14 +246,8 @@ void GraphicsProgram::Configure(bool is_indexed) { | |||
| 240 | buffer_cache.UpdateGraphicsBuffers(is_indexed); | 246 | buffer_cache.UpdateGraphicsBuffers(is_indexed); |
| 241 | buffer_cache.BindHostGeometryBuffers(is_indexed); | 247 | buffer_cache.BindHostGeometryBuffers(is_indexed); |
| 242 | 248 | ||
| 243 | // FIXME: Unhack this | ||
| 244 | if (assembly_programs[0].handle != 0) { | 249 | if (assembly_programs[0].handle != 0) { |
| 245 | // TODO: State track this | 250 | program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); |
| 246 | glEnable(GL_VERTEX_PROGRAM_NV); | ||
| 247 | glEnable(GL_FRAGMENT_PROGRAM_NV); | ||
| 248 | glBindProgramARB(GL_VERTEX_PROGRAM_NV, assembly_programs[0].handle); | ||
| 249 | glBindProgramARB(GL_FRAGMENT_PROGRAM_NV, assembly_programs[4].handle); | ||
| 250 | program_manager.BindProgram(0); | ||
| 251 | } else { | 251 | } else { |
| 252 | program_manager.BindProgram(program.handle); | 252 | program_manager.BindProgram(program.handle); |
| 253 | } | 253 | } |
| @@ -300,19 +300,6 @@ void GraphicsProgram::Configure(bool is_indexed) { | |||
| 300 | if (image_binding != 0) { | 300 | if (image_binding != 0) { |
| 301 | glBindImageTextures(0, image_binding, images.data()); | 301 | glBindImageTextures(0, image_binding, images.data()); |
| 302 | } | 302 | } |
| 303 | texture_cache.UpdateRenderTargets(false); | ||
| 304 | |||
| 305 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); | ||
| 306 | if (assembly_programs[0].handle != 0) { | ||
| 307 | // TODO: State track this | ||
| 308 | glEnable(GL_VERTEX_PROGRAM_NV); | ||
| 309 | glEnable(GL_FRAGMENT_PROGRAM_NV); | ||
| 310 | glBindProgramARB(GL_VERTEX_PROGRAM_NV, assembly_programs[0].handle); | ||
| 311 | glBindProgramARB(GL_FRAGMENT_PROGRAM_NV, assembly_programs[4].handle); | ||
| 312 | program_manager.BindProgram(0); | ||
| 313 | } else { | ||
| 314 | program_manager.BindProgram(program.handle); | ||
| 315 | } | ||
| 316 | } | 303 | } |
| 317 | 304 | ||
| 318 | } // namespace OpenGL | 305 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_graphics_program.h b/src/video_core/renderer_opengl/gl_graphics_program.h index 58aa4b0bc..18292bb16 100644 --- a/src/video_core/renderer_opengl/gl_graphics_program.h +++ b/src/video_core/renderer_opengl/gl_graphics_program.h | |||
| @@ -89,6 +89,7 @@ private: | |||
| 89 | 89 | ||
| 90 | OGLProgram program; | 90 | OGLProgram program; |
| 91 | std::array<OGLAssemblyProgram, 5> assembly_programs; | 91 | std::array<OGLAssemblyProgram, 5> assembly_programs; |
| 92 | u32 enabled_stages_mask{}; | ||
| 92 | 93 | ||
| 93 | std::array<Shader::Info, 5> stage_infos{}; | 94 | std::array<Shader::Info, 5> stage_infos{}; |
| 94 | std::array<u32, 5> base_uniform_bindings{}; | 95 | std::array<u32, 5> base_uniform_bindings{}; |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 70781d6f5..48669b3cd 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -4,24 +4,69 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 8 | #include <span> | ||
| 9 | |||
| 7 | #include <glad/glad.h> | 10 | #include <glad/glad.h> |
| 8 | 11 | ||
| 12 | #include "video_core/renderer_opengl/gl_resource_manager.h" | ||
| 13 | |||
| 14 | #pragma optimize("", off) | ||
| 15 | |||
| 9 | namespace OpenGL { | 16 | namespace OpenGL { |
| 10 | 17 | ||
| 11 | class ProgramManager { | 18 | class ProgramManager { |
| 19 | static constexpr size_t NUM_STAGES = 5; | ||
| 20 | |||
| 21 | static constexpr std::array ASSEMBLY_PROGRAM_ENUMS{ | ||
| 22 | GL_VERTEX_PROGRAM_NV, GL_TESS_CONTROL_PROGRAM_NV, GL_TESS_EVALUATION_PROGRAM_NV, | ||
| 23 | GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV, | ||
| 24 | }; | ||
| 25 | |||
| 12 | public: | 26 | public: |
| 13 | void BindProgram(GLuint program) { | 27 | void BindProgram(GLuint program) { |
| 14 | if (bound_program == program) { | 28 | if (current_source_program == program) { |
| 15 | return; | 29 | return; |
| 16 | } | 30 | } |
| 17 | bound_program = program; | 31 | current_source_program = program; |
| 18 | glUseProgram(program); | 32 | glUseProgram(program); |
| 19 | } | 33 | } |
| 20 | 34 | ||
| 35 | void BindAssemblyPrograms(std::span<const OGLAssemblyProgram, NUM_STAGES> programs, | ||
| 36 | u32 stage_mask) { | ||
| 37 | const u32 changed_mask = current_assembly_mask ^ stage_mask; | ||
| 38 | current_assembly_mask = stage_mask; | ||
| 39 | |||
| 40 | if (changed_mask != 0) { | ||
| 41 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { | ||
| 42 | if (((changed_mask >> stage) & 1) != 0) { | ||
| 43 | if (((stage_mask >> stage) & 1) != 0) { | ||
| 44 | glEnable(ASSEMBLY_PROGRAM_ENUMS[stage]); | ||
| 45 | } else { | ||
| 46 | glDisable(ASSEMBLY_PROGRAM_ENUMS[stage]); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
| 51 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { | ||
| 52 | if (current_assembly_programs[stage] != programs[stage].handle) { | ||
| 53 | current_assembly_programs[stage] = programs[stage].handle; | ||
| 54 | glBindProgramARB(ASSEMBLY_PROGRAM_ENUMS[stage], programs[stage].handle); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | if (current_source_program != 0) { | ||
| 58 | current_source_program = 0; | ||
| 59 | glUseProgram(0); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 21 | void RestoreGuestCompute() {} | 63 | void RestoreGuestCompute() {} |
| 22 | 64 | ||
| 23 | private: | 65 | private: |
| 24 | GLuint bound_program = 0; | 66 | GLuint current_source_program = 0; |
| 67 | |||
| 68 | u32 current_assembly_mask = 0; | ||
| 69 | std::array<GLuint, NUM_STAGES> current_assembly_programs; | ||
| 25 | }; | 70 | }; |
| 26 | 71 | ||
| 27 | } // namespace OpenGL | 72 | } // namespace OpenGL |