diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 600119321..d4a99f79f 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -144,12 +144,40 @@ static bool IsPassThroughTevStage(const TevStageConfig& stage) { stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1); } -static std::string TexCoord(const PicaShaderConfig& config, int texture_unit) { - if (texture_unit == 2 && config.state.texture2_use_coord1) { - return "texcoord[1]"; +static std::string SampleTexture(const PicaShaderConfig& config, unsigned texture_unit) { + const auto& state = config.state; + switch (texture_unit) { + case 0: + // Only unit 0 respects the texturing type + switch (state.texture0_type) { + case TexturingRegs::TextureConfig::Texture2D: + return "texture(tex[0], texcoord[0])"; + case TexturingRegs::TextureConfig::Projection2D: + return "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))"; + default: + LOG_CRITICAL(HW_GPU, "Unhandled texture type %x", + static_cast(state.texture0_type)); + UNIMPLEMENTED(); + return "texture(tex[0], texcoord[0])"; + } + case 1: + return "texture(tex[1], texcoord[1])"; + case 2: + if (state.texture2_use_coord1) + return "texture(tex[2], texcoord[1])"; + else + return "texture(tex[2], texcoord[2])"; + case 3: + if (state.proctex.enable) { + return "ProcTex()"; + } else { + LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it"); + return "vec4(0.0)"; + } + default: + UNREACHABLE(); + return ""; } - - return "texcoord[" + std::to_string(texture_unit) + "]"; } /// Writes the specified TEV stage source component(s) @@ -168,35 +196,16 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config, out += "secondary_fragment_color"; break; case Source::Texture0: - // Only unit 0 respects the texturing type (according to 3DBrew) - switch (state.texture0_type) { - case TexturingRegs::TextureConfig::Texture2D: - out += "texture(tex[0], texcoord[0])"; - break; - case TexturingRegs::TextureConfig::Projection2D: - out += "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))"; - break; - default: - out += "texture(tex[0], texcoord[0])"; - LOG_CRITICAL(HW_GPU, "Unhandled texture type %x", - static_cast(state.texture0_type)); - UNIMPLEMENTED(); - break; - } + out += SampleTexture(config, 0); break; case Source::Texture1: - out += "texture(tex[1], texcoord[1])"; + out += SampleTexture(config, 1); break; case Source::Texture2: - out += "texture(tex[2], " + TexCoord(config, 2) + ")"; + out += SampleTexture(config, 2); break; case Source::Texture3: - if (config.state.proctex.enable) { - out += "ProcTex()"; - } else { - LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it"); - out += "vec4(0.0)"; - } + out += SampleTexture(config, 3); break; case Source::PreviousBuffer: out += "combiner_buffer"; @@ -506,18 +515,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { if (lighting.bump_mode == LightingRegs::LightingBumpMode::NormalMap) { // Bump mapping is enabled using a normal map, read perturbation vector from the selected // texture - if (lighting.bump_selector == 3) { - if (config.state.proctex.enable) { - out += "vec3 surface_normal = 2.0 * ProcTex().rgb - 1.0;\n"; - } else { - LOG_ERROR(Render_OpenGL, "Using Texture3 without enabling it"); - out += "vec3 surface_normal = vec3(-1.0);\n"; - } - } else { - std::string bump_selector = std::to_string(lighting.bump_selector); - out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], " + - TexCoord(config, lighting.bump_selector) + ").rgb - 1.0;\n"; - } + out += "vec3 surface_normal = 2.0 * (" + SampleTexture(config, lighting.bump_selector) + + ").rgb - 1.0;\n"; // Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher // precision result