From 71edb55114af129d6f580e271ad5196043342abe Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 9 Oct 2015 19:32:38 -0400 Subject: [PATCH] gl_shader_gen: Require explicit uniform locations. - Fixes uniform issue on AMD. --- .../renderer_opengl/gl_rasterizer.cpp | 27 ++++--------- .../renderer_opengl/gl_rasterizer.h | 40 +++++++------------ .../renderer_opengl/gl_shader_gen.cpp | 25 ++++++------ 3 files changed, 35 insertions(+), 57 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 4f9865230..64639ed26 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -476,20 +476,14 @@ void RasterizerOpenGL::SetShader() { std::unique_ptr shader = Common::make_unique(); shader->shader.Create(GLShader::GenerateVertexShader().c_str(), GLShader::GenerateFragmentShader(config).c_str()); - shader->uniform_alphatest_ref = glGetUniformLocation(shader->shader.handle, "alphatest_ref"); - shader->uniform_tex = glGetUniformLocation(shader->shader.handle, "tex"); - shader->uniform_tev_combiner_buffer_color = glGetUniformLocation(shader->shader.handle, "tev_combiner_buffer_color"); - shader->uniform_tev_const_colors = glGetUniformLocation(shader->shader.handle, "const_color"); state.draw.shader_program = shader->shader.handle; state.Apply(); // Set the texture samplers to correspond to different texture units - if (shader->uniform_tex != -1) { - glUniform1i(shader->uniform_tex, 0); - glUniform1i(shader->uniform_tex + 1, 1); - glUniform1i(shader->uniform_tex + 2, 2); - } + glUniform1i(PicaShader::Uniform::Texture0, 0); + glUniform1i(PicaShader::Uniform::Texture1, 1); + glUniform1i(PicaShader::Uniform::Texture2, 2); current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); } @@ -622,8 +616,7 @@ void RasterizerOpenGL::SyncBlendColor() { void RasterizerOpenGL::SyncAlphaTest() { const auto& regs = Pica::g_state.regs; - if (current_shader->uniform_alphatest_ref != -1) - glUniform1i(current_shader->uniform_alphatest_ref, regs.output_merger.alpha_test.ref); + glUniform1i(PicaShader::Uniform::AlphaTestRef, regs.output_merger.alpha_test.ref); } void RasterizerOpenGL::SyncLogicOp() { @@ -654,17 +647,13 @@ void RasterizerOpenGL::SyncDepthTest() { } void RasterizerOpenGL::SyncCombinerColor() { - if (current_shader->uniform_tev_combiner_buffer_color != -1) { - auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); - glUniform4fv(current_shader->uniform_tev_combiner_buffer_color, 1, combiner_color.data()); - } + auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); + glUniform4fv(PicaShader::Uniform::TevCombinerBufferColor, 1, combiner_color.data()); } void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevStageConfig& tev_stage) { - if (current_shader->uniform_tev_const_colors != -1) { - auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); - glUniform4fv(current_shader->uniform_tev_const_colors + stage_index, 1, const_color.data()); - } + auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); + glUniform4fv(PicaShader::Uniform::TevConstColors + stage_index, 1, const_color.data()); } void RasterizerOpenGL::SyncDrawState() { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 484579d82..79c34944a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -153,36 +153,24 @@ public: /// Notify rasterizer that a 3DS memory region has been changed void NotifyFlush(PAddr addr, u32 size) override; -private: - /// Structure used for managing texture environment states - struct TEVConfigUniforms { - GLuint enabled; - GLuint color_sources; - GLuint alpha_sources; - GLuint color_modifiers; - GLuint alpha_modifiers; - GLuint color_alpha_op; - GLuint color_alpha_multiplier; - GLuint const_color; - GLuint updates_combiner_buffer_color_alpha; - }; - - struct TEVShader { + /// OpenGL shader generated for a given Pica register state + struct PicaShader { + /// OpenGL shader resource OGLShader shader; - // Hardware fragment shader - GLuint uniform_alphatest_ref; - GLuint uniform_tex; - GLuint uniform_tev_combiner_buffer_color; - GLuint uniform_tev_const_colors; - - TEVShader() = default; - TEVShader(TEVShader&& o) : shader(std::move(o.shader)), - uniform_alphatest_ref(o.uniform_alphatest_ref), uniform_tex(o.uniform_tex), - uniform_tev_combiner_buffer_color(o.uniform_tev_combiner_buffer_color), - uniform_tev_const_colors(o.uniform_tev_const_colors) {} + /// Fragment shader uniforms + enum Uniform : GLuint { + AlphaTestRef = 0, + TevConstColors = 1, + Texture0 = 7, + Texture1 = 8, + Texture2 = 9, + TevCombinerBufferColor = 10, + }; }; +private: + /// Structure used for storing information about color textures struct TextureInfo { OGLTexture texture; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 79c690e76..50bb2e3cc 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -321,25 +321,26 @@ static void WriteTevStage(std::string& out, const ShaderCacheKey& config, unsign std::string GenerateFragmentShader(const ShaderCacheKey& config) { std::string out = R"( -#version 150 core +#version 330 +#extension GL_ARB_explicit_uniform_location : require #define NUM_VTX_ATTR 7 #define NUM_TEV_STAGES 6 in vec4 attr[NUM_VTX_ATTR]; out vec4 color; - -uniform int alphatest_ref; -uniform vec4 const_color[NUM_TEV_STAGES]; -uniform sampler2D tex[3]; - -uniform vec4 tev_combiner_buffer_color; - -void main(void) { -vec4 g_combiner_buffer = tev_combiner_buffer_color; -vec4 g_last_tex_env_out = vec4(0.0, 0.0, 0.0, 0.0); )"; + using Uniform = RasterizerOpenGL::PicaShader::Uniform; + out += "layout(location = " + std::to_string(Uniform::AlphaTestRef) + ") uniform int alphatest_ref;\n"; + out += "layout(location = " + std::to_string(Uniform::TevConstColors) + ") uniform vec4 const_color[NUM_TEV_STAGES];\n"; + out += "layout(location = " + std::to_string(Uniform::Texture0) + ") uniform sampler2D tex[3];\n"; + out += "layout(location = " + std::to_string(Uniform::TevCombinerBufferColor) + ") uniform vec4 tev_combiner_buffer_color;\n"; + + out += "void main() {\n"; + out += "vec4 combiner_buffer = tev_combiner_buffer_color;\n"; + out += "vec4 last_tex_env_out = vec4(0.0);\n"; + // Do not do any sort of processing if it's obvious we're not going to pass the alpha test if (config.alpha_test_func == Regs::CompareFunc::Never) { out += "discard; }"; @@ -362,7 +363,7 @@ vec4 g_last_tex_env_out = vec4(0.0, 0.0, 0.0, 0.0); std::string GenerateVertexShader() { static const std::string out = R"( -#version 150 core +#version 330 #define NUM_VTX_ATTR 7