citra-emu
/
citra
Archived
1
0
Fork 0

renderer_gl: Use explicit bindings (#6940)

* renderer_gl: Use explicit bindings

* gl_state: Match shadow order with vulkan
This commit is contained in:
GPUCode 2023-09-07 21:42:22 +03:00 committed by GitHub
parent e2d8eef5fa
commit 928f352c94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 102 deletions

View File

@ -26,7 +26,7 @@ using VSOutputAttributes = RasterizerRegs::VSOutputAttributes;
namespace OpenGL { namespace OpenGL {
const std::string UniformBlockDef = Pica::Shader::BuildShaderUniformDefinitions(); const std::string UniformBlockDef = Pica::Shader::BuildShaderUniformDefinitions("binding = 0,");
static std::string GetVertexInterfaceDeclaration(bool is_output, bool separable_shader) { static std::string GetVertexInterfaceDeclaration(bool is_output, bool separable_shader) {
std::string out; std::string out;
@ -1375,22 +1375,22 @@ in vec4 gl_FragCoord;
layout(location = 0) out vec4 color; layout(location = 0) out vec4 color;
uniform sampler2D tex0; layout(binding = 0) uniform sampler2D tex0;
uniform sampler2D tex1; layout(binding = 1) uniform sampler2D tex1;
uniform sampler2D tex2; layout(binding = 2) uniform sampler2D tex2;
uniform sampler2D tex_normal; //< Used for custom normal maps layout(binding = 3) uniform samplerBuffer texture_buffer_lut_lf;
uniform samplerCube tex_cube; layout(binding = 4) uniform samplerBuffer texture_buffer_lut_rg;
uniform samplerBuffer texture_buffer_lut_lf; layout(binding = 5) uniform samplerBuffer texture_buffer_lut_rgba;
uniform samplerBuffer texture_buffer_lut_rg; layout(binding = 6) uniform samplerCube tex_cube;
uniform samplerBuffer texture_buffer_lut_rgba; layout(binding = 7) uniform sampler2D tex_normal;
layout(r32ui) uniform readonly uimage2D shadow_texture_px; layout(binding = 0, r32ui) uniform readonly uimage2D shadow_texture_px;
layout(r32ui) uniform readonly uimage2D shadow_texture_nx; layout(binding = 1, r32ui) uniform readonly uimage2D shadow_texture_nx;
layout(r32ui) uniform readonly uimage2D shadow_texture_py; layout(binding = 2, r32ui) uniform readonly uimage2D shadow_texture_py;
layout(r32ui) uniform readonly uimage2D shadow_texture_ny; layout(binding = 3, r32ui) uniform readonly uimage2D shadow_texture_ny;
layout(r32ui) uniform readonly uimage2D shadow_texture_pz; layout(binding = 4, r32ui) uniform readonly uimage2D shadow_texture_pz;
layout(r32ui) uniform readonly uimage2D shadow_texture_nz; layout(binding = 5, r32ui) uniform readonly uimage2D shadow_texture_nz;
layout(r32ui) uniform uimage2D shadow_buffer; layout(binding = 6, r32ui) uniform uimage2D shadow_buffer;
)"; )";
out += UniformBlockDef; out += UniformBlockDef;
@ -1773,7 +1773,7 @@ std::optional<ShaderDecompiler::ProgramResult> GenerateVertexShader(
out += R"( out += R"(
#define uniforms vs_uniforms #define uniforms vs_uniforms
layout (std140) uniform vs_config { layout (binding = 1, std140) uniform vs_config {
pica_uniforms uniforms; pica_uniforms uniforms;
}; };

View File

@ -87,72 +87,6 @@ static std::tuple<PicaVSConfig, Pica::Shader::ShaderSetup> BuildVSConfigFromRaw(
return {PicaVSConfig{raw.GetRawShaderConfig().vs, setup}, setup}; return {PicaVSConfig{raw.GetRawShaderConfig().vs, setup}, setup};
} }
static void SetShaderUniformBlockBinding(GLuint shader, const char* name,
Pica::Shader::UniformBindings binding,
std::size_t expected_size) {
const GLuint ub_index = glGetUniformBlockIndex(shader, name);
if (ub_index == GL_INVALID_INDEX) {
return;
}
GLint ub_size = 0;
glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size);
ASSERT_MSG(static_cast<std::size_t>(ub_size) == expected_size,
"Uniform block size did not match! Got {}, expected {}", static_cast<int>(ub_size),
expected_size);
glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding));
}
static void SetShaderUniformBlockBindings(GLuint shader) {
SetShaderUniformBlockBinding(shader, "shader_data", Pica::Shader::UniformBindings::Common,
sizeof(Pica::Shader::UniformData));
SetShaderUniformBlockBinding(shader, "vs_config", Pica::Shader::UniformBindings::VS,
sizeof(Pica::Shader::VSUniformData));
}
static void SetShaderSamplerBinding(GLuint shader, const char* name,
TextureUnits::TextureUnit binding) {
GLint uniform_tex = glGetUniformLocation(shader, name);
if (uniform_tex != -1) {
glUniform1i(uniform_tex, binding.id);
}
}
static void SetShaderImageBinding(GLuint shader, const char* name, GLuint binding) {
GLint uniform_tex = glGetUniformLocation(shader, name);
if (uniform_tex != -1) {
glUniform1i(uniform_tex, static_cast<GLint>(binding));
}
}
static void SetShaderSamplerBindings(GLuint shader) {
OpenGLState cur_state = OpenGLState::GetCurState();
GLuint old_program = std::exchange(cur_state.draw.shader_program, shader);
cur_state.Apply();
// Set the texture samplers to correspond to different texture units
SetShaderSamplerBinding(shader, "tex0", TextureUnits::PicaTexture(0));
SetShaderSamplerBinding(shader, "tex1", TextureUnits::PicaTexture(1));
SetShaderSamplerBinding(shader, "tex2", TextureUnits::PicaTexture(2));
SetShaderSamplerBinding(shader, "tex_cube", TextureUnits::TextureCube);
SetShaderSamplerBinding(shader, "tex_normal", TextureUnits::TextureNormalMap);
// Set the texture samplers to correspond to different lookup table texture units
SetShaderSamplerBinding(shader, "texture_buffer_lut_lf", TextureUnits::TextureBufferLUT_LF);
SetShaderSamplerBinding(shader, "texture_buffer_lut_rg", TextureUnits::TextureBufferLUT_RG);
SetShaderSamplerBinding(shader, "texture_buffer_lut_rgba", TextureUnits::TextureBufferLUT_RGBA);
SetShaderImageBinding(shader, "shadow_buffer", ImageUnits::ShadowBuffer);
SetShaderImageBinding(shader, "shadow_texture_px", ImageUnits::ShadowTexturePX);
SetShaderImageBinding(shader, "shadow_texture_nx", ImageUnits::ShadowTextureNX);
SetShaderImageBinding(shader, "shadow_texture_py", ImageUnits::ShadowTexturePY);
SetShaderImageBinding(shader, "shadow_texture_ny", ImageUnits::ShadowTextureNY);
SetShaderImageBinding(shader, "shadow_texture_pz", ImageUnits::ShadowTexturePZ);
SetShaderImageBinding(shader, "shadow_texture_nz", ImageUnits::ShadowTextureNZ);
cur_state.draw.shader_program = old_program;
cur_state.Apply();
}
/** /**
* An object representing a shader program staging. It can be either a shader object or a program * An object representing a shader program staging. It can be either a shader object or a program
* object, depending on whether separable program is used. * object, depending on whether separable program is used.
@ -175,11 +109,6 @@ public:
shader.Create(source, type); shader.Create(source, type);
OGLProgram& program = std::get<OGLProgram>(shader_or_program); OGLProgram& program = std::get<OGLProgram>(shader_or_program);
program.Create(true, std::array{shader.handle}); program.Create(true, std::array{shader.handle});
SetShaderUniformBlockBindings(program.handle);
if (type == GL_FRAGMENT_SHADER) {
SetShaderSamplerBindings(program.handle);
}
} }
} }
@ -192,8 +121,6 @@ public:
} }
void Inject(OGLProgram&& program) { void Inject(OGLProgram&& program) {
SetShaderUniformBlockBindings(program.handle);
SetShaderSamplerBindings(program.handle);
shader_or_program = std::move(program); shader_or_program = std::move(program);
} }
@ -455,9 +382,6 @@ void ShaderProgramManager::ApplyTo(OpenGLState& state) {
auto& disk_cache = impl->disk_cache; auto& disk_cache = impl->disk_cache;
disk_cache.SaveDumpToFile(unique_identifier, cached_program.handle, disk_cache.SaveDumpToFile(unique_identifier, cached_program.handle,
VideoCore::g_hw_shader_accurate_mul); VideoCore::g_hw_shader_accurate_mul);
SetShaderUniformBlockBindings(cached_program.handle);
SetShaderSamplerBindings(cached_program.handle);
} }
state.draw.shader_program = cached_program.handle; state.draw.shader_program = cached_program.handle;
} }
@ -586,8 +510,6 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading,
OGLProgram shader = OGLProgram shader =
GeneratePrecompiledProgram(dump.second, supported_formats, impl->separable); GeneratePrecompiledProgram(dump.second, supported_formats, impl->separable);
if (shader.handle != 0) { if (shader.handle != 0) {
SetShaderUniformBlockBindings(shader.handle);
SetShaderSamplerBindings(shader.handle);
impl->program_cache.emplace(unique_identifier, std::move(shader)); impl->program_cache.emplace(unique_identifier, std::move(shader));
} else { } else {
LOG_ERROR(Frontend, "Failed to link Precompiled program!"); LOG_ERROR(Frontend, "Failed to link Precompiled program!");

View File

@ -32,13 +32,13 @@ constexpr TextureUnit TextureColorBuffer{10};
} // namespace TextureUnits } // namespace TextureUnits
namespace ImageUnits { namespace ImageUnits {
constexpr GLuint ShadowBuffer = 0; constexpr GLuint ShadowTexturePX = 0;
constexpr GLuint ShadowTexturePX = 1; constexpr GLuint ShadowTextureNX = 1;
constexpr GLuint ShadowTextureNX = 2; constexpr GLuint ShadowTexturePY = 2;
constexpr GLuint ShadowTexturePY = 3; constexpr GLuint ShadowTextureNY = 3;
constexpr GLuint ShadowTextureNY = 4; constexpr GLuint ShadowTexturePZ = 4;
constexpr GLuint ShadowTexturePZ = 5; constexpr GLuint ShadowTextureNZ = 5;
constexpr GLuint ShadowTextureNZ = 6; constexpr GLuint ShadowBuffer = 6;
} // namespace ImageUnits } // namespace ImageUnits
class OpenGLState { class OpenGLState {