From ce4fee737352f2d23122d5f269d306bf7d4a4a09 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 11 Sep 2022 21:14:47 -0700 Subject: [PATCH] softgpu: Refactor triangle cull processing. --- GPU/Software/TransformUnit.cpp | 54 ++++++++++++---------------------- GPU/Software/TransformUnit.h | 7 +++++ 2 files changed, 25 insertions(+), 36 deletions(-) diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 28a91a7a8c..aa31e3edf6 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -447,12 +447,6 @@ SoftDirty TransformUnit::GetDirty() { return binner_->GetDirty(); } -enum class CullType { - CW, - CCW, - OFF, -}; - void TransformUnit::SubmitPrimitive(const void* vertices, const void* indices, GEPrimitiveType prim_type, int vertex_count, u32 vertex_type, int *bytesRead, SoftwareDrawEngine *drawEngine) { VertexDecoder &vdecoder = *drawEngine->FindVertexDecoder(vertex_type); @@ -541,17 +535,8 @@ void TransformUnit::SubmitPrimitive(const void* vertices, const void* indices, G switch (prim_type) { case GE_PRIM_TRIANGLES: - { - 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 (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_); - } + SendTriangle(cullType, &data_[0]); break; - } case GE_PRIM_LINES: Clipper::ProcessLine(data_[0], data_[1], *binner_); @@ -688,16 +673,9 @@ void TransformUnit::SubmitPrimitive(const void* vertices, const void* indices, G continue; } - 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 ((!(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_); - } else { - Clipper::ProcessTriangle(data_[0], data_[1], data_[2], data_[provoking_index], *binner_); - } + int wind = (data_index_ - 1) % 2; + CullType altCullType = cullType == CullType::OFF ? cullType : CullType((int)cullType ^ wind); + SendTriangle(altCullType, &data_[0], provoking_index); } break; } @@ -764,16 +742,9 @@ void TransformUnit::SubmitPrimitive(const void* vertices, const void* indices, G continue; } - 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 ((!(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_); - } else { - Clipper::ProcessTriangle(data_[0], data_[1], data_[2], data_[provoking_index], *binner_); - } + int wind = (data_index_ - 1) % 2; + CullType altCullType = cullType == CullType::OFF ? cullType : CullType((int)cullType ^ wind); + SendTriangle(altCullType, &data_[0], provoking_index); } break; } @@ -784,6 +755,17 @@ void TransformUnit::SubmitPrimitive(const void* vertices, const void* indices, G } } +void TransformUnit::SendTriangle(CullType cullType, const VertexData *verts, int provoking) { + if (cullType == CullType::OFF) { + Clipper::ProcessTriangle(verts[0], verts[1], verts[2], verts[provoking], *binner_); + Clipper::ProcessTriangle(verts[2], verts[1], verts[0], verts[provoking], *binner_); + } else if (cullType == CullType::CW) { + Clipper::ProcessTriangle(verts[2], verts[1], verts[0], verts[provoking], *binner_); + } else { + Clipper::ProcessTriangle(verts[0], verts[1], verts[2], verts[provoking], *binner_); + } +} + void TransformUnit::Flush(const char *reason) { binner_->Flush(reason); GPUDebug::NotifyDraw(); diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index faa761639c..ec5883e8e2 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -37,6 +37,12 @@ typedef Vec4 ClipCoords; // Range: -w <= x/y/z <= w class BinManager; struct TransformState; +enum class CullType { + CW = 0, + CCW = 1, + OFF = 2, +}; + struct ScreenCoords { ScreenCoords() {} @@ -133,6 +139,7 @@ public: private: VertexData ReadVertex(VertexReader &vreader, const TransformState &lstate, bool &outside_range_flag); + void SendTriangle(CullType cullType, const VertexData *verts, int provoking = 2); u8 *decoded_ = nullptr; BinManager *binner_ = nullptr;