diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_compute_pipeline.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | 62 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_pipeline.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.h | 100 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_util.cpp | 57 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_util.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/util_shaders.cpp | 19 |
9 files changed, 154 insertions, 116 deletions
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index c63e87a56..aa1cc592f 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp | |||
| @@ -46,17 +46,13 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac | |||
| 46 | kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} { | 46 | kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} { |
| 47 | switch (device.GetShaderBackend()) { | 47 | switch (device.GetShaderBackend()) { |
| 48 | case Settings::ShaderBackend::GLSL: | 48 | case Settings::ShaderBackend::GLSL: |
| 49 | source_program.handle = glCreateProgram(); | 49 | source_program = CreateProgram(code, GL_COMPUTE_SHADER); |
| 50 | AttachShader(GL_COMPUTE_SHADER, source_program.handle, code); | ||
| 51 | LinkProgram(source_program.handle); | ||
| 52 | break; | 50 | break; |
| 53 | case Settings::ShaderBackend::GLASM: | 51 | case Settings::ShaderBackend::GLASM: |
| 54 | assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); | 52 | assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); |
| 55 | break; | 53 | break; |
| 56 | case Settings::ShaderBackend::SPIRV: | 54 | case Settings::ShaderBackend::SPIRV: |
| 57 | source_program.handle = glCreateProgram(); | 55 | source_program = CreateProgram(code_v, GL_COMPUTE_SHADER); |
| 58 | AttachShader(GL_COMPUTE_SHADER, source_program.handle, code_v); | ||
| 59 | LinkProgram(source_program.handle); | ||
| 60 | break; | 56 | break; |
| 61 | } | 57 | } |
| 62 | std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), | 58 | std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), |
| @@ -154,7 +150,7 @@ void ComputePipeline::Configure() { | |||
| 154 | if (assembly_program.handle != 0) { | 150 | if (assembly_program.handle != 0) { |
| 155 | program_manager.BindComputeAssemblyProgram(assembly_program.handle); | 151 | program_manager.BindComputeAssemblyProgram(assembly_program.handle); |
| 156 | } else { | 152 | } else { |
| 157 | program_manager.BindProgram(source_program.handle); | 153 | program_manager.BindComputeProgram(source_program.handle); |
| 158 | } | 154 | } |
| 159 | buffer_cache.UnbindComputeTextureBuffers(); | 155 | buffer_cache.UnbindComputeTextureBuffers(); |
| 160 | size_t texbuf_index{}; | 156 | size_t texbuf_index{}; |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 1f19b5825..c8b2d833d 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | |||
| @@ -237,44 +237,32 @@ GraphicsPipeline::GraphicsPipeline( | |||
| 237 | if (key.xfb_enabled && device.UseAssemblyShaders()) { | 237 | if (key.xfb_enabled && device.UseAssemblyShaders()) { |
| 238 | GenerateTransformFeedbackState(); | 238 | GenerateTransformFeedbackState(); |
| 239 | } | 239 | } |
| 240 | auto func{ | 240 | auto func{[this, device, sources, sources_spirv, |
| 241 | [this, device, sources, sources_spirv, shader_notify](ShaderContext::Context*) mutable { | 241 | shader_notify](ShaderContext::Context*) mutable { |
| 242 | if (!device.UseAssemblyShaders()) { | 242 | for (size_t stage = 0; stage < 5; ++stage) { |
| 243 | program.handle = glCreateProgram(); | 243 | switch (device.GetShaderBackend()) { |
| 244 | } | 244 | case Settings::ShaderBackend::GLSL: |
| 245 | for (size_t stage = 0; stage < 5; ++stage) { | 245 | if (!sources[stage].empty()) { |
| 246 | switch (device.GetShaderBackend()) { | 246 | source_programs[stage] = CreateProgram(sources[stage], Stage(stage)); |
| 247 | case Settings::ShaderBackend::GLSL: { | ||
| 248 | const auto code{sources[stage]}; | ||
| 249 | if (code.empty()) { | ||
| 250 | continue; | ||
| 251 | } | ||
| 252 | AttachShader(Stage(stage), program.handle, code); | ||
| 253 | } break; | ||
| 254 | case Settings::ShaderBackend::GLASM: { | ||
| 255 | const auto code{sources[stage]}; | ||
| 256 | if (code.empty()) { | ||
| 257 | continue; | ||
| 258 | } | ||
| 259 | assembly_programs[stage] = CompileProgram(code, AssemblyStage(stage)); | ||
| 260 | } break; | ||
| 261 | case Settings::ShaderBackend::SPIRV: { | ||
| 262 | const auto code{sources_spirv[stage]}; | ||
| 263 | if (code.empty()) { | ||
| 264 | continue; | ||
| 265 | } | ||
| 266 | AttachShader(Stage(stage), program.handle, code); | ||
| 267 | } break; | ||
| 268 | } | 247 | } |
| 248 | break; | ||
| 249 | case Settings::ShaderBackend::GLASM: | ||
| 250 | if (!sources[stage].empty()) { | ||
| 251 | assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage)); | ||
| 252 | } | ||
| 253 | break; | ||
| 254 | case Settings::ShaderBackend::SPIRV: | ||
| 255 | if (!sources_spirv[stage].empty()) { | ||
| 256 | source_programs[stage] = CreateProgram(sources_spirv[stage], Stage(stage)); | ||
| 257 | } | ||
| 258 | break; | ||
| 269 | } | 259 | } |
| 270 | if (!device.UseAssemblyShaders()) { | 260 | } |
| 271 | LinkProgram(program.handle); | 261 | if (shader_notify) { |
| 272 | } | 262 | shader_notify->MarkShaderComplete(); |
| 273 | if (shader_notify) { | 263 | } |
| 274 | shader_notify->MarkShaderComplete(); | 264 | is_built = true; |
| 275 | } | 265 | }}; |
| 276 | is_built.store(true, std::memory_order_relaxed); | ||
| 277 | }}; | ||
| 278 | if (thread_worker) { | 266 | if (thread_worker) { |
| 279 | thread_worker->QueueWork(std::move(func)); | 267 | thread_worker->QueueWork(std::move(func)); |
| 280 | } else { | 268 | } else { |
| @@ -449,7 +437,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 449 | if (assembly_programs[0].handle != 0) { | 437 | if (assembly_programs[0].handle != 0) { |
| 450 | program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); | 438 | program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); |
| 451 | } else { | 439 | } else { |
| 452 | program_manager.BindProgram(program.handle); | 440 | program_manager.BindSourcePrograms(source_programs); |
| 453 | } | 441 | } |
| 454 | const ImageId* views_it{image_view_ids.data()}; | 442 | const ImageId* views_it{image_view_ids.data()}; |
| 455 | GLsizei texture_binding = 0; | 443 | GLsizei texture_binding = 0; |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h index 5f5d57385..5e34b9537 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h | |||
| @@ -129,7 +129,7 @@ private: | |||
| 129 | 129 | ||
| 130 | void (*configure_func)(GraphicsPipeline*, bool){}; | 130 | void (*configure_func)(GraphicsPipeline*, bool){}; |
| 131 | 131 | ||
| 132 | OGLProgram program; | 132 | std::array<OGLProgram, 5> source_programs; |
| 133 | std::array<OGLAssemblyProgram, 5> assembly_programs; | 133 | std::array<OGLAssemblyProgram, 5> assembly_programs; |
| 134 | u32 enabled_stages_mask{}; | 134 | u32 enabled_stages_mask{}; |
| 135 | 135 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 88b734bcb..d7ef0775d 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -24,34 +24,68 @@ class ProgramManager { | |||
| 24 | 24 | ||
| 25 | public: | 25 | public: |
| 26 | explicit ProgramManager(const Device& device) { | 26 | explicit ProgramManager(const Device& device) { |
| 27 | glCreateProgramPipelines(1, &pipeline.handle); | ||
| 27 | if (device.UseAssemblyShaders()) { | 28 | if (device.UseAssemblyShaders()) { |
| 28 | glEnable(GL_COMPUTE_PROGRAM_NV); | 29 | glEnable(GL_COMPUTE_PROGRAM_NV); |
| 29 | } | 30 | } |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | void BindProgram(GLuint program) { | 33 | void BindComputeProgram(GLuint program) { |
| 33 | if (current_source_program == program) { | ||
| 34 | return; | ||
| 35 | } | ||
| 36 | current_source_program = program; | ||
| 37 | glUseProgram(program); | 34 | glUseProgram(program); |
| 35 | is_compute_bound = true; | ||
| 38 | } | 36 | } |
| 39 | 37 | ||
| 40 | void BindComputeAssemblyProgram(GLuint program) { | 38 | void BindComputeAssemblyProgram(GLuint program) { |
| 41 | if (current_compute_assembly_program != program) { | 39 | if (current_assembly_compute_program != program) { |
| 42 | current_compute_assembly_program = program; | 40 | current_assembly_compute_program = program; |
| 43 | glBindProgramARB(GL_COMPUTE_PROGRAM_NV, program); | 41 | glBindProgramARB(GL_COMPUTE_PROGRAM_NV, program); |
| 44 | } | 42 | } |
| 45 | if (current_source_program != 0) { | 43 | UnbindPipeline(); |
| 46 | current_source_program = 0; | 44 | } |
| 47 | glUseProgram(0); | 45 | |
| 46 | void BindSourcePrograms(std::span<const OGLProgram, NUM_STAGES> programs) { | ||
| 47 | static constexpr std::array<GLenum, 5> stage_enums{ | ||
| 48 | GL_VERTEX_SHADER_BIT, GL_TESS_CONTROL_SHADER_BIT, GL_TESS_EVALUATION_SHADER_BIT, | ||
| 49 | GL_GEOMETRY_SHADER_BIT, GL_FRAGMENT_SHADER_BIT, | ||
| 50 | }; | ||
| 51 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { | ||
| 52 | if (current_programs[stage] != programs[stage].handle) { | ||
| 53 | current_programs[stage] = programs[stage].handle; | ||
| 54 | glUseProgramStages(pipeline.handle, stage_enums[stage], programs[stage].handle); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | BindPipeline(); | ||
| 58 | } | ||
| 59 | |||
| 60 | void BindPresentPrograms(GLuint vertex, GLuint fragment) { | ||
| 61 | if (current_programs[0] != vertex) { | ||
| 62 | current_programs[0] = vertex; | ||
| 63 | glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, vertex); | ||
| 64 | } | ||
| 65 | if (current_programs[4] != fragment) { | ||
| 66 | current_programs[4] = fragment; | ||
| 67 | glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fragment); | ||
| 68 | } | ||
| 69 | glUseProgramStages( | ||
| 70 | pipeline.handle, | ||
| 71 | GL_TESS_CONTROL_SHADER_BIT | GL_TESS_EVALUATION_SHADER_BIT | GL_GEOMETRY_SHADER_BIT, 0); | ||
| 72 | current_programs[1] = 0; | ||
| 73 | current_programs[2] = 0; | ||
| 74 | current_programs[3] = 0; | ||
| 75 | |||
| 76 | if (current_stage_mask != 0) { | ||
| 77 | current_stage_mask = 0; | ||
| 78 | for (const GLenum program_type : ASSEMBLY_PROGRAM_ENUMS) { | ||
| 79 | glDisable(program_type); | ||
| 80 | } | ||
| 48 | } | 81 | } |
| 82 | BindPipeline(); | ||
| 49 | } | 83 | } |
| 50 | 84 | ||
| 51 | void BindAssemblyPrograms(std::span<const OGLAssemblyProgram, NUM_STAGES> programs, | 85 | void BindAssemblyPrograms(std::span<const OGLAssemblyProgram, NUM_STAGES> programs, |
| 52 | u32 stage_mask) { | 86 | u32 stage_mask) { |
| 53 | const u32 changed_mask = current_assembly_mask ^ stage_mask; | 87 | const u32 changed_mask = current_stage_mask ^ stage_mask; |
| 54 | current_assembly_mask = stage_mask; | 88 | current_stage_mask = stage_mask; |
| 55 | 89 | ||
| 56 | if (changed_mask != 0) { | 90 | if (changed_mask != 0) { |
| 57 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { | 91 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { |
| @@ -65,25 +99,47 @@ public: | |||
| 65 | } | 99 | } |
| 66 | } | 100 | } |
| 67 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { | 101 | for (size_t stage = 0; stage < NUM_STAGES; ++stage) { |
| 68 | if (current_assembly_programs[stage] != programs[stage].handle) { | 102 | if (current_programs[stage] != programs[stage].handle) { |
| 69 | current_assembly_programs[stage] = programs[stage].handle; | 103 | current_programs[stage] = programs[stage].handle; |
| 70 | glBindProgramARB(ASSEMBLY_PROGRAM_ENUMS[stage], programs[stage].handle); | 104 | glBindProgramARB(ASSEMBLY_PROGRAM_ENUMS[stage], programs[stage].handle); |
| 71 | } | 105 | } |
| 72 | } | 106 | } |
| 73 | if (current_source_program != 0) { | 107 | UnbindPipeline(); |
| 74 | current_source_program = 0; | ||
| 75 | glUseProgram(0); | ||
| 76 | } | ||
| 77 | } | 108 | } |
| 78 | 109 | ||
| 79 | void RestoreGuestCompute() {} | 110 | void RestoreGuestCompute() {} |
| 80 | 111 | ||
| 81 | private: | 112 | private: |
| 82 | GLuint current_source_program = 0; | 113 | void BindPipeline() { |
| 114 | if (!is_pipeline_bound) { | ||
| 115 | is_pipeline_bound = true; | ||
| 116 | glBindProgramPipeline(pipeline.handle); | ||
| 117 | } | ||
| 118 | UnbindCompute(); | ||
| 119 | } | ||
| 120 | |||
| 121 | void UnbindPipeline() { | ||
| 122 | if (is_pipeline_bound) { | ||
| 123 | is_pipeline_bound = false; | ||
| 124 | glBindProgramPipeline(0); | ||
| 125 | } | ||
| 126 | UnbindCompute(); | ||
| 127 | } | ||
| 128 | |||
| 129 | void UnbindCompute() { | ||
| 130 | if (is_compute_bound) { | ||
| 131 | is_compute_bound = false; | ||
| 132 | glUseProgram(0); | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | OGLPipeline pipeline; | ||
| 137 | bool is_pipeline_bound{}; | ||
| 138 | bool is_compute_bound{}; | ||
| 83 | 139 | ||
| 84 | u32 current_assembly_mask = 0; | 140 | u32 current_stage_mask = 0; |
| 85 | std::array<GLuint, NUM_STAGES> current_assembly_programs{}; | 141 | std::array<GLuint, NUM_STAGES> current_programs{}; |
| 86 | GLuint current_compute_assembly_program = 0; | 142 | GLuint current_assembly_compute_program = 0; |
| 87 | }; | 143 | }; |
| 88 | 144 | ||
| 89 | } // namespace OpenGL | 145 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index 5109985f1..d432072ad 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp | |||
| @@ -13,6 +13,33 @@ | |||
| 13 | 13 | ||
| 14 | namespace OpenGL { | 14 | namespace OpenGL { |
| 15 | 15 | ||
| 16 | static OGLProgram LinkSeparableProgram(GLuint shader) { | ||
| 17 | OGLProgram program; | ||
| 18 | program.handle = glCreateProgram(); | ||
| 19 | glProgramParameteri(program.handle, GL_PROGRAM_SEPARABLE, GL_TRUE); | ||
| 20 | glAttachShader(program.handle, shader); | ||
| 21 | glLinkProgram(program.handle); | ||
| 22 | if (!Settings::values.renderer_debug) { | ||
| 23 | return program; | ||
| 24 | } | ||
| 25 | GLint link_status{}; | ||
| 26 | glGetProgramiv(program.handle, GL_LINK_STATUS, &link_status); | ||
| 27 | |||
| 28 | GLint log_length{}; | ||
| 29 | glGetProgramiv(program.handle, GL_INFO_LOG_LENGTH, &log_length); | ||
| 30 | if (log_length == 0) { | ||
| 31 | return program; | ||
| 32 | } | ||
| 33 | std::string log(log_length, 0); | ||
| 34 | glGetProgramInfoLog(program.handle, log_length, nullptr, log.data()); | ||
| 35 | if (link_status == GL_FALSE) { | ||
| 36 | LOG_ERROR(Render_OpenGL, "{}", log); | ||
| 37 | } else { | ||
| 38 | LOG_WARNING(Render_OpenGL, "{}", log); | ||
| 39 | } | ||
| 40 | return program; | ||
| 41 | } | ||
| 42 | |||
| 16 | static void LogShader(GLuint shader, std::string_view code = {}) { | 43 | static void LogShader(GLuint shader, std::string_view code = {}) { |
| 17 | GLint shader_status{}; | 44 | GLint shader_status{}; |
| 18 | glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_status); | 45 | glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_status); |
| @@ -36,7 +63,7 @@ static void LogShader(GLuint shader, std::string_view code = {}) { | |||
| 36 | } | 63 | } |
| 37 | } | 64 | } |
| 38 | 65 | ||
| 39 | void AttachShader(GLenum stage, GLuint program, std::string_view code) { | 66 | OGLProgram CreateProgram(std::string_view code, GLenum stage) { |
| 40 | OGLShader shader; | 67 | OGLShader shader; |
| 41 | shader.handle = glCreateShader(stage); | 68 | shader.handle = glCreateShader(stage); |
| 42 | 69 | ||
| @@ -44,45 +71,23 @@ void AttachShader(GLenum stage, GLuint program, std::string_view code) { | |||
| 44 | const GLchar* const code_ptr = code.data(); | 71 | const GLchar* const code_ptr = code.data(); |
| 45 | glShaderSource(shader.handle, 1, &code_ptr, &length); | 72 | glShaderSource(shader.handle, 1, &code_ptr, &length); |
| 46 | glCompileShader(shader.handle); | 73 | glCompileShader(shader.handle); |
| 47 | glAttachShader(program, shader.handle); | ||
| 48 | if (Settings::values.renderer_debug) { | 74 | if (Settings::values.renderer_debug) { |
| 49 | LogShader(shader.handle, code); | 75 | LogShader(shader.handle, code); |
| 50 | } | 76 | } |
| 77 | return LinkSeparableProgram(shader.handle); | ||
| 51 | } | 78 | } |
| 52 | 79 | ||
| 53 | void AttachShader(GLenum stage, GLuint program, std::span<const u32> code) { | 80 | OGLProgram CreateProgram(std::span<const u32> code, GLenum stage) { |
| 54 | OGLShader shader; | 81 | OGLShader shader; |
| 55 | shader.handle = glCreateShader(stage); | 82 | shader.handle = glCreateShader(stage); |
| 56 | 83 | ||
| 57 | glShaderBinary(1, &shader.handle, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, code.data(), | 84 | glShaderBinary(1, &shader.handle, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, code.data(), |
| 58 | static_cast<GLsizei>(code.size_bytes())); | 85 | static_cast<GLsizei>(code.size_bytes())); |
| 59 | glSpecializeShader(shader.handle, "main", 0, nullptr, nullptr); | 86 | glSpecializeShader(shader.handle, "main", 0, nullptr, nullptr); |
| 60 | glAttachShader(program, shader.handle); | ||
| 61 | if (Settings::values.renderer_debug) { | 87 | if (Settings::values.renderer_debug) { |
| 62 | LogShader(shader.handle); | 88 | LogShader(shader.handle); |
| 63 | } | 89 | } |
| 64 | } | 90 | return LinkSeparableProgram(shader.handle); |
| 65 | |||
| 66 | void LinkProgram(GLuint program) { | ||
| 67 | glLinkProgram(program); | ||
| 68 | if (!Settings::values.renderer_debug) { | ||
| 69 | return; | ||
| 70 | } | ||
| 71 | GLint link_status{}; | ||
| 72 | glGetProgramiv(program, GL_LINK_STATUS, &link_status); | ||
| 73 | |||
| 74 | GLint log_length{}; | ||
| 75 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length); | ||
| 76 | if (log_length == 0) { | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | std::string log(log_length, 0); | ||
| 80 | glGetProgramInfoLog(program, log_length, nullptr, log.data()); | ||
| 81 | if (link_status == GL_FALSE) { | ||
| 82 | LOG_ERROR(Render_OpenGL, "{}", log); | ||
| 83 | } else { | ||
| 84 | LOG_WARNING(Render_OpenGL, "{}", log); | ||
| 85 | } | ||
| 86 | } | 91 | } |
| 87 | 92 | ||
| 88 | OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target) { | 93 | OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_util.h b/src/video_core/renderer_opengl/gl_shader_util.h index ff5aa024f..4e1a2a8e1 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.h +++ b/src/video_core/renderer_opengl/gl_shader_util.h | |||
| @@ -17,11 +17,9 @@ | |||
| 17 | 17 | ||
| 18 | namespace OpenGL { | 18 | namespace OpenGL { |
| 19 | 19 | ||
| 20 | void AttachShader(GLenum stage, GLuint program, std::string_view code); | 20 | OGLProgram CreateProgram(std::string_view code, GLenum stage); |
| 21 | 21 | ||
| 22 | void AttachShader(GLenum stage, GLuint program, std::span<const u32> code); | 22 | OGLProgram CreateProgram(std::span<const u32> code, GLenum stage); |
| 23 | |||
| 24 | void LinkProgram(GLuint program); | ||
| 25 | 23 | ||
| 26 | OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target); | 24 | OGLAssemblyProgram CompileProgram(std::string_view code, GLenum target); |
| 27 | 25 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index c9cfa6366..d15167e19 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -251,10 +251,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color | |||
| 251 | 251 | ||
| 252 | void RendererOpenGL::InitOpenGLObjects() { | 252 | void RendererOpenGL::InitOpenGLObjects() { |
| 253 | // Create shader programs | 253 | // Create shader programs |
| 254 | present_program.handle = glCreateProgram(); | 254 | present_vertex = CreateProgram(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER); |
| 255 | AttachShader(GL_VERTEX_SHADER, present_program.handle, HostShaders::OPENGL_PRESENT_VERT); | 255 | present_fragment = CreateProgram(HostShaders::OPENGL_PRESENT_FRAG, GL_FRAGMENT_SHADER); |
| 256 | AttachShader(GL_FRAGMENT_SHADER, present_program.handle, HostShaders::OPENGL_PRESENT_FRAG); | ||
| 257 | LinkProgram(present_program.handle); | ||
| 258 | 256 | ||
| 259 | // Generate presentation sampler | 257 | // Generate presentation sampler |
| 260 | present_sampler.Create(); | 258 | present_sampler.Create(); |
| @@ -340,8 +338,9 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 340 | // Set projection matrix | 338 | // Set projection matrix |
| 341 | const std::array ortho_matrix = | 339 | const std::array ortho_matrix = |
| 342 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); | 340 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); |
| 343 | program_manager.BindProgram(present_program.handle); | 341 | program_manager.BindPresentPrograms(present_vertex.handle, present_fragment.handle); |
| 344 | glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data()); | 342 | glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE, |
| 343 | ortho_matrix.data()); | ||
| 345 | 344 | ||
| 346 | const auto& texcoords = screen_info.display_texcoords; | 345 | const auto& texcoords = screen_info.display_texcoords; |
| 347 | auto left = texcoords.left; | 346 | auto left = texcoords.left; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index b3ee55665..d455f572f 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -110,7 +110,8 @@ private: | |||
| 110 | // OpenGL object IDs | 110 | // OpenGL object IDs |
| 111 | OGLSampler present_sampler; | 111 | OGLSampler present_sampler; |
| 112 | OGLBuffer vertex_buffer; | 112 | OGLBuffer vertex_buffer; |
| 113 | OGLProgram present_program; | 113 | OGLProgram present_vertex; |
| 114 | OGLProgram present_fragment; | ||
| 114 | OGLFramebuffer screenshot_framebuffer; | 115 | OGLFramebuffer screenshot_framebuffer; |
| 115 | 116 | ||
| 116 | // GPU address of the vertex buffer | 117 | // GPU address of the vertex buffer |
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp index 8aa0683c8..37a4d1d9d 100644 --- a/src/video_core/renderer_opengl/util_shaders.cpp +++ b/src/video_core/renderer_opengl/util_shaders.cpp | |||
| @@ -42,12 +42,7 @@ using VideoCore::Surface::BytesPerBlock; | |||
| 42 | 42 | ||
| 43 | namespace { | 43 | namespace { |
| 44 | OGLProgram MakeProgram(std::string_view source) { | 44 | OGLProgram MakeProgram(std::string_view source) { |
| 45 | OGLProgram program; | 45 | return CreateProgram(source, GL_COMPUTE_SHADER); |
| 46 | OGLShader shader; | ||
| 47 | program.handle = glCreateProgram(); | ||
| 48 | AttachShader(GL_COMPUTE_SHADER, program.handle, source); | ||
| 49 | LinkProgram(program.handle); | ||
| 50 | return program; | ||
| 51 | } | 46 | } |
| 52 | 47 | ||
| 53 | size_t NumPixelsInCopy(const VideoCommon::ImageCopy& copy) { | 48 | size_t NumPixelsInCopy(const VideoCommon::ImageCopy& copy) { |
| @@ -84,7 +79,7 @@ void UtilShaders::ASTCDecode(Image& image, const ImageBufferMap& map, | |||
| 84 | .width = VideoCore::Surface::DefaultBlockWidth(image.info.format), | 79 | .width = VideoCore::Surface::DefaultBlockWidth(image.info.format), |
| 85 | .height = VideoCore::Surface::DefaultBlockHeight(image.info.format), | 80 | .height = VideoCore::Surface::DefaultBlockHeight(image.info.format), |
| 86 | }; | 81 | }; |
| 87 | program_manager.BindProgram(astc_decoder_program.handle); | 82 | program_manager.BindComputeProgram(astc_decoder_program.handle); |
| 88 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); | 83 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); |
| 89 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_ENC_BUFFER, astc_buffer.handle); | 84 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_ENC_BUFFER, astc_buffer.handle); |
| 90 | 85 | ||
| @@ -132,7 +127,7 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map, | |||
| 132 | static constexpr GLuint BINDING_INPUT_BUFFER = 1; | 127 | static constexpr GLuint BINDING_INPUT_BUFFER = 1; |
| 133 | static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; | 128 | static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; |
| 134 | 129 | ||
| 135 | program_manager.BindProgram(block_linear_unswizzle_2d_program.handle); | 130 | program_manager.BindComputeProgram(block_linear_unswizzle_2d_program.handle); |
| 136 | glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); | 131 | glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); |
| 137 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); | 132 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); |
| 138 | 133 | ||
| @@ -171,7 +166,7 @@ void UtilShaders::BlockLinearUpload3D(Image& image, const ImageBufferMap& map, | |||
| 171 | static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; | 166 | static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; |
| 172 | 167 | ||
| 173 | glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); | 168 | glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); |
| 174 | program_manager.BindProgram(block_linear_unswizzle_3d_program.handle); | 169 | program_manager.BindComputeProgram(block_linear_unswizzle_3d_program.handle); |
| 175 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); | 170 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); |
| 176 | 171 | ||
| 177 | const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format)); | 172 | const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format)); |
| @@ -220,7 +215,7 @@ void UtilShaders::PitchUpload(Image& image, const ImageBufferMap& map, | |||
| 220 | UNIMPLEMENTED_IF_MSG(!std::has_single_bit(bytes_per_block), | 215 | UNIMPLEMENTED_IF_MSG(!std::has_single_bit(bytes_per_block), |
| 221 | "Non-power of two images are not implemented"); | 216 | "Non-power of two images are not implemented"); |
| 222 | 217 | ||
| 223 | program_manager.BindProgram(pitch_unswizzle_program.handle); | 218 | program_manager.BindComputeProgram(pitch_unswizzle_program.handle); |
| 224 | glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); | 219 | glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); |
| 225 | glUniform2ui(LOC_ORIGIN, 0, 0); | 220 | glUniform2ui(LOC_ORIGIN, 0, 0); |
| 226 | glUniform2i(LOC_DESTINATION, 0, 0); | 221 | glUniform2i(LOC_DESTINATION, 0, 0); |
| @@ -248,7 +243,7 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im | |||
| 248 | static constexpr GLuint LOC_SRC_OFFSET = 0; | 243 | static constexpr GLuint LOC_SRC_OFFSET = 0; |
| 249 | static constexpr GLuint LOC_DST_OFFSET = 1; | 244 | static constexpr GLuint LOC_DST_OFFSET = 1; |
| 250 | 245 | ||
| 251 | program_manager.BindProgram(copy_bc4_program.handle); | 246 | program_manager.BindComputeProgram(copy_bc4_program.handle); |
| 252 | 247 | ||
| 253 | for (const ImageCopy& copy : copies) { | 248 | for (const ImageCopy& copy : copies) { |
| 254 | ASSERT(copy.src_subresource.base_layer == 0); | 249 | ASSERT(copy.src_subresource.base_layer == 0); |
| @@ -284,7 +279,7 @@ void UtilShaders::CopyBGR(Image& dst_image, Image& src_image, | |||
| 284 | break; | 279 | break; |
| 285 | case 4: { | 280 | case 4: { |
| 286 | // BGRA8 copy | 281 | // BGRA8 copy |
| 287 | program_manager.BindProgram(copy_bgra_program.handle); | 282 | program_manager.BindComputeProgram(copy_bgra_program.handle); |
| 288 | constexpr GLenum FORMAT = GL_RGBA8; | 283 | constexpr GLenum FORMAT = GL_RGBA8; |
| 289 | for (const ImageCopy& copy : copies) { | 284 | for (const ImageCopy& copy : copies) { |
| 290 | ASSERT(copy.src_offset == zero_offset); | 285 | ASSERT(copy.src_offset == zero_offset); |