Treat invalid blend factors as fixed consistently.

This commit is contained in:
Unknown W. Brackets 2015-11-19 06:48:06 -08:00
parent 63769a2383
commit c22953a4b9
4 changed files with 27 additions and 12 deletions

@ -145,6 +145,11 @@ const bool nonAlphaSrcFactors[16] = {
true, // GE_SRCBLEND_DOUBLEDSTALPHA,
true, // GE_SRCBLEND_DOUBLEINVDSTALPHA,
true, // GE_SRCBLEND_FIXA,
true,
true,
true,
true,
true,
};
const bool nonAlphaDestFactors[16] = {
@ -159,6 +164,11 @@ const bool nonAlphaDestFactors[16] = {
true, // GE_DSTBLEND_DOUBLEDSTALPHA,
true, // GE_DSTBLEND_DOUBLEINVDSTALPHA,
true, // GE_DSTBLEND_FIXB,
true,
true,
true,
true,
true,
};
ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend) {
@ -302,6 +312,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
case GE_DSTBLEND_DSTALPHA:
case GE_DSTBLEND_INVDSTALPHA:
case GE_DSTBLEND_FIXB:
default:
// TODO: Could use vertexFullAlpha, but it's not calculated yet.
// This outputs the original alpha for the dest factor.
return REPLACE_BLEND_PRE_SRC;
@ -341,6 +352,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
case GE_DSTBLEND_DSTALPHA:
case GE_DSTBLEND_INVDSTALPHA:
case GE_DSTBLEND_FIXB:
default:
if (bufferFormat == GE_FORMAT_565) {
return REPLACE_BLEND_STANDARD;
}
@ -373,6 +385,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
case GE_DSTBLEND_DSTALPHA:
case GE_DSTBLEND_INVDSTALPHA:
case GE_DSTBLEND_FIXB:
default:
if (bufferFormat == GE_FORMAT_565) {
return REPLACE_BLEND_STANDARD;
}
@ -380,6 +393,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
}
case GE_SRCBLEND_FIXA:
default:
switch (funcB) {
case GE_DSTBLEND_DOUBLESRCALPHA:
// Can't safely double alpha, will clamp.
@ -397,6 +411,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
case GE_DSTBLEND_FIXB:
default:
if (gstate.getFixA() == 0xFFFFFF && gstate.getFixB() == 0x000000) {
// Some games specify this. Some cards may prefer blending off entirely.
return REPLACE_BLEND_NO;

@ -75,10 +75,10 @@ bool GenerateFragmentShaderDX9(const ShaderID &id, char *buffer) {
WRITE(p, "float2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE);
WRITE(p, "sampler fbotex : register(s1);\n");
}
if (replaceBlendFuncA == GE_SRCBLEND_FIXA) {
if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) {
WRITE(p, "float3 u_blendFixA : register(c%i);\n", CONST_PS_BLENDFIXA);
}
if (replaceBlendFuncB == GE_DSTBLEND_FIXB) {
if (replaceBlendFuncB >= GE_DSTBLEND_FIXB) {
WRITE(p, "float3 u_blendFixB : register(c%i);\n", CONST_PS_BLENDFIXB);
}
}
@ -305,6 +305,7 @@ bool GenerateFragmentShaderDX9(const ShaderID &id, char *buffer) {
case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "float3(2.0, 2.0, 2.0)"; break;
case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "ERROR"; break;
case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break;
default: srcFactor = "u_blendFixA"; break;
}
WRITE(p, " v.rgb = v.rgb * %s;\n", srcFactor);

@ -178,10 +178,10 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) {
}
WRITE(p, "uniform sampler2D fbotex;\n");
}
if (replaceBlendFuncA == GE_SRCBLEND_FIXA) {
if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) {
WRITE(p, "uniform vec3 u_blendFixA;\n");
}
if (replaceBlendFuncB == GE_DSTBLEND_FIXB) {
if (replaceBlendFuncB >= GE_DSTBLEND_FIXB) {
WRITE(p, "uniform vec3 u_blendFixB;\n");
}
}
@ -502,6 +502,7 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) {
case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "vec3(2.0)"; break;
case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "ERROR"; break;
case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break;
default: srcFactor = "u_blendFixA"; break;
}
WRITE(p, " v.rgb = v.rgb * %s;\n", srcFactor);
@ -533,6 +534,7 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) {
case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "vec3(destColor.a * 2.0)"; break;
case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "vec3(1.0 - destColor.a * 2.0)"; break;
case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break;
default: srcFactor = "u_blendFixA"; break;
}
switch (replaceBlendFuncB) {
case GE_DSTBLEND_SRCCOLOR: dstFactor = "v.rgb"; break;
@ -546,6 +548,7 @@ bool GenerateFragmentShader(const ShaderID &id, char *buffer) {
case GE_DSTBLEND_DOUBLEDSTALPHA: dstFactor = "vec3(destColor.a * 2.0)"; break;
case GE_DSTBLEND_DOUBLEINVDSTALPHA: dstFactor = "vec3(1.0 - destColor.a * 2.0)"; break;
case GE_DSTBLEND_FIXB: dstFactor = "u_blendFixB"; break;
default: srcFactor = "u_blendFixB"; break;
}
switch (replaceBlendEq) {

@ -840,11 +840,9 @@ static inline Vec3<int> GetSourceFactor(const Vec4<int>& source, const Vec4<int>
return Vec3<int>::AssignToAll(255 - 2 * dst.a());
case GE_SRCBLEND_FIXA:
return Vec3<int>::FromRGB(gstate.getFixA());
default:
ERROR_LOG_REPORT(G3D, "Software: Unknown source factor %x", gstate.getBlendFuncA());
return Vec3<int>();
// All other dest factors (> 10) are treated as FIXA.
return Vec3<int>::FromRGB(gstate.getFixA());
}
}
@ -890,11 +888,9 @@ static inline Vec3<int> GetDestFactor(const Vec4<int>& source, const Vec4<int>&
return Vec3<int>::AssignToAll(255 - 2 * dst.a());
case GE_DSTBLEND_FIXB:
return Vec3<int>::FromRGB(gstate.getFixB());
default:
ERROR_LOG_REPORT(G3D, "Software: Unknown dest factor %x", gstate.getBlendFuncB());
return Vec3<int>();
// All other dest factors (> 10) are treated as FIXB.
return Vec3<int>::FromRGB(gstate.getFixB());
}
}