mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-24 08:24:18 +00:00
renderer_gl: Use explicit bindings (#6940)
* renderer_gl: Use explicit bindings * gl_state: Match shadow order with vulkan
This commit is contained in:
parent
e2d8eef5fa
commit
928f352c94
3 changed files with 24 additions and 102 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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!");
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue