Merge branch 'hrydgard:master' into hotfix_openxr_glitches

This commit is contained in:
Luboš Vonásek authored and GitHub committed 2023-04-01 20:17:25 +02:00
commit de089c3fee
3 files changed
+33 -21

No files matched your search

+22 -18
View File
@@ -101,7 +101,6 @@ template <GEBufferFormat fmt, bool alphaBlend>
static inline void DrawSinglePixel(u16 *pixel, const u32 color_in) {
u32 new_color;
// Because of this check, we only support src.a / 1-src.a blending.
// We take advantage of short circuiting by checking the constant (template) value first.
if (!alphaBlend || (color_in >> 24) == 255) {
new_color = color_in & 0xFFFFFF;
} else {
@@ -142,7 +141,7 @@ template <bool alphaBlend>
static inline void DrawSinglePixel32(u32 *pixel, const u32 color_in) {
u32 new_color;
// Because of this check, we only support src.a / 1-src.a blending.
if ((color_in >> 24) == 255 || !alphaBlend) {
if (!alphaBlend || (color_in >> 24) == 255) {
new_color = color_in & 0xFFFFFF;
} else {
const u32 old_color = *pixel;
@@ -231,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];
@@ -245,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);
@@ -255,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
@@ -272,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...
@@ -293,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)
@@ -393,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));
+9 -3
View File
@@ -42,14 +42,20 @@ void HeadlessHost::SendDebugScreenshot(const u8 *pixbuf, u32 w, u32 h) {
ScreenshotComparer comparer(pixels, FRAME_STRIDE, FRAME_WIDTH, FRAME_HEIGHT);
double errors = comparer.Compare(comparisonScreenshot_);
if (errors < 0)
SendDebugOutput(comparer.GetError() + "\n");
SendAndCollectOutput(comparer.GetError() + "\n");
if (errors > maxScreenshotError_)
SendDebugOutput(StringFromFormat("Screenshot MSE: %f\n", errors));
SendAndCollectOutput(StringFromFormat("Screenshot MSE: %f\n", errors));
if (errors > maxScreenshotError_ && writeFailureScreenshot_) {
if (comparer.SaveActualBitmap(Path("__testfailure.bmp")))
SendDebugOutput("Actual output written to: __testfailure.bmp\n");
SendAndCollectOutput("Actual output written to: __testfailure.bmp\n");
comparer.SaveVisualComparisonPNG(Path("__testcompare.png"));
}
}
void HeadlessHost::SendAndCollectOutput(const std::string &output) {
SendDebugOutput(output);
if (PSP_CoreParameter().collectDebugOutput)
*PSP_CoreParameter().collectDebugOutput += output;
}
+2
View File
@@ -62,6 +62,8 @@ public:
virtual void SwapBuffers() {}
protected:
void SendAndCollectOutput(const std::string &output);
Path comparisonScreenshot_;
double maxScreenshotError_ = 0.0;
std::string debugOutputBuffer_;