softgpu: Fix cull in throughmode.

Was only an issue for triangles used to draw rectangles, but caused our
test to fail.

Also move a test that was failing due to an outdated prx to passing.
This commit is contained in:
Unknown W. Brackets 2022-01-25 19:06:43 -08:00
parent 0e2f5d66b6
commit 61e30e8f8b
4 changed files with 20 additions and 23 deletions

View file

@ -436,17 +436,6 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, const TransformState
return vertex;
}
#define START_OPEN_U 1
#define END_OPEN_U 2
#define START_OPEN_V 4
#define END_OPEN_V 8
struct SplinePatch {
VertexData points[16];
int type;
int pad[3];
};
void TransformUnit::SetDirty(SoftDirty flags) {
binner_->SetDirty(flags);
}
@ -454,6 +443,12 @@ SoftDirty TransformUnit::GetDirty() {
return binner_->GetDirty();
}
enum class CullType {
CW,
CCW,
OFF,
};
void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine)
{
VertexDecoder &vdecoder = *drawEngine->FindVertexDecoder(vertex_type);
@ -509,6 +504,9 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
binner_->ClearDirty(SoftDirty::LIGHT_ALL | SoftDirty::TRANSFORM_ALL);
}
bool skipCull = !gstate.isCullEnabled() || gstate.isModeClear();
const CullType cullType = skipCull ? CullType::OFF : (gstate.getCullMode() ? CullType::CCW : CullType::CW);
bool outside_range_flag = false;
switch (prim_type) {
case GE_PRIM_POINTS:
@ -539,10 +537,10 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
switch (prim_type) {
case GE_PRIM_TRIANGLES:
{
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
if (cullType == CullType::OFF) {
Clipper::ProcessTriangle(data[0], data[1], data[2], data[2], *binner_);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[2], *binner_);
} else if (!gstate.getCullMode()) {
} else if (cullType == CullType::CW) {
Clipper::ProcessTriangle(data[2], data[1], data[0], data[2], *binner_);
} else {
Clipper::ProcessTriangle(data[0], data[1], data[2], data[2], *binner_);
@ -587,7 +585,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
}
}
if (data_index == 4 && gstate.isModeThrough()) {
if (data_index == 4 && gstate.isModeThrough() && cullType == CullType::OFF) {
if (Rasterizer::DetectRectangleSlices(data)) {
data[1] = data[3];
data_index = 2;
@ -644,7 +642,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()) {
if (data_index == 0 && vertex_count == 4 && gstate.isModeThrough() && cullType == CullType::OFF) {
for (int vtx = 0; vtx < 4; ++vtx) {
if (indices) {
vreader.Goto(ConvertIndex(vtx) - index_lower_bound);
@ -684,10 +682,10 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
continue;
}
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
if (cullType == CullType::OFF) {
Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index], *binner_);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], *binner_);
} else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) {
} else if ((!(int)cullType) ^ ((data_index - 1) % 2)) {
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], *binner_);
@ -721,7 +719,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
break;
}
if (data_index == 1 && vertex_count == 4 && gstate.isModeThrough()) {
if (data_index == 1 && vertex_count == 4 && gstate.isModeThrough() && cullType == CullType::OFF) {
for (int vtx = start_vtx; vtx < vertex_count; ++vtx) {
if (indices) {
vreader.Goto(ConvertIndex(vtx) - index_lower_bound);
@ -760,10 +758,10 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
continue;
}
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
if (cullType == CullType::OFF) {
Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index], *binner_);
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], *binner_);
} else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) {
} else if ((!(int)cullType) ^ ((data_index - 1) % 2)) {
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index], *binner_);

View file

@ -32,7 +32,6 @@ typedef Vec3<float> WorldCoords;
typedef Vec3<float> ViewCoords;
typedef Vec4<float> ClipCoords; // Range: -w <= x/y/z <= w
struct SplinePatch;
class BinManager;
struct TransformState;

@ -1 +1 @@
Subproject commit 8d7eac4f5a5e38f6fe43cfe7c49dd961a9f32244
Subproject commit 2351bb1abde22ea5d3e68d1f242dc947434e3753

View file

@ -138,6 +138,7 @@ tests_good = [
"gpu/commands/blend565",
"gpu/commands/blocktransfer",
"gpu/commands/material",
"gpu/displaylist/alignment",
"gpu/dither/dither",
"gpu/filtering/linear",
"gpu/filtering/mipmaplinear",
@ -380,7 +381,6 @@ tests_next = [
"gpu/commands/light",
"gpu/complex/complex",
"gpu/depth/precision",
"gpu/displaylist/alignment",
"gpu/displaylist/state",
"gpu/ge/break",
"gpu/ge/get",