diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 1a72aaf52f..cbc231608e 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -184,7 +184,9 @@ void DrawEngineCommon::DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex int bytesRead; uint32_t vertTypeID = GetVertTypeID(vtype, 0, decOptions_.applySkinInDecode); - SubmitPrim(&temp[0], nullptr, prim, vertexCount, vertTypeID, cullMode, &bytesRead); + + bool clockwise = !gstate.isCullEnabled() || gstate.getCullMode() == cullMode; + SubmitPrim(&temp[0], nullptr, prim, vertexCount, vertTypeID, clockwise, &bytesRead); DispatchFlush(); if (!prevThrough) { @@ -681,7 +683,7 @@ uint64_t DrawEngineCommon::ComputeHash() { return fullhash; } -int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t *stall, u32 vertTypeID, int cullMode, int *bytesRead, bool isTriangle) { +int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t *stall, u32 vertTypeID, bool clockwise, int *bytesRead, bool isTriangle) { const uint32_t *start = cmd; int prevDrawVerts = numDrawVerts_ - 1; DeferredVerts &dv = drawVerts_[prevDrawVerts]; @@ -705,7 +707,7 @@ int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t * DeferredInds &di = drawInds_[numDrawInds_++]; di.indexType = 0; di.prim = newPrim; - di.cullMode = cullMode; + di.clockwise = clockwise; di.vertexCount = vertexCount; di.vertDecodeIndex = prevDrawVerts; di.offset = offset; @@ -722,7 +724,7 @@ int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t * } // vertTypeID is the vertex type but with the UVGen mode smashed into the top bits. -bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { +bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, bool clockwise, int *bytesRead) { if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawVerts_ >= MAX_DEFERRED_DRAW_VERTS || numDrawInds_ >= MAX_DEFERRED_DRAW_INDS || vertexCountInDrawCalls_ + vertexCount > VERTEX_BUFFER_MAX) { DispatchFlush(); } @@ -758,7 +760,7 @@ bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti di.inds = inds; di.indexType = (vertTypeID & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT; di.prim = prim; - di.cullMode = cullMode; + di.clockwise = clockwise; di.vertexCount = vertexCount; di.vertDecodeIndex = numDrawVerts_; di.offset = 0; @@ -824,10 +826,7 @@ void DrawEngineCommon::DecodeInds() { const DeferredInds &di = drawInds_[i]; int indexOffset = drawVertexOffsets_[di.vertDecodeIndex] + di.offset; - bool clockwise = true; - if (gstate.isCullEnabled() && gstate.getCullMode() != di.cullMode) { - clockwise = false; - } + bool clockwise = di.clockwise; // We've already collapsed subsequent draws with the same vertex pointer, so no tricky logic here anymore. // 2. Loop through the drawcalls, translating indices as we go. switch (di.indexType) { diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index a10e9f1cde..5827c958f4 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -96,8 +96,8 @@ public: // This would seem to be unnecessary now, but is still required for splines/beziers to work in the software backend since SubmitPrim // is different. Should probably refactor that. // Note that vertTypeID should be computed using GetVertTypeID(). - virtual void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { - SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, cullMode, bytesRead); + virtual void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, bool clockwise, int *bytesRead) { + SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, clockwise, bytesRead); } virtual void DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex *buffer, int vertexCount, int cullMode, bool continuation); @@ -111,8 +111,8 @@ public: } } - int ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t *stall, u32 vertTypeID, int cullMode, int *bytesRead, bool isTriangle); - bool SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead); + int ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t *stall, u32 vertTypeID, bool clockwise, int *bytesRead, bool isTriangle); + bool SubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, bool clockwise, int *bytesRead); template void SubmitCurve(const void *control_points, const void *indices, Surface &surface, u32 vertType, int *bytesRead, const char *scope); void ClearSplineBezierWeights(); @@ -257,7 +257,7 @@ protected: u8 vertDecodeIndex; // index into the drawVerts_ array to look up the vertexOffset. u8 indexType; s8 prim; - u8 cullMode; + bool clockwise; u16 offset; }; diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index eeb2c73367..69c80d1c02 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -577,7 +577,7 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode(), decOptions_.applySkinInDecode); int generatedBytesRead; if (output.count) - DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, gstate.getCullMode(), &generatedBytesRead); + DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, true, &generatedBytesRead); if (flushOnParams_) DispatchFlush(); diff --git a/GPU/GPUCommonHW.cpp b/GPU/GPUCommonHW.cpp index 5f3709783f..b08839ac77 100644 --- a/GPU/GPUCommonHW.cpp +++ b/GPU/GPUCommonHW.cpp @@ -989,7 +989,7 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) { int cullMode = gstate.getCullMode(); uint32_t vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode(), g_Config.bSoftwareSkinning); - if (!drawEngineCommon_->SubmitPrim(verts, inds, prim, count, vertTypeID, cullMode, &bytesRead)) { + if (!drawEngineCommon_->SubmitPrim(verts, inds, prim, count, vertTypeID, true, &bytesRead)) { canExtend = false; } // After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed). @@ -1024,11 +1024,12 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) { // TODO: more efficient updating of verts/inds u32 count = data & 0xFFFF; + bool clockwise = !gstate.isCullEnabled() || gstate.getCullMode() == cullMode; if (canExtend) { // Non-indexed draws can be cheaply merged if vertexAddr hasn't changed, that means the vertices // are consecutive in memory. _dbg_assert_((vertexType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_NONE); - int commandsExecuted = drawEngineCommon_->ExtendNonIndexedPrim(src, stall, vertTypeID, cullMode, &bytesRead, isTriangle); + int commandsExecuted = drawEngineCommon_->ExtendNonIndexedPrim(src, stall, vertTypeID, clockwise, &bytesRead, isTriangle); if (!commandsExecuted) { goto bail; } @@ -1046,7 +1047,7 @@ void GPUCommonHW::Execute_Prim(u32 op, u32 diff) { // We can extend again after submitting a normal draw. canExtend = isTriangle; } - if (!drawEngineCommon_->SubmitPrim(verts, inds, newPrim, count, vertTypeID, cullMode, &bytesRead)) { + if (!drawEngineCommon_->SubmitPrim(verts, inds, newPrim, count, vertTypeID, clockwise, &bytesRead)) { canExtend = false; } AdvanceVerts(vertexType, count, bytesRead); diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index eacdb481ae..234ef5aca3 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -71,8 +71,8 @@ void SoftwareDrawEngine::DispatchFlush() { transformUnit.Flush("debug"); } -void SoftwareDrawEngine::DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { - _assert_msg_(cullMode == gstate.getCullMode(), "Mixed cull mode not supported."); +void SoftwareDrawEngine::DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, bool clockwise, int *bytesRead) { + _assert_msg_(clockwise, "Mixed cull mode not supported."); transformUnit.SubmitPrimitive(verts, inds, prim, vertexCount, vertTypeID, bytesRead, this); } diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index f2a2a93472..295953a8e0 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -178,7 +178,7 @@ public: void NotifyConfigChanged() override; void DispatchFlush() override; - void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int cullMode, int *bytesRead) override; + void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, bool clockwise, int *bytesRead) override; void DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex *buffer, int vertexCount, int cullMode, bool continuation) override; VertexDecoder *FindVertexDecoder(u32 vtype);