summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_shader_manager.h
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-07-14 08:48:30 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:40 +0200
commite1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5 (patch)
treeac6ddd37fd94fd2ccd693b4da0443ff28b75008d /src/video_core/renderer_opengl/gl_shader_manager.h
parentshader: Implement ISETP.X (diff)
downloadyuzu-e1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5.tar
yuzu-e1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5.tar.gz
yuzu-e1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5.tar.bz2
yuzu-e1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5.tar.lz
yuzu-e1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5.tar.xz
yuzu-e1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5.tar.zst
yuzu-e1ed218b418cd1ed94f6f25ccd0db86b63bd6bb5.zip
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h100
1 files changed, 78 insertions, 22 deletions
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 {
public:
explicit ProgramManager(const Device& device) {
+ glCreateProgramPipelines(1, &pipeline.handle);
if (device.UseAssemblyShaders()) {
glEnable(GL_COMPUTE_PROGRAM_NV);
}
}
- void BindProgram(GLuint program) {
- if (current_source_program == program) {
- return;
- }
- current_source_program = program;
+ void BindComputeProgram(GLuint program) {
glUseProgram(program);
+ is_compute_bound = true;
}
void BindComputeAssemblyProgram(GLuint program) {
- if (current_compute_assembly_program != program) {
- current_compute_assembly_program = program;
+ if (current_assembly_compute_program != program) {
+ current_assembly_compute_program = program;
glBindProgramARB(GL_COMPUTE_PROGRAM_NV, program);
}
- if (current_source_program != 0) {
- current_source_program = 0;
- glUseProgram(0);
+ UnbindPipeline();
+ }
+
+ void BindSourcePrograms(std::span<const OGLProgram, NUM_STAGES> programs) {
+ static constexpr std::array<GLenum, 5> stage_enums{
+ GL_VERTEX_SHADER_BIT, GL_TESS_CONTROL_SHADER_BIT, GL_TESS_EVALUATION_SHADER_BIT,
+ GL_GEOMETRY_SHADER_BIT, GL_FRAGMENT_SHADER_BIT,
+ };
+ for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
+ if (current_programs[stage] != programs[stage].handle) {
+ current_programs[stage] = programs[stage].handle;
+ glUseProgramStages(pipeline.handle, stage_enums[stage], programs[stage].handle);
+ }
+ }
+ BindPipeline();
+ }
+
+ void BindPresentPrograms(GLuint vertex, GLuint fragment) {
+ if (current_programs[0] != vertex) {
+ current_programs[0] = vertex;
+ glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, vertex);
+ }
+ if (current_programs[4] != fragment) {
+ current_programs[4] = fragment;
+ glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fragment);
+ }
+ glUseProgramStages(
+ pipeline.handle,
+ GL_TESS_CONTROL_SHADER_BIT | GL_TESS_EVALUATION_SHADER_BIT | GL_GEOMETRY_SHADER_BIT, 0);
+ current_programs[1] = 0;
+ current_programs[2] = 0;
+ current_programs[3] = 0;
+
+ if (current_stage_mask != 0) {
+ current_stage_mask = 0;
+ for (const GLenum program_type : ASSEMBLY_PROGRAM_ENUMS) {
+ glDisable(program_type);
+ }
}
+ BindPipeline();
}
void BindAssemblyPrograms(std::span<const OGLAssemblyProgram, NUM_STAGES> programs,
u32 stage_mask) {
- const u32 changed_mask = current_assembly_mask ^ stage_mask;
- current_assembly_mask = stage_mask;
+ const u32 changed_mask = current_stage_mask ^ stage_mask;
+ current_stage_mask = stage_mask;
if (changed_mask != 0) {
for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
@@ -65,25 +99,47 @@ public:
}
}
for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
- if (current_assembly_programs[stage] != programs[stage].handle) {
- current_assembly_programs[stage] = programs[stage].handle;
+ if (current_programs[stage] != programs[stage].handle) {
+ current_programs[stage] = programs[stage].handle;
glBindProgramARB(ASSEMBLY_PROGRAM_ENUMS[stage], programs[stage].handle);
}
}
- if (current_source_program != 0) {
- current_source_program = 0;
- glUseProgram(0);
- }
+ UnbindPipeline();
}
void RestoreGuestCompute() {}
private:
- GLuint current_source_program = 0;
+ void BindPipeline() {
+ if (!is_pipeline_bound) {
+ is_pipeline_bound = true;
+ glBindProgramPipeline(pipeline.handle);
+ }
+ UnbindCompute();
+ }
+
+ void UnbindPipeline() {
+ if (is_pipeline_bound) {
+ is_pipeline_bound = false;
+ glBindProgramPipeline(0);
+ }
+ UnbindCompute();
+ }
+
+ void UnbindCompute() {
+ if (is_compute_bound) {
+ is_compute_bound = false;
+ glUseProgram(0);
+ }
+ }
+
+ OGLPipeline pipeline;
+ bool is_pipeline_bound{};
+ bool is_compute_bound{};
- u32 current_assembly_mask = 0;
- std::array<GLuint, NUM_STAGES> current_assembly_programs{};
- GLuint current_compute_assembly_program = 0;
+ u32 current_stage_mask = 0;
+ std::array<GLuint, NUM_STAGES> current_programs{};
+ GLuint current_assembly_compute_program = 0;
};
} // namespace OpenGL