Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement in-shader ABSDIFF blending mode #5859

Merged
merged 3 commits into from Apr 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions GPU/GLES/FragmentShaderGenerator.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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");
Expand Down
7 changes: 6 additions & 1 deletion GPU/GLES/StateMapping.cpp
Expand Up @@ -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]);
}
Expand Down