mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
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:
1 parent
2c5b0999e8
commit
a88b8a14f6
1 file changed
+21
-16
@@ -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));
|
||||
|
||||
Reference in new issue
Block a user