2018-04-07 11:12:38 +02:00
|
|
|
// Copyright 2018 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2021-05-20 21:53:51 +02:00
|
|
|
#include <array>
|
|
|
|
#include <span>
|
|
|
|
|
2018-04-07 11:12:38 +02:00
|
|
|
#include <glad/glad.h>
|
2018-08-23 23:30:27 +02:00
|
|
|
|
2021-05-20 21:53:51 +02:00
|
|
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
2021-05-20 21:59:05 +02:00
|
|
|
#include "video_core/renderer_opengl/gl_device.h"
|
2021-05-20 21:53:51 +02:00
|
|
|
|
2020-05-18 03:32:49 +02:00
|
|
|
namespace OpenGL {
|
|
|
|
|
2018-04-07 11:12:38 +02:00
|
|
|
class ProgramManager {
|
2021-05-20 21:53:51 +02:00
|
|
|
static constexpr size_t NUM_STAGES = 5;
|
|
|
|
|
|
|
|
static constexpr std::array ASSEMBLY_PROGRAM_ENUMS{
|
|
|
|
GL_VERTEX_PROGRAM_NV, GL_TESS_CONTROL_PROGRAM_NV, GL_TESS_EVALUATION_PROGRAM_NV,
|
|
|
|
GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV,
|
|
|
|
};
|
|
|
|
|
2018-04-07 11:12:38 +02:00
|
|
|
public:
|
2021-05-20 21:59:05 +02:00
|
|
|
explicit ProgramManager(const Device& device) {
|
|
|
|
if (device.UseAssemblyShaders()) {
|
|
|
|
glEnable(GL_COMPUTE_PROGRAM_NV);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 09:28:34 +02:00
|
|
|
void BindProgram(GLuint program) {
|
2021-05-20 21:53:51 +02:00
|
|
|
if (current_source_program == program) {
|
2021-05-23 09:28:34 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-05-20 21:53:51 +02:00
|
|
|
current_source_program = program;
|
2021-05-23 09:28:34 +02:00
|
|
|
glUseProgram(program);
|
|
|
|
}
|
2020-05-18 03:32:49 +02:00
|
|
|
|
2021-05-20 21:59:05 +02:00
|
|
|
void BindComputeAssemblyProgram(GLuint program) {
|
|
|
|
if (current_compute_assembly_program != program) {
|
|
|
|
current_compute_assembly_program = program;
|
|
|
|
glBindProgramARB(GL_COMPUTE_PROGRAM_NV, program);
|
|
|
|
}
|
|
|
|
if (current_source_program != 0) {
|
|
|
|
current_source_program = 0;
|
|
|
|
glUseProgram(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-20 21:53:51 +02:00
|
|
|
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;
|
|
|
|
|
|
|
|
if (changed_mask != 0) {
|
|
|
|
for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
|
|
|
|
if (((changed_mask >> stage) & 1) != 0) {
|
|
|
|
if (((stage_mask >> stage) & 1) != 0) {
|
|
|
|
glEnable(ASSEMBLY_PROGRAM_ENUMS[stage]);
|
|
|
|
} else {
|
|
|
|
glDisable(ASSEMBLY_PROGRAM_ENUMS[stage]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
|
|
|
|
if (current_assembly_programs[stage] != programs[stage].handle) {
|
|
|
|
current_assembly_programs[stage] = programs[stage].handle;
|
|
|
|
glBindProgramARB(ASSEMBLY_PROGRAM_ENUMS[stage], programs[stage].handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (current_source_program != 0) {
|
|
|
|
current_source_program = 0;
|
|
|
|
glUseProgram(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 09:28:34 +02:00
|
|
|
void RestoreGuestCompute() {}
|
2018-04-15 21:14:57 +02:00
|
|
|
|
2018-11-29 07:24:21 +01:00
|
|
|
private:
|
2021-05-20 21:53:51 +02:00
|
|
|
GLuint current_source_program = 0;
|
|
|
|
|
|
|
|
u32 current_assembly_mask = 0;
|
|
|
|
std::array<GLuint, NUM_STAGES> current_assembly_programs;
|
2021-05-20 21:59:05 +02:00
|
|
|
GLuint current_compute_assembly_program = 0;
|
2018-04-07 11:12:38 +02:00
|
|
|
};
|
|
|
|
|
2020-05-18 03:32:49 +02:00
|
|
|
} // namespace OpenGL
|