From 71aaad23fba5e4ab4e9610b99384078d1c0d6d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 10 Dec 2023 12:21:07 +0100 Subject: [PATCH] Fix issue with zero-vertex draw calls. Though, should maybe just filter them out earlier. --- GPU/Common/DrawEngineCommon.cpp | 17 ++++++++--------- GPU/Common/VertexDecoderCommon.cpp | 6 +++++- GPU/Vulkan/DrawEngineVulkan.cpp | 8 ++++++++ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index eec4070f51d3..190f6160d4cd 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -899,8 +899,11 @@ bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti *bytesRead = vertexCount * dec_->VertexSize(); // Check that we have enough vertices to form the requested primitive. - if (vertexCount < 3 && ((vertexCount < 2 && prim > 0) || (prim > GE_PRIM_LINE_STRIP && prim != GE_PRIM_RECTANGLES))) - return false; + if (vertexCount < 3) { + if ((vertexCount < 2 && prim > 0) || (prim > GE_PRIM_LINE_STRIP && prim != GE_PRIM_RECTANGLES)) { + return false; + } + } bool applySkin = (vertTypeID & GE_VTYPE_WEIGHT_MASK) && decOptions_.applySkinInDecode; @@ -919,10 +922,10 @@ bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti if (inds && numDrawVerts_ > decodeVertsCounter_ && drawVerts_[numDrawVerts_ - 1].verts == verts && !applySkin) { // Same vertex pointer as a previous un-decoded draw call - let's just extend the decode! di.vertDecodeIndex = numDrawVerts_ - 1; - DeferredVerts &dv = drawVerts_[numDrawVerts_ - 1]; u16 lb; u16 ub; GetIndexBounds(inds, vertexCount, vertTypeID, &lb, &ub); + DeferredVerts &dv = drawVerts_[numDrawVerts_ - 1]; if (lb < dv.indexLowerBound) dv.indexLowerBound = lb; if (ub > dv.indexUpperBound) @@ -933,12 +936,8 @@ bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti dv.verts = verts; dv.vertexCount = vertexCount; dv.uvScale = gstate_c.uv; - if (inds) { - GetIndexBounds(inds, vertexCount, vertTypeID, &dv.indexLowerBound, &dv.indexUpperBound); - } else { - dv.indexLowerBound = 0; - dv.indexUpperBound = vertexCount - 1; - } + // Does handle the unindexed case. + GetIndexBounds(inds, vertexCount, vertTypeID, &dv.indexLowerBound, &dv.indexUpperBound); } vertexCountInDrawCalls_ += vertexCount; diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index cc8b6452e2b1..e500c69db5fa 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -154,7 +154,11 @@ void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBo *indexUpperBound = (u16)upperBound; } else { *indexLowerBound = 0; - *indexUpperBound = count - 1; + if (count > 0) { + *indexUpperBound = count - 1; + } else { + *indexUpperBound = 0; + } } } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 5149a37c41e3..670338bbb4d2 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -376,8 +376,11 @@ void DrawEngineVulkan::DoFlush() { lastVType_ |= (1 << 26); dec_ = GetVertexDecoder(lastVType_); } + int prevDecodedVerts = numDecodedVerts_; + DecodeVerts(decoded_); DecodeInds(); + bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; if (gstate.isModeThrough()) { gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255); @@ -385,6 +388,11 @@ void DrawEngineVulkan::DoFlush() { gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255); } + int vcount = indexGen.VertexCount(); + if (numDecodedVerts_ > 10 * vcount) { + decIndex_ = decIndex_; + } + gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); prim = indexGen.Prim(); // Undo the strip optimization, not supported by the SW code yet.