diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 5d02b0ca796a..c31683f53c38 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -292,6 +292,7 @@ void ComputeFragmentShaderID(FragmentShaderID *id) { bool enableAlphaDoubling = !alphaToColorDoubling && CanDoubleSrcBlendMode(); bool doTextureProjection = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX; bool doTextureAlpha = gstate.isTextureAlphaUsed(); + bool computeAbsdiff = gstate.getBlendEq() == GE_BLENDMODE_ABSDIFF; ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(); // All texfuncs except replace are the same for RGB as for RGBA with full alpha. @@ -326,11 +327,16 @@ void ComputeFragmentShaderID(FragmentShaderID *id) { // 3 bits id0 |= ReplaceAlphaWithStencilType() << 21; } + id0 |= (alphaTestAgainstZero & 1) << 24; if (enableAlphaTest) gpuStats.numAlphaTestedDraws++; else gpuStats.numNonAlphaTestedDraws++; + + if (computeAbsdiff) { + id0 |= (computeAbsdiff & 1) << 25; + } } id->d[0] = id0; @@ -407,6 +413,7 @@ void GenerateFragmentShader(char *buffer) { bool enableAlphaDoubling = !alphaToColorDoubling && CanDoubleSrcBlendMode(); bool doTextureProjection = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX; bool doTextureAlpha = gstate.isTextureAlphaUsed(); + bool computeAbsdiff = gstate.getBlendEq() == GE_BLENDMODE_ABSDIFF; ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(); if (gstate_c.textureFullAlpha && gstate.getTextureFunction() != GE_TEXFUNC_REPLACE) @@ -592,6 +599,11 @@ void GenerateFragmentShader(char *buffer) { } } + // Handle ABSDIFF blending mode using GL_EXT_shader_framebuffer_fetch + if (computeAbsdiff && gl_extensions.EXT_shader_framebuffer_fetch) { + WRITE(p, " gl_FragColor.rgb = abs(v.rgb - gl_LastFragData[0].rgb);\n"); + } + switch (stencilToAlpha) { case REPLACE_ALPHA_DUALSOURCE: WRITE(p, " fragColor0 = vec4(v.rgb, 0.0);\n"); diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 1378d7efb52c..179039094f67 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -325,7 +325,12 @@ void TransformDrawEngine::ApplyDrawState(int prim) { } if (((blendFuncEq >= GE_BLENDMODE_MIN) && gl_extensions.EXT_blend_minmax) || gl_extensions.GLES3) { - glstate.blendEquation.set(eqLookup[blendFuncEq]); + if (blendFuncEq == GE_BLENDMODE_ABSDIFF && gl_extensions.EXT_shader_framebuffer_fetch) { + // Handle GE_BLENDMODE_ABSDIFF in fragment shader and turn off regular alpha blending here. + glstate.blend.set(false); + } else { + glstate.blendEquation.set(eqLookup[blendFuncEq]); + } } else { glstate.blendEquation.set(eqLookupNoMinMax[blendFuncEq]); }