From 3d4c1548b63eeb81ca44cbd8c11a1892dbc91708 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 9 Feb 2022 19:04:12 -0800 Subject: [PATCH] softgpu: Allow tri -> rect in transform. --- GPU/Software/RasterizerRectangle.cpp | 24 +++++++++++++++++++++--- GPU/Software/RasterizerRectangle.h | 6 +++--- GPU/Software/TransformUnit.cpp | 10 +++++----- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index ae9e920ff0..336d62474e 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -306,7 +306,7 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1, BinManager &b return false; } -bool DetectRectangleFromThroughModeStrip(const RasterizerState &state, const VertexData data[4], int *tlIndex, int *brIndex) { +bool DetectRectangleFromStrip(const RasterizerState &state, const VertexData data[4], int *tlIndex, int *brIndex) { // Color and Z must be flat. Also find the TL and BR meanwhile. int tl = 0, br = 0; for (int i = 1; i < 4; ++i) { @@ -317,6 +317,15 @@ bool DetectRectangleFromThroughModeStrip(const RasterizerState &state, const Ver if (state.pixelID.depthWrite || state.pixelID.DepthTestFunc() != GE_COMP_ALWAYS) return false; } + if (!state.throughMode) { + if (!state.throughMode && !(data[i].color1 == data[0].color1)) + return false; + // Do we have to think about perspective correction or slope mip level? + if (state.enableTextures && data[i].clippos.w != data[0].clippos.w) + return false; + if (state.pixelID.applyFog && data[i].fogdepth != data[0].fogdepth) + return false; + } if (data[i].screenpos.x <= data[tl].screenpos.x && data[i].screenpos.y <= data[tl].screenpos.y) tl = i; @@ -367,7 +376,7 @@ bool DetectRectangleFromThroughModeStrip(const RasterizerState &state, const Ver return false; } -bool DetectRectangleFromThroughModeFan(const RasterizerState &state, const VertexData *data, int c, int *tlIndex, int *brIndex) { +bool DetectRectangleFromFan(const RasterizerState &state, const VertexData *data, int c, int *tlIndex, int *brIndex) { // Color and Z must be flat. for (int i = 1; i < c; ++i) { if (!(data[i].color0 == data[0].color0)) @@ -377,6 +386,15 @@ bool DetectRectangleFromThroughModeFan(const RasterizerState &state, const Verte if (state.pixelID.depthWrite || state.pixelID.DepthTestFunc() != GE_COMP_ALWAYS) return false; } + if (!state.throughMode) { + if (!state.throughMode && !(data[i].color1 == data[0].color1)) + return false; + // Do we have to think about perspective correction or slope mip level? + if (state.enableTextures && data[i].clippos.w != data[0].clippos.w) + return false; + if (state.pixelID.applyFog && data[i].fogdepth != data[0].fogdepth) + return false; + } } // Check for the common case: a single TL-TR-BR-BL. @@ -410,7 +428,7 @@ bool DetectRectangleFromThroughModeFan(const RasterizerState &state, const Verte return false; } -bool DetectRectangleSlices(const RasterizerState &state, const VertexData data[4]) { +bool DetectRectangleThroughModeSlices(const RasterizerState &state, const VertexData data[4]) { // Color and Z must be flat. for (int i = 1; i < 4; ++i) { if (!(data[i].color0 == data[0].color0)) diff --git a/GPU/Software/RasterizerRectangle.h b/GPU/Software/RasterizerRectangle.h index 8d94cff536..4407b10a01 100644 --- a/GPU/Software/RasterizerRectangle.h +++ b/GPU/Software/RasterizerRectangle.h @@ -20,7 +20,7 @@ namespace Rasterizer { bool RectangleFastPath(const VertexData &v0, const VertexData &v1, BinManager &binner); void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &range, const RasterizerState &state); - bool DetectRectangleFromThroughModeStrip(const RasterizerState &state, const VertexData data[4], int *tlIndex, int *brIndex); - bool DetectRectangleFromThroughModeFan(const RasterizerState &state, const VertexData *data, int c, int *tlIndex, int *brIndex); - bool DetectRectangleSlices(const RasterizerState &state, const VertexData data[4]); + bool DetectRectangleFromStrip(const RasterizerState &state, const VertexData data[4], int *tlIndex, int *brIndex); + bool DetectRectangleFromFan(const RasterizerState &state, const VertexData *data, int c, int *tlIndex, int *brIndex); + bool DetectRectangleThroughModeSlices(const RasterizerState &state, const VertexData data[4]); } diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 6ea3060d7e..a548bdb6b5 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -593,7 +593,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy } if (data_index == 4 && gstate.isModeThrough() && cullType == CullType::OFF) { - if (Rasterizer::DetectRectangleSlices(binner_->State(), data)) { + if (Rasterizer::DetectRectangleThroughModeSlices(binner_->State(), data)) { data[1] = data[3]; data_index = 2; } @@ -649,7 +649,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy // If index count == 4, check if we can convert to a rectangle. // This is for Darkstalkers (and should speed up many 2D games). - if (data_index == 0 && vertex_count == 4 && gstate.isModeThrough() && cullType == CullType::OFF) { + if (data_index == 0 && vertex_count == 4 && cullType == CullType::OFF) { for (int vtx = 0; vtx < 4; ++vtx) { if (indices) { vreader.Goto(ConvertIndex(vtx) - index_lower_bound); @@ -662,7 +662,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy // If a strip is effectively a rectangle, draw it as such! int tl = -1, br = -1; - if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeStrip(binner_->State(), data, &tl, &br)) { + if (!outside_range_flag && Rasterizer::DetectRectangleFromStrip(binner_->State(), data, &tl, &br)) { Clipper::ProcessRect(data[tl], data[br], *binner_); break; } @@ -727,7 +727,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy break; } - if (data_index == 1 && vertex_count == 4 && gstate.isModeThrough() && cullType == CullType::OFF) { + if (data_index == 1 && vertex_count == 4 && cullType == CullType::OFF) { for (int vtx = start_vtx; vtx < vertex_count; ++vtx) { if (indices) { vreader.Goto(ConvertIndex(vtx) - index_lower_bound); @@ -738,7 +738,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy } int tl = -1, br = -1; - if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeFan(binner_->State(), data, vertex_count, &tl, &br)) { + if (!outside_range_flag && Rasterizer::DetectRectangleFromFan(binner_->State(), data, vertex_count, &tl, &br)) { Clipper::ProcessRect(data[tl], data[br], *binner_); break; }