Skip to content

Commit

Permalink
softgpu: Combine tris to rects with ignored z too.
Browse files Browse the repository at this point in the history
  • Loading branch information
unknownbrackets committed Feb 12, 2022
1 parent 85cb410 commit 2381f35
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 28 deletions.
45 changes: 23 additions & 22 deletions GPU/Software/RasterizerRectangle.cpp
Expand Up @@ -306,22 +306,17 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1, BinManager &b
return false;
}

bool DetectRectangleFromThroughModeStrip(const VertexData data[4]) {
// We'll only do this when the color is flat.
if (!(data[0].color0 == data[1].color0))
return false;
if (!(data[1].color0 == data[2].color0))
return false;
if (!(data[2].color0 == data[3].color0))
return false;

// And the depth must also be flat.
if (!(data[0].screenpos.z == data[1].screenpos.z))
return false;
if (!(data[1].screenpos.z == data[2].screenpos.z))
return false;
if (!(data[2].screenpos.z == data[3].screenpos.z))
return false;
bool DetectRectangleFromThroughModeStrip(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))
return false;
if (!(data[i].screenpos.z == data[0].screenpos.z)) {
// Sometimes, we don't actually care about z.
if (state.pixelID.depthWrite || state.pixelID.DepthTestFunc() != GE_COMP_ALWAYS)
return false;
}
}

// OK, now let's look at data to detect rectangles. There are a few possibilities
// but we focus on Darkstalkers for now.
Expand Down Expand Up @@ -371,13 +366,16 @@ bool DetectRectangleFromThroughModeStrip(const VertexData data[4]) {
return false;
}

bool DetectRectangleFromThroughModeFan(const VertexData *data, int c, int *tlIndex, int *brIndex) {
bool DetectRectangleFromThroughModeFan(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))
return false;
if (!(data[i].screenpos.z == data[0].screenpos.z))
return false;
if (!(data[i].screenpos.z == data[0].screenpos.z)) {
// Sometimes, we don't actually care about z.
if (state.pixelID.depthWrite || state.pixelID.DepthTestFunc() != GE_COMP_ALWAYS)
return false;
}
}

// Check for the common case: a single TL-TR-BR-BL.
Expand Down Expand Up @@ -411,13 +409,16 @@ bool DetectRectangleFromThroughModeFan(const VertexData *data, int c, int *tlInd
return false;
}

bool DetectRectangleSlices(const VertexData data[4]) {
bool DetectRectangleSlices(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))
return false;
if (!(data[i].screenpos.z == data[0].screenpos.z))
return false;
if (!(data[i].screenpos.z == data[0].screenpos.z)) {
// Sometimes, we don't actually care about z.
if (state.pixelID.depthWrite || state.pixelID.DepthTestFunc() != GE_COMP_ALWAYS)
return false;
}
}

// Games very commonly use vertical strips of rectangles. Detect and combine.
Expand Down
6 changes: 3 additions & 3 deletions GPU/Software/RasterizerRectangle.h
Expand Up @@ -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 VertexData data[4]);
bool DetectRectangleFromThroughModeFan(const VertexData *data, int c, int *tlIndex, int *brIndex);
bool DetectRectangleSlices(const VertexData data[4]);
bool DetectRectangleFromThroughModeStrip(const RasterizerState &state, const VertexData data[4]);
bool DetectRectangleFromThroughModeFan(const RasterizerState &state, const VertexData *data, int c, int *tlIndex, int *brIndex);
bool DetectRectangleSlices(const RasterizerState &state, const VertexData data[4]);
}
6 changes: 3 additions & 3 deletions GPU/Software/TransformUnit.cpp
Expand Up @@ -593,7 +593,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
}

if (data_index == 4 && gstate.isModeThrough() && cullType == CullType::OFF) {
if (Rasterizer::DetectRectangleSlices(data)) {
if (Rasterizer::DetectRectangleSlices(binner_->State(), data)) {
data[1] = data[3];
data_index = 2;
}
Expand Down Expand Up @@ -661,7 +661,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
}

// If a strip is effectively a rectangle, draw it as such!
if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeStrip(data)) {
if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeStrip(binner_->State(), data)) {
Clipper::ProcessRect(data[0], data[3], *binner_);
break;
}
Expand Down Expand Up @@ -737,7 +737,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
}

int tl = -1, br = -1;
if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeFan(data, vertex_count, &tl, &br)) {
if (!outside_range_flag && Rasterizer::DetectRectangleFromThroughModeFan(binner_->State(), data, vertex_count, &tl, &br)) {
Clipper::ProcessRect(data[tl], data[br], *binner_);
break;
}
Expand Down

0 comments on commit 2381f35

Please sign in to comment.