From b4977610cc0a5fc43dc1b3b7218e09c93ac1d7ab Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 23 Mar 2013 13:12:03 +0100 Subject: [PATCH] Smarter draw call joining, fixing MH vertex glitches. Thanks bovine for identifying the issue. --- GPU/GLES/IndexGenerator.cpp | 175 ++++++++++++--------------------- GPU/GLES/IndexGenerator.h | 7 ++ GPU/GLES/TransformPipeline.cpp | 87 ++++++++-------- GPU/GLES/VertexDecoder.cpp | 2 +- GPU/GLES/VertexDecoder.h | 2 +- 5 files changed, 120 insertions(+), 153 deletions(-) diff --git a/GPU/GLES/IndexGenerator.cpp b/GPU/GLES/IndexGenerator.cpp index 612b9cbecb..b585e34ae1 100644 --- a/GPU/GLES/IndexGenerator.cpp +++ b/GPU/GLES/IndexGenerator.cpp @@ -18,7 +18,7 @@ #include "IndexGenerator.h" // Points don't need indexing... -const u8 indexedPrimitiveType[7] = { +static const u8 indexedPrimitiveType[7] = { GE_PRIM_POINTS, GE_PRIM_LINES, GE_PRIM_LINES, @@ -54,11 +54,8 @@ void IndexGenerator::Setup(u16 *inds) { } void IndexGenerator::AddPoints(int numVerts) { - //if we have no vertices return for (int i = 0; i < numVerts; i++) - { *inds_++ = index_ + i; - } // ignore overflow verts index_ += numVerts; count_ += numVerts; @@ -66,12 +63,9 @@ void IndexGenerator::AddPoints(int numVerts) { seenPrims_ |= 1 << GE_PRIM_POINTS; } -void IndexGenerator::AddList(int numVerts) -{ - //if we have no vertices return +void IndexGenerator::AddList(int numVerts) { int numTris = numVerts / 3; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ + i*3; *inds_++ = index_ + i*3 + 1; *inds_++ = index_ + i*3 + 2; @@ -84,12 +78,10 @@ void IndexGenerator::AddList(int numVerts) seenPrims_ |= 1 << GE_PRIM_TRIANGLES; } -void IndexGenerator::AddStrip(int numVerts) -{ +void IndexGenerator::AddStrip(int numVerts) { bool wind = false; int numTris = numVerts - 2; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ + i; *inds_++ = index_ + i+(wind?2:1); *inds_++ = index_ + i+(wind?1:2); @@ -101,11 +93,9 @@ void IndexGenerator::AddStrip(int numVerts) seenPrims_ |= 1 << GE_PRIM_TRIANGLE_STRIP; } -void IndexGenerator::AddFan(int numVerts) -{ +void IndexGenerator::AddFan(int numVerts) { int numTris = numVerts - 2; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_; *inds_++ = index_ + i + 1; *inds_++ = index_ + i + 2; @@ -117,11 +107,9 @@ void IndexGenerator::AddFan(int numVerts) } //Lines -void IndexGenerator::AddLineList(int numVerts) -{ +void IndexGenerator::AddLineList(int numVerts) { int numLines = numVerts / 2; - for (int i = 0; i < numLines; i++) - { + for (int i = 0; i < numLines; i++) { *inds_++ = index_ + i*2; *inds_++ = index_ + i*2+1; } @@ -131,11 +119,9 @@ void IndexGenerator::AddLineList(int numVerts) seenPrims_ |= 1 << prim_; } -void IndexGenerator::AddLineStrip(int numVerts) -{ +void IndexGenerator::AddLineStrip(int numVerts) { int numLines = numVerts - 1; - for (int i = 0; i < numLines; i++) - { + for (int i = 0; i < numLines; i++) { *inds_++ = index_ + i; *inds_++ = index_ + i + 1; } @@ -145,11 +131,9 @@ void IndexGenerator::AddLineStrip(int numVerts) seenPrims_ |= 1 << GE_PRIM_LINE_STRIP; } -void IndexGenerator::AddRectangles(int numVerts) -{ +void IndexGenerator::AddRectangles(int numVerts) { int numRects = numVerts / 2; - for (int i = 0; i < numRects; i++) - { + for (int i = 0; i < numRects; i++) { *inds_++ = index_ + i*2; *inds_++ = index_ + i*2+1; } @@ -159,219 +143,186 @@ void IndexGenerator::AddRectangles(int numVerts) seenPrims_ |= 1 << GE_PRIM_RECTANGLES; } -void IndexGenerator::TranslatePoints(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) -{ +void IndexGenerator::TranslatePrim(int prim, int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { + switch (prim) { + case GE_PRIM_POINTS: TranslatePoints(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_LINES: TranslateLineList(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_LINE_STRIP: TranslateLineStrip(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_TRIANGLES: TranslateList(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_TRIANGLE_STRIP: TranslateStrip(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_TRIANGLE_FAN: TranslateFan(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_RECTANGLES: TranslateRectangles(numInds, inds, indexLowerBound, indexUpperBound); break; // Same + } +} + +void IndexGenerator::TranslatePrim(int prim, int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { + switch (prim) { + case GE_PRIM_POINTS: TranslatePoints(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_LINES: TranslateLineList(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_LINE_STRIP: TranslateLineStrip(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_TRIANGLES: TranslateList(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_TRIANGLE_STRIP: TranslateStrip(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_TRIANGLE_FAN: TranslateFan(numInds, inds, indexLowerBound, indexUpperBound); break; + case GE_PRIM_RECTANGLES: TranslateRectangles(numInds, inds, indexLowerBound, indexUpperBound); break; // Same + } +} + +void IndexGenerator::TranslatePoints(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { int numVerts = indexUpperBound - indexLowerBound + 1; for (int i = 0; i < numInds; i++) - { *inds_++ = index_ - indexLowerBound + inds[i]; - } - index_ += numVerts; count_ += numInds; prim_ = GE_PRIM_POINTS; seenPrims_ |= (1 << GE_PRIM_POINTS) | SEEN_INDEX8; } -void IndexGenerator::TranslatePoints(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslatePoints(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { for (int i = 0; i < numInds; i++) - { *inds_++ = index_ - indexLowerBound + inds[i]; - } - index_ += numVerts; count_ += numInds; prim_ = GE_PRIM_POINTS; seenPrims_ |= (1 << GE_PRIM_POINTS) | SEEN_INDEX16; } -void IndexGenerator::TranslateList(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateList(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { int numTris = numInds / 3; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ - indexLowerBound + inds[i*3]; *inds_++ = index_ - indexLowerBound + inds[i*3 + 1]; *inds_++ = index_ - indexLowerBound + inds[i*3 + 2]; } - index_ += numVerts; count_ += numTris * 3; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= (1 << GE_PRIM_TRIANGLES) | SEEN_INDEX8; } -void IndexGenerator::TranslateStrip(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateStrip(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { bool wind = false; int numTris = numInds - 2; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ - indexLowerBound + inds[i]; *inds_++ = index_ - indexLowerBound + inds[i + (wind?2:1)]; *inds_++ = index_ - indexLowerBound + inds[i + (wind?1:2)]; wind = !wind; } - index_ += numVerts; count_ += numTris * 3; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= (1 << GE_PRIM_TRIANGLE_STRIP) | SEEN_INDEX8; } -void IndexGenerator::TranslateFan(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateFan(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { if (numInds <= 0) return; int numTris = numInds - 2; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ - indexLowerBound + inds[0]; *inds_++ = index_ - indexLowerBound + inds[i + 1]; *inds_++ = index_ - indexLowerBound + inds[i + 2]; } - index_ += numVerts; count_ += numTris * 3; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= (1 << GE_PRIM_TRIANGLE_FAN) | SEEN_INDEX8; } -void IndexGenerator::TranslateList(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateList(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { int numTris = numInds / 3; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ - indexLowerBound + inds[i*3]; *inds_++ = index_ - indexLowerBound + inds[i*3 + 1]; *inds_++ = index_ - indexLowerBound + inds[i*3 + 2]; } - index_ += numVerts; count_ += numTris * 3; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= (1 << GE_PRIM_TRIANGLES) | SEEN_INDEX16; } -void IndexGenerator::TranslateStrip(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateStrip(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { bool wind = false; int numTris = numInds - 2; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ - indexLowerBound + inds[i]; *inds_++ = index_ - indexLowerBound + inds[i + (wind?2:1)]; *inds_++ = index_ - indexLowerBound + inds[i + (wind?1:2)]; wind = !wind; } - index_ += numVerts; count_ += numTris * 3; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= (1 << GE_PRIM_TRIANGLE_STRIP) | SEEN_INDEX16; } -void IndexGenerator::TranslateFan(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateFan(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { if (numInds <= 0) return; int numTris = numInds - 2; - for (int i = 0; i < numTris; i++) - { + for (int i = 0; i < numTris; i++) { *inds_++ = index_ - indexLowerBound + inds[0]; *inds_++ = index_ - indexLowerBound + inds[i + 1]; *inds_++ = index_ - indexLowerBound + inds[i + 2]; } - index_ += numVerts; count_ += numTris * 3; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= (1 << GE_PRIM_TRIANGLE_FAN) | SEEN_INDEX16; } -void IndexGenerator::TranslateLineList(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateLineList(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { int numLines = numInds / 2; - for (int i = 0; i < numLines; i++) - { + for (int i = 0; i < numLines; i++) { *inds_++ = index_ - indexLowerBound + inds[i*2]; *inds_++ = index_ - indexLowerBound + inds[i*2+1]; } - index_ += numVerts; count_ += numLines * 2; prim_ = GE_PRIM_LINES; seenPrims_ |= (1 << GE_PRIM_LINES) | SEEN_INDEX8; } -void IndexGenerator::TranslateLineStrip(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateLineStrip(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { int numLines = numInds - 1; - for (int i = 0; i < numLines; i++) - { + for (int i = 0; i < numLines; i++) { *inds_++ = index_ - indexLowerBound + inds[i]; *inds_++ = index_ - indexLowerBound + inds[i + 1]; } - index_ += numVerts; count_ += numLines * 2; prim_ = GE_PRIM_LINES; seenPrims_ |= (1 << GE_PRIM_LINE_STRIP) | SEEN_INDEX8; } -void IndexGenerator::TranslateLineList(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateLineList(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { int numLines = numInds / 2; - for (int i = 0; i < numLines; i++) - { + for (int i = 0; i < numLines; i++) { *inds_++ = index_ - indexLowerBound + inds[i*2]; *inds_++ = index_ - indexLowerBound + inds[i*2+1]; } - index_ += numVerts; count_ += numLines * 2; prim_ = GE_PRIM_LINES; seenPrims_ |= (1 << GE_PRIM_LINES) | SEEN_INDEX16; } -void IndexGenerator::TranslateLineStrip(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateLineStrip(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { int numLines = numInds - 1; - for (int i = 0; i < numLines; i++) - { + for (int i = 0; i < numLines; i++) { *inds_++ = index_ - indexLowerBound + inds[i]; *inds_++ = index_ - indexLowerBound + inds[i + 1]; } - index_ += numVerts; count_ += numLines * 2; prim_ = GE_PRIM_LINES; seenPrims_ |= (1 << GE_PRIM_LINE_STRIP) | SEEN_INDEX16; } -void IndexGenerator::TranslateRectangles(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateRectangles(int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound) { int numRects = numInds / 2; - for (int i = 0; i < numRects; i++) - { + for (int i = 0; i < numRects; i++) { *inds_++ = index_ - indexLowerBound + inds[i*2]; *inds_++ = index_ - indexLowerBound + inds[i*2+1]; } - index_ += numVerts; count_ += numRects * 2; prim_ = GE_PRIM_RECTANGLES; seenPrims_ |= (1 << GE_PRIM_RECTANGLES) | SEEN_INDEX8; } -void IndexGenerator::TranslateRectangles(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) -{ - int numVerts = indexUpperBound - indexLowerBound + 1; +void IndexGenerator::TranslateRectangles(int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound) { int numRects = numInds / 2; - for (int i = 0; i < numRects; i++) - { + for (int i = 0; i < numRects; i++) { *inds_++ = index_ - indexLowerBound + inds[i*2]; *inds_++ = index_ - indexLowerBound + inds[i*2+1]; } - index_ += numVerts; count_ += numRects * 2; prim_ = GE_PRIM_RECTANGLES; seenPrims_ |= (1 << GE_PRIM_RECTANGLES) | SEEN_INDEX16; diff --git a/GPU/GLES/IndexGenerator.h b/GPU/GLES/IndexGenerator.h index 2d1bbfdd86..a026cb6dc4 100644 --- a/GPU/GLES/IndexGenerator.h +++ b/GPU/GLES/IndexGenerator.h @@ -44,6 +44,9 @@ public: // Rectangles void AddRectangles(int numVerts); + void TranslatePrim(int prim, int numInds, const u8 *inds, int indexLowerBound, int indexUpperBound); + void TranslatePrim(int prim, int numInds, const u16 *inds, int indexLowerBound, int indexUpperBound); + void TranslatePoints(int numVerts, const u8 *inds, int indexLowerBound, int indexUpperBound); void TranslatePoints(int numVerts, const u16 *inds, int indexLowerBound, int indexUpperBound); // Translates already indexed lists @@ -62,6 +65,10 @@ public: void TranslateFan(int numVerts, const u8 *inds, int indexLowerBound, int indexUpperBound); void TranslateFan(int numVerts, const u16 *inds, int indexLowerBound, int indexUpperBound); + void Advance(int numVerts) { + index_ += numVerts; + } + int MaxIndex() const { return index_; } int VertexCount() const { return count_; } diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index dea62daf22..83bff71bec 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -759,9 +759,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( void TransformDrawEngine::SubmitPrim(void *verts, void *inds, int prim, int vertexCount, u32 vertType, int forceIndexType, int *bytesRead) { if (vertexCount == 0) - { return; // we ignore zero-sized draw calls. - } if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS) Flush(); @@ -804,50 +802,61 @@ void TransformDrawEngine::DecodeVerts() { indexGen.SetIndex(collectedVerts); int indexLowerBound = dc.indexLowerBound, indexUpperBound = dc.indexUpperBound; - // Decode the verts and apply morphing - dec.DecodeVerts(decoded + collectedVerts * (int)dec.GetDecVtxFmt().stride, - dc.verts, dc.inds, dc.prim, dc.vertexCount, indexLowerBound, indexUpperBound); - collectedVerts += indexUpperBound - indexLowerBound + 1; - u32 indexType = dc.indexType; - int vertexCount = dc.vertexCount; void *inds = dc.inds; - switch (indexType) { - case GE_VTYPE_IDX_NONE >> GE_VTYPE_IDX_SHIFT: + if (indexType == GE_VTYPE_IDX_NONE >> GE_VTYPE_IDX_SHIFT) { + // Decode the verts and apply morphing. Simple. + dec.DecodeVerts(decoded + collectedVerts * (int)dec.GetDecVtxFmt().stride, + dc.verts, dc.prim, indexLowerBound, indexUpperBound); + collectedVerts += indexUpperBound - indexLowerBound + 1; switch (dc.prim) { - case GE_PRIM_POINTS: indexGen.AddPoints(vertexCount); break; - case GE_PRIM_LINES: indexGen.AddLineList(vertexCount); break; - case GE_PRIM_LINE_STRIP: indexGen.AddLineStrip(vertexCount); break; - case GE_PRIM_TRIANGLES: indexGen.AddList(vertexCount); break; - case GE_PRIM_TRIANGLE_STRIP: indexGen.AddStrip(vertexCount); break; - case GE_PRIM_TRIANGLE_FAN: indexGen.AddFan(vertexCount); break; - case GE_PRIM_RECTANGLES: indexGen.AddRectangles(vertexCount); break; // Same + case GE_PRIM_POINTS: indexGen.AddPoints(dc.vertexCount); break; + case GE_PRIM_LINES: indexGen.AddLineList(dc.vertexCount); break; + case GE_PRIM_LINE_STRIP: indexGen.AddLineStrip(dc.vertexCount); break; + case GE_PRIM_TRIANGLES: indexGen.AddList(dc.vertexCount); break; + case GE_PRIM_TRIANGLE_STRIP: indexGen.AddStrip(dc.vertexCount); break; + case GE_PRIM_TRIANGLE_FAN: indexGen.AddFan(dc.vertexCount); break; + case GE_PRIM_RECTANGLES: indexGen.AddRectangles(dc.vertexCount); break; // Same } - break; + } else { + // It's fairly common that games issue long sequences of PRIM calls, with differing + // inds pointer but the same base vertex pointer. We'd like to reuse vertices between + // these as much as possible, so we make sure here to combine as many as possible + // into one nice big drawcall, sharing data. - case GE_VTYPE_IDX_8BIT >> GE_VTYPE_IDX_SHIFT: - switch (dc.prim) { - case GE_PRIM_POINTS: indexGen.TranslatePoints(vertexCount, (const u8 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_LINES: indexGen.TranslateLineList(vertexCount, (const u8 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_LINE_STRIP: indexGen.TranslateLineStrip(vertexCount, (const u8 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_TRIANGLES: indexGen.TranslateList(vertexCount, (const u8 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_TRIANGLE_STRIP: indexGen.TranslateStrip(vertexCount, (const u8 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_TRIANGLE_FAN: indexGen.TranslateFan(vertexCount, (const u8 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_RECTANGLES: indexGen.TranslateRectangles(vertexCount, (const u8 *)inds, indexLowerBound, indexUpperBound); break; // Same + // 1. Look ahead to find the max index, only looking as "matching" drawcalls. + // Expand the lower and upper bounds as we go. + int j = i + 1; + int lastMatch = i; + while (j < numDrawCalls) { + if (drawCalls[j].verts != dc.verts) + break; + indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound); + indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound); + lastMatch = j; + j++; + } + + // 2. Loop through the drawcalls, translating indices as we go. + for (j = i; j <= lastMatch; j++) { + switch (indexType) { + case GE_VTYPE_IDX_8BIT >> GE_VTYPE_IDX_SHIFT: + indexGen.TranslatePrim(dc.prim, drawCalls[j].vertexCount, (const u8 *)drawCalls[j].inds, indexLowerBound, indexUpperBound); + break; + case GE_VTYPE_IDX_16BIT >> GE_VTYPE_IDX_SHIFT: + indexGen.TranslatePrim(dc.prim, drawCalls[j].vertexCount, (const u16 *)drawCalls[j].inds, indexLowerBound, indexUpperBound); + break; + } } - break; - case GE_VTYPE_IDX_16BIT >> GE_VTYPE_IDX_SHIFT: - switch (dc.prim) { - case GE_PRIM_POINTS: indexGen.TranslatePoints(vertexCount, (const u16 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_LINES: indexGen.TranslateLineList(vertexCount, (const u16 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_LINE_STRIP: indexGen.TranslateLineStrip(vertexCount, (const u16 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_TRIANGLES: indexGen.TranslateList(vertexCount, (const u16 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_TRIANGLE_STRIP: indexGen.TranslateStrip(vertexCount, (const u16 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_TRIANGLE_FAN: indexGen.TranslateFan(vertexCount, (const u16 *)inds, indexLowerBound, indexUpperBound); break; - case GE_PRIM_RECTANGLES: indexGen.TranslateRectangles(vertexCount, (const u16 *)inds, indexLowerBound, indexUpperBound); break; // Same - } - break; + // 3. Decode that range of vertex data. + dec.DecodeVerts(decoded + collectedVerts * (int)dec.GetDecVtxFmt().stride, + dc.verts, dc.prim, indexLowerBound, indexUpperBound); + collectedVerts += indexUpperBound - indexLowerBound + 1; + + // 4. Advance indexgen vertex counter. + indexGen.Advance(indexUpperBound - indexLowerBound + 1); + i = j; } } } diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp index 75614f67ea..37781b7cc7 100644 --- a/GPU/GLES/VertexDecoder.cpp +++ b/GPU/GLES/VertexDecoder.cpp @@ -717,7 +717,7 @@ void GetIndexBounds(void *inds, int count, u32 vertType, u16 *indexLowerBound, u *indexUpperBound = (u16)upperBound; } -void VertexDecoder::DecodeVerts(u8 *decodedptr, const void *verts, const void *inds, int prim, int count, int indexLowerBound, int indexUpperBound) const { +void VertexDecoder::DecodeVerts(u8 *decodedptr, const void *verts, int prim, int indexLowerBound, int indexUpperBound) const { // Decode the vertices within the found bounds, once each decoded_ = decodedptr; // + lowerBound * decFmt.stride; ptr_ = (const u8*)verts + indexLowerBound * size; diff --git a/GPU/GLES/VertexDecoder.h b/GPU/GLES/VertexDecoder.h index 496e29b24c..47e1133d23 100644 --- a/GPU/GLES/VertexDecoder.h +++ b/GPU/GLES/VertexDecoder.h @@ -97,7 +97,7 @@ public: u32 VertexType() const { return fmt_; } const DecVtxFormat &GetDecVtxFmt() { return decFmt; } - void DecodeVerts(u8 *decoded, const void *verts, const void *inds, int prim, int count, int indexLowerBound, int indexUpperBound) const; + void DecodeVerts(u8 *decoded, const void *verts, int prim, int indexLowerBound, int indexUpperBound) const; // This could be easily generalized to inject any one component. Don't know another use for it though. u32 InjectUVs(u8 *decoded, const void *verts, float *customuv, int count) const;