diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 9880fb1ee0..8fe1f13ec7 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -217,7 +217,7 @@ StencilValueType ReplaceAlphaWithStencilType() { return STENCIL_VALUE_KEEP; } -ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend) { +ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bufferFormat) { if (!gstate.isAlphaBlendEnabled() || gstate.isModeClear()) { return REPLACE_BLEND_NO; } @@ -256,6 +256,9 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend) { case GE_DSTBLEND_DOUBLEDSTALPHA: case GE_DSTBLEND_DOUBLEINVDSTALPHA: + if (bufferFormat == GE_FORMAT_565) { + return REPLACE_BLEND_2X_ALPHA; + } return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_DOUBLESRCALPHA: @@ -276,16 +279,30 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend) { switch (funcB) { case GE_DSTBLEND_SRCCOLOR: case GE_DSTBLEND_INVSRCCOLOR: + if (bufferFormat == GE_FORMAT_565) { + return REPLACE_BLEND_STANDARD; + } // Can't double, we need the source color to be correct. return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_DOUBLEDSTALPHA: case GE_DSTBLEND_DOUBLEINVDSTALPHA: + if (bufferFormat == GE_FORMAT_565) { + return REPLACE_BLEND_STANDARD; + } + return !allowShaderBlend ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO; + case GE_DSTBLEND_DOUBLESRCALPHA: case GE_DSTBLEND_DOUBLEINVSRCALPHA: + if (bufferFormat == GE_FORMAT_565) { + return REPLACE_BLEND_2X_ALPHA; + } return !allowShaderBlend ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO; default: + if (bufferFormat == GE_FORMAT_565) { + return REPLACE_BLEND_STANDARD; + } // We can't technically do this correctly (due to clamping) without reading the dst alpha. return !allowShaderBlend ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO; } @@ -299,6 +316,9 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend) { case GE_DSTBLEND_DOUBLEDSTALPHA: case GE_DSTBLEND_DOUBLEINVDSTALPHA: + if (bufferFormat == GE_FORMAT_565) { + return REPLACE_BLEND_STANDARD; + } return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; case GE_DSTBLEND_FIXB: @@ -335,6 +355,9 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend) { case GE_DSTBLEND_DOUBLEDSTALPHA: case GE_DSTBLEND_DOUBLEINVDSTALPHA: + if (bufferFormat == GE_FORMAT_565) { + return REPLACE_BLEND_STANDARD; + } return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO; default: diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index 595c8e1ae1..6acf4c7e36 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -1,5 +1,7 @@ #pragma once +#include "GPU/ge_constants.h" + enum StencilValueType { STENCIL_VALUE_UNIFORM, STENCIL_VALUE_ZERO, @@ -41,7 +43,7 @@ bool IsAlphaTestAgainstZero(); StencilValueType ReplaceAlphaWithStencilType(); ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend); -ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend); +ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bufferFormat); bool CanUseHardwareTransform(int prim); LogicOpReplaceType ReplaceLogicOpType(); diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index ecabfd848a..a528d3f983 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -209,7 +209,7 @@ void ComputeFragmentShaderID(ShaderID *id_out, uint32_t vertType) { bool doTextureAlpha = gstate.isTextureAlphaUsed(); bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT; - ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend); + ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend, gstate.FrameBufFormat()); ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(replaceBlend); // All texfuncs except replace are the same for RGB as for RGBA with full alpha. diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 91694b6563..5836cad112 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -282,7 +282,7 @@ void TransformDrawEngineDX9::ApplyBlendState() { // Unfortunately, we can't really do this in Direct3D 9... gstate_c.allowShaderBlend = false; - ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend); + ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend, gstate.FrameBufFormat()); ReplaceAlphaType replaceAlphaWithStencil = ReplaceAlphaWithStencil(replaceBlend); bool usePreSrc = false; diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index b0e1512556..0ec7fbd4f2 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -324,7 +324,7 @@ void TransformDrawEngine::ApplyBlendState() { // If we can't apply blending, we make a copy of the framebuffer and do it manually. gstate_c.allowShaderBlend = !g_Config.bDisableSlowFramebufEffects; - ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend); + ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend, gstate.FrameBufFormat()); ReplaceAlphaType replaceAlphaWithStencil = ReplaceAlphaWithStencil(replaceBlend); bool usePreSrc = false; @@ -406,6 +406,21 @@ void TransformDrawEngine::ApplyBlendState() { bool approxFuncB = false; GLuint glBlendFuncB = blendFuncB == GE_DSTBLEND_FIXB ? blendColor2Func(fixB, approxFuncB) : bLookup[blendFuncB]; + if (gstate.FrameBufFormat() == GE_FORMAT_565) { + if (blendFuncA == GE_SRCBLEND_DSTALPHA || blendFuncA == GE_SRCBLEND_DOUBLEDSTALPHA) { + glBlendFuncA = GL_ZERO; + } + if (blendFuncA == GE_SRCBLEND_INVDSTALPHA || blendFuncA == GE_SRCBLEND_DOUBLEINVDSTALPHA) { + glBlendFuncA = GL_ONE; + } + if (blendFuncB == GE_DSTBLEND_DSTALPHA || blendFuncB == GE_DSTBLEND_DOUBLEDSTALPHA) { + glBlendFuncB = GL_ZERO; + } + if (blendFuncB == GE_DSTBLEND_INVDSTALPHA || blendFuncB == GE_DSTBLEND_DOUBLEINVDSTALPHA) { + glBlendFuncB = GL_ONE; + } + } + if (usePreSrc) { glBlendFuncA = GL_ONE; // Need to pull in the fixed color.