From 7dfe8b58dc3211c581d2839104010b37ab3c49ca Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 5 Mar 2016 13:12:24 -0800 Subject: [PATCH 1/2] Clear attrMask on bad shader compile. This prevents various crashes when incorrect attributes are enabled. --- GPU/GLES/ShaderManager.cpp | 3 +++ GPU/GLES/TransformPipeline.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index fab370a0d7..82fdcdd654 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -156,6 +156,9 @@ LinkedShader::LinkedShader(ShaderID VSID, Shader *vs, ShaderID FSID, Shader *fs, } // Prevent a buffer overflow. numBones = 0; + // Avoid weird attribute enables. + attrMask = 0; + availableUniforms = 0; return; } diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 7d2fcfc712..7ef3f0d08d 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -247,7 +247,7 @@ static const GlTypeInfo GLComp[] = { }; static inline void VertexAttribSetup(int attrib, int fmt, int stride, u8 *ptr) { - if (attrib != -1 && fmt) { + if (fmt) { const GlTypeInfo &type = GLComp[fmt]; glVertexAttribPointer(attrib, type.count, type.type, type.normalized, stride, ptr); } From 212848c1ccbe978a223da351c9b17a362e452c0d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 5 Mar 2016 13:27:27 -0800 Subject: [PATCH 2/2] Explicitly enable dual source blending in shader. Without this, the shader fails to compile on SHIELD devices with up-to-date drivers. It may have also been failing on other devices. The specification notes that the #extension line must be used. --- GPU/GLES/FragmentShaderGenerator.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 2959a65c1e..87c6a644dc 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -60,6 +60,8 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { bool bitwiseOps = false; const char *lastFragData = nullptr; + ReplaceAlphaType stencilToAlpha = static_cast(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2)); + if (gl_extensions.IsGLES) { // ES doesn't support dual source alpha :( if (gstate_c.featureFlags & GPU_SUPPORTS_GLSL_ES_300) { @@ -69,6 +71,10 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { glslES30 = true; bitwiseOps = true; texelFetch = "texelFetch"; + + if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE && gl_extensions.EXT_blend_func_extended) { + WRITE(p, "#extension GL_EXT_blend_func_extended : require\n"); + } } else { WRITE(p, "#version 100\n"); // GLSL ES 1.0 if (gl_extensions.EXT_gpu_shader4) { @@ -79,6 +85,10 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { if (gl_extensions.EXT_blend_func_extended) { // Oldy moldy GLES, so use the fixed output name. fragColor1 = "gl_SecondaryFragColorEXT"; + + if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE && gl_extensions.EXT_blend_func_extended) { + WRITE(p, "#extension GL_EXT_blend_func_extended : require\n"); + } } } @@ -164,7 +174,6 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) { bool textureAtOffset = id.Bit(FS_BIT_TEXTURE_AT_OFFSET); ReplaceBlendType replaceBlend = static_cast(id.Bits(FS_BIT_REPLACE_BLEND, 3)); - ReplaceAlphaType stencilToAlpha = static_cast(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2)); GEBlendSrcFactor replaceBlendFuncA = (GEBlendSrcFactor)id.Bits(FS_BIT_BLENDFUNC_A, 4); GEBlendDstFactor replaceBlendFuncB = (GEBlendDstFactor)id.Bits(FS_BIT_BLENDFUNC_B, 4);