softgpu: Fix over-optimization of alpha test.

When alpha blend is off, was previously skipping the alpha test if only it
was enabled.  See #17213.
This commit is contained in:
Unknown W. Brackets committed 2023-03-31 23:53:37 -07:00
1 parent 2c5b0999e8
commit a88b8a14f6
1 file changed
+21 -16
+21 -16
View File
@@ -230,7 +230,7 @@ static inline Vec4IntResult SOFTRAST_CALL ModulateRGBA(Vec4IntArg prim_in, Vec4I
return ToVec4IntResult(out);
}
template <GEBufferFormat fmt, bool isWhite, bool alphaBlend>
template <GEBufferFormat fmt, bool isWhite, bool alphaBlend, bool alphaTestZero>
static void DrawSpriteTex(const DrawingCoords &pos0, const DrawingCoords &pos1, int s_start, int t_start, int ds, int dt, u32 color0, const RasterizerState &state, Sampler::FetchFunc fetchFunc) {
const u8 *texptr = state.texptr[0];
uint16_t texbufw = state.texbufw[0];
@@ -244,7 +244,7 @@ static void DrawSpriteTex(const DrawingCoords &pos0, const DrawingCoords &pos1,
for (int x = pos0.x; x < pos1.x; x++) {
Vec4<int> tex_color = fetchFunc(s, t, texptr, texbufw, 0, state.samplerID);
if (isWhite) {
if (!alphaBlend || tex_color.a() != 0) {
if (!alphaTestZero || tex_color.a() != 0) {
u32 tex_color32 = tex_color.ToRGBA();
if (fmt == GE_FORMAT_8888)
DrawSinglePixel32<alphaBlend>(pixel32, tex_color32);
@@ -254,7 +254,7 @@ static void DrawSpriteTex(const DrawingCoords &pos0, const DrawingCoords &pos1,
} else {
Vec4<int> prim_color = c0;
prim_color = Vec4<int>(ModulateRGBA(ToVec4IntArg(prim_color), ToVec4IntArg(tex_color), state.samplerID));
if (!alphaBlend || prim_color.a() > 0) {
if (!alphaTestZero || prim_color.a() > 0) {
if (fmt == GE_FORMAT_8888)
DrawSinglePixel32<alphaBlend>(pixel32, prim_color.ToRGBA());
else
@@ -271,20 +271,20 @@ static void DrawSpriteTex(const DrawingCoords &pos0, const DrawingCoords &pos1,
}
}
template <bool isWhite, bool alphaBlend>
template <bool isWhite, bool alphaBlend, bool alphaTestZero>
static void DrawSpriteTex(const DrawingCoords &pos0, const DrawingCoords &pos1, int s_start, int t_start, int ds, int dt, u32 color0, const RasterizerState &state, Sampler::FetchFunc fetchFunc) {
switch (state.pixelID.FBFormat()) {
case GE_FORMAT_565:
DrawSpriteTex<GE_FORMAT_565, isWhite, alphaBlend>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
DrawSpriteTex<GE_FORMAT_565, isWhite, alphaBlend, alphaTestZero>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
break;
case GE_FORMAT_5551:
DrawSpriteTex<GE_FORMAT_5551, isWhite, alphaBlend>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
DrawSpriteTex<GE_FORMAT_5551, isWhite, alphaBlend, alphaTestZero>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
break;
case GE_FORMAT_4444:
DrawSpriteTex<GE_FORMAT_4444, isWhite, alphaBlend>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
DrawSpriteTex<GE_FORMAT_4444, isWhite, alphaBlend, alphaTestZero>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
break;
case GE_FORMAT_8888:
DrawSpriteTex<GE_FORMAT_8888, isWhite, alphaBlend>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
DrawSpriteTex<GE_FORMAT_8888, isWhite, alphaBlend, alphaTestZero>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
break;
default:
// Invalid, don't draw anything...
@@ -292,6 +292,17 @@ static void DrawSpriteTex(const DrawingCoords &pos0, const DrawingCoords &pos1,
}
}
template <bool isWhite>
static inline void DrawSpriteTex(const DrawingCoords &pos0, const DrawingCoords &pos1, int s_start, int t_start, int ds, int dt, u32 color0, const RasterizerState &state, Sampler::FetchFunc fetchFunc) {
// Standard alpha blending implies skipping alpha zero.
if (state.pixelID.alphaBlend)
DrawSpriteTex<isWhite, true, true>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
else if (state.pixelID.AlphaTestFunc() != GE_COMP_ALWAYS)
DrawSpriteTex<isWhite, false, true>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
else
DrawSpriteTex<isWhite, false, false>(pos0, pos1, s_start, t_start, ds, dt, color0, state, fetchFunc);
}
template <GEBufferFormat fmt, bool alphaBlend>
static void DrawSpriteNoTex(const DrawingCoords &pos0, const DrawingCoords &pos1, u32 color0, const RasterizerState &state) {
if (alphaBlend && Vec4<int>::FromRGBA(color0).a() == 0)
@@ -392,15 +403,9 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran
if (UseDrawSinglePixel(pixelID) && (samplerID.TexFunc() == GE_TEXFUNC_MODULATE || samplerID.TexFunc() == GE_TEXFUNC_REPLACE) && samplerID.useTextureAlpha) {
if (isWhite || samplerID.TexFunc() == GE_TEXFUNC_REPLACE) {
if (pixelID.alphaBlend)
DrawSpriteTex<true, true>(pos0, pos1, s_start, t_start, ds, dt, v1.color0, state, fetchFunc);
else
DrawSpriteTex<true, false>(pos0, pos1, s_start, t_start, ds, dt, v1.color0, state, fetchFunc);
DrawSpriteTex<true>(pos0, pos1, s_start, t_start, ds, dt, v1.color0, state, fetchFunc);
} else {
if (pixelID.alphaBlend)
DrawSpriteTex<false, true>(pos0, pos1, s_start, t_start, ds, dt, v1.color0, state, fetchFunc);
else
DrawSpriteTex<false, false>(pos0, pos1, s_start, t_start, ds, dt, v1.color0, state, fetchFunc);
DrawSpriteTex<false>(pos0, pos1, s_start, t_start, ds, dt, v1.color0, state, fetchFunc);
}
} else {
float dsf = ds * (1.0f / (float)(1 << state.samplerID.width0Shift));