From 2e9daa5f89ebdb3892d6793eedbfb9107c5771f2 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 21 Dec 2012 18:46:15 +0100 Subject: [PATCH] All drawing is now indexed lists, through IndexGenerator. --- GPU/GLES/IndexGenerator.cpp | 50 +++++++++++++ GPU/GLES/IndexGenerator.h | 8 +++ GPU/GLES/TransformPipeline.cpp | 126 ++++++++++++++++----------------- GPU/GLES/TransformPipeline.h | 2 +- GPU/GLES/VertexDecoder.cpp | 2 +- GPU/GLES/VertexDecoder.h | 1 + 6 files changed, 122 insertions(+), 67 deletions(-) diff --git a/GPU/GLES/IndexGenerator.cpp b/GPU/GLES/IndexGenerator.cpp index 7a786488cf..b08ab3cd5b 100644 --- a/GPU/GLES/IndexGenerator.cpp +++ b/GPU/GLES/IndexGenerator.cpp @@ -31,6 +31,7 @@ const u8 indexedPrimitiveType[7] = { void IndexGenerator::Reset() { prim_ = -1; inds_ = 0; + count_ = 0; } bool IndexGenerator::PrimCompatible(int prim) { @@ -41,8 +42,22 @@ bool IndexGenerator::PrimCompatible(int prim) { void IndexGenerator::Start(u16 *inds, int baseIndex, int prim) { + count_ = 0; this->inds_ = inds; index_ = baseIndex; + prim_ = indexedPrimitiveType[prim]; +} + +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; } void IndexGenerator::AddList(int numVerts) @@ -58,6 +73,7 @@ void IndexGenerator::AddList(int numVerts) // ignore overflow verts index_ += numVerts; + count_ += numTris * 3; } void IndexGenerator::AddStrip(int numVerts) @@ -72,6 +88,7 @@ void IndexGenerator::AddStrip(int numVerts) wind = !wind; } index_ += numVerts; + count_ += numTris * 3; } void IndexGenerator::AddFan(int numVerts) @@ -84,6 +101,27 @@ void IndexGenerator::AddFan(int numVerts) *inds_++ = index_ + i + 2; } index_ += numVerts; + count_ += numTris * 3; +} + +void IndexGenerator::TranslatePoints(int numVerts, const u8 *inds, int offset) +{ + for (int i = 0; i < numVerts; i++) + { + *inds_++ = index_ + offset + inds[i]; + } + index_ += numVerts; + count_ += numVerts; +} + +void IndexGenerator::TranslatePoints(int numVerts, const u16 *inds, int offset) +{ + for (int i = 0; i < numVerts; i++) + { + *inds_++ = index_ + offset + inds[i]; + } + index_ += numVerts; + count_ += numVerts; } void IndexGenerator::TranslateList(int numVerts, const u8 *inds, int offset) @@ -96,6 +134,7 @@ void IndexGenerator::TranslateList(int numVerts, const u8 *inds, int offset) *inds_++ = index_ + offset + inds[i*3 + 2]; } index_ += numVerts; + count_ += numTris * 3; } void IndexGenerator::TranslateStrip(int numVerts, const u8 *inds, int offset) @@ -110,6 +149,7 @@ void IndexGenerator::TranslateStrip(int numVerts, const u8 *inds, int offset) wind = !wind; } index_ += numVerts; + count_ += numTris * 3; } void IndexGenerator::TranslateFan(int numVerts, const u8 *inds, int offset) @@ -123,6 +163,7 @@ void IndexGenerator::TranslateFan(int numVerts, const u8 *inds, int offset) *inds_++ = index_ + offset + inds[i + 2]; } index_ += numVerts; + count_ += numTris * 3; } void IndexGenerator::TranslateList(int numVerts, const u16 *inds, int offset) @@ -135,6 +176,7 @@ void IndexGenerator::TranslateList(int numVerts, const u16 *inds, int offset) *inds_++ = index_ + offset + inds[i*3 + 2]; } index_ += numVerts; + count_ += numTris * 3; } void IndexGenerator::TranslateStrip(int numVerts, const u16 *inds, int offset) @@ -149,6 +191,7 @@ void IndexGenerator::TranslateStrip(int numVerts, const u16 *inds, int offset) wind = !wind; } index_ += numVerts; + count_ += numTris * 3; } void IndexGenerator::TranslateFan(int numVerts, const u16 *inds, int offset) @@ -162,6 +205,7 @@ void IndexGenerator::TranslateFan(int numVerts, const u16 *inds, int offset) *inds_++ = index_ + offset + inds[i + 2]; } index_ += numVerts; + count_ += numTris * 3; } //Lines @@ -174,6 +218,7 @@ void IndexGenerator::AddLineList(int numVerts) *inds_++ = index_ + i*2+1; } index_ += numVerts; + count_ += numLines * 2; } void IndexGenerator::AddLineStrip(int numVerts) @@ -185,6 +230,7 @@ void IndexGenerator::AddLineStrip(int numVerts) *inds_++ = index_ + i + 1; } index_ += numVerts; + count_ += numLines * 2; } void IndexGenerator::TranslateLineList(int numVerts, const u8 *inds, int offset) @@ -196,6 +242,7 @@ void IndexGenerator::TranslateLineList(int numVerts, const u8 *inds, int offset) *inds_++ = index_ + i*2+1; } index_ += numVerts; + count_ += numLines * 2; } void IndexGenerator::TranslateLineStrip(int numVerts, const u8 *inds, int offset) @@ -207,6 +254,7 @@ void IndexGenerator::TranslateLineStrip(int numVerts, const u8 *inds, int offset *inds_++ = index_ + i + 1; } index_ += numVerts; + count_ += numLines * 2; } void IndexGenerator::TranslateLineList(int numVerts, const u16 *inds, int offset) @@ -218,6 +266,7 @@ void IndexGenerator::TranslateLineList(int numVerts, const u16 *inds, int offset *inds_++ = index_ + i*2+1; } index_ += numVerts; + count_ += numLines * 2; } void IndexGenerator::TranslateLineStrip(int numVerts, const u16 *inds, int offset) @@ -229,4 +278,5 @@ void IndexGenerator::TranslateLineStrip(int numVerts, const u16 *inds, int offse *inds_++ = index_ + i + 1; } index_ += numVerts; + count_ += numLines * 2; } \ No newline at end of file diff --git a/GPU/GLES/IndexGenerator.h b/GPU/GLES/IndexGenerator.h index 45d3a0bad3..bb2a9bde00 100644 --- a/GPU/GLES/IndexGenerator.h +++ b/GPU/GLES/IndexGenerator.h @@ -28,6 +28,8 @@ public: void Start(u16 *indexptr, int baseIndex, int prim); bool PrimCompatible(int prim); + // Points (why index these? code simplicity) + void AddPoints(int numVerts); // Triangles void AddList(int numVerts); void AddStrip(int numVerts); @@ -36,6 +38,8 @@ public: void AddLineList(int numVerts); void AddLineStrip(int numVerts); + void TranslatePoints(int numVerts, const u8 *inds, int offset); + void TranslatePoints(int numVerts, const u16 *inds, int offset); // Translates already indexed lists void TranslateLineList(int numVerts, const u8 *inds, int offset); void TranslateLineStrip(int numVerts, const u8 *inds, int offset); @@ -49,9 +53,13 @@ public: void TranslateStrip(int numVerts, const u16 *inds, int offset); void TranslateFan(int numVerts, const u16 *inds, int offset); + int MaxIndex() { return index_; } + int VertexCount() { return count_; } + private: u16 *inds_; int index_; + int count_; int prim_; }; diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 91a8548749..913f2c23ca 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -30,6 +30,7 @@ #include "VertexDecoder.h" #include "ShaderManager.h" #include "DisplayListInterpreter.h" +#include "IndexGenerator.h" const GLuint glprim[8] = { GL_POINTS, @@ -42,7 +43,9 @@ const GLuint glprim[8] = { }; u8 decoded[65536 * 32]; -// uint16_t decIndex[65536]; // Unused +uint16_t decIndex[65536]; // Unused + +IndexGenerator indexGen; TransformedVertex transformed[65536]; TransformedVertex transformedExpanded[65536]; @@ -262,7 +265,7 @@ static void DesetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decF // Actually again, single quads could be drawn more efficiently using GL_TRIANGLE_STRIP, no need to duplicate verts as for // GL_TRIANGLES. Still need to sw transform to compute the extra two corners though. -void SoftwareTransformAndDraw(int prim, LinkedShader *program, int forceIndexType, int vertexCount, void *inds, const DecVtxFormat &decVtxFormat, int indexLowerBound, int indexUpperBound, float *customUV) +void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex, float *customUV) { /* DEBUG_LOG(G3D, "View matrix:"); @@ -289,7 +292,7 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int forceIndexTyp Lighter lighter; VertexReader reader(decoded, decVtxFormat); - for (int index = indexLowerBound; index <= indexUpperBound; index++) + for (int index = 0; index < maxIndex; index++) { reader.Goto(index); @@ -483,48 +486,19 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int forceIndexTyp const TransformedVertex *drawBuffer = transformed; int numTrans = 0; - int indexType = (gstate.vertType & GE_VTYPE_IDX_MASK); - if (forceIndexType != -1) { - indexType = forceIndexType; - } bool drawIndexed = false; - GLuint glIndexType = 0; if (prim != GE_PRIM_RECTANGLES) { // We can simply draw the unexpanded buffer. numTrans = vertexCount; - switch (indexType) { - case GE_VTYPE_IDX_8BIT: - drawIndexed = true; - glIndexType = GL_UNSIGNED_BYTE; - break; - case GE_VTYPE_IDX_16BIT: - drawIndexed = true; - glIndexType = GL_UNSIGNED_SHORT; - break; - default: - drawIndexed = false; - break; - } + drawIndexed = true; } else { numTrans = 0; drawBuffer = transformedExpanded; TransformedVertex *trans = &transformedExpanded[0]; TransformedVertex saved; for (int i = 0; i < vertexCount; i++) { - int index; - if (indexType == GE_VTYPE_IDX_8BIT) - { - index = ((u8*)inds)[i]; - } - else if (indexType == GE_VTYPE_IDX_16BIT) - { - index = ((u16*)inds)[i]; - } - else - { - index = i; - } + int index = ((u16*)inds)[i]; TransformedVertex &transVtx = transformed[index]; if ((i & 1) == 0) @@ -591,7 +565,7 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int forceIndexTyp if (program->a_color0 != -1) glVertexAttribPointer(program->a_color0, 4, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 5 * 4); if (program->a_color1 != -1) glVertexAttribPointer(program->a_color1, 3, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 9 * 4); if (drawIndexed) { - glDrawElements(glprim[prim], numTrans, glIndexType, (GLvoid *)inds); + glDrawElements(glprim[prim], numTrans, GL_UNSIGNED_SHORT, (GLvoid *)inds); } else { glDrawArrays(glprim[prim], 0, numTrans); } @@ -603,6 +577,10 @@ void SoftwareTransformAndDraw(int prim, LinkedShader *program, int forceIndexTyp void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, float *customUV, int forceIndexType, int *bytesRead) { + // For the future + if (!indexGen.PrimCompatible(prim)) + Flush(prim); + int indexLowerBound, indexUpperBound; // First, decode the verts and apply morphing VertexDecoder dec; @@ -611,6 +589,51 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte if (bytesRead) *bytesRead = vertexCount * dec.VertexSize(); + indexGen.Start(decIndex, 0, prim); + + int indexType = (gstate.vertType & GE_VTYPE_IDX_MASK); + if (forceIndexType != -1) indexType = forceIndexType; + switch (indexType) { + case GE_VTYPE_IDX_NONE: + switch (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.AddLineList(vertexCount); break; // Same + } + break; + + case GE_VTYPE_IDX_8BIT: + switch (prim) { + case GE_PRIM_POINTS: indexGen.TranslatePoints(vertexCount, (const u16 *)inds, -indexLowerBound); break; + case GE_PRIM_LINES: indexGen.TranslateLineList(vertexCount, (const u8 *)inds, -indexLowerBound); break; + case GE_PRIM_LINE_STRIP: indexGen.TranslateLineStrip(vertexCount, (const u8 *)inds, -indexLowerBound); break; + case GE_PRIM_TRIANGLES: indexGen.TranslateList(vertexCount, (const u8 *)inds, -indexLowerBound); break; + case GE_PRIM_TRIANGLE_STRIP: indexGen.TranslateStrip(vertexCount, (const u8 *)inds, -indexLowerBound); break; + case GE_PRIM_TRIANGLE_FAN: indexGen.TranslateFan(vertexCount, (const u8 *)inds, -indexLowerBound); break; + case GE_PRIM_RECTANGLES: indexGen.TranslateLineList(vertexCount, (const u8 *)inds, -indexLowerBound); break; // Same + } + break; + + case GE_VTYPE_IDX_16BIT: + switch (prim) { + case GE_PRIM_POINTS: indexGen.TranslatePoints(vertexCount, (const u16 *)inds, -indexLowerBound); break; + case GE_PRIM_LINES: indexGen.TranslateLineList(vertexCount, (const u16 *)inds, -indexLowerBound); break; + case GE_PRIM_LINE_STRIP: indexGen.TranslateLineStrip(vertexCount, (const u16 *)inds, -indexLowerBound); break; + case GE_PRIM_TRIANGLES: indexGen.TranslateList(vertexCount, (const u16 *)inds, -indexLowerBound); break; + case GE_PRIM_TRIANGLE_STRIP: indexGen.TranslateStrip(vertexCount, (const u16 *)inds, -indexLowerBound); break; + case GE_PRIM_TRIANGLE_FAN: indexGen.TranslateFan(vertexCount, (const u16 *)inds, -indexLowerBound); break; + case GE_PRIM_RECTANGLES: indexGen.TranslateLineList(vertexCount, (const u16 *)inds, -indexLowerBound); break; // Same + } + break; + } + + indexType = GE_VTYPE_IDX_16BIT; + // From here on out, the index type is ALWAYS 16-bit. Deal with it. + // And here we should return, having collected the morphed but untransformed vertices. // Note that DecodeVerts should convert strips into indexed lists etc, adding to our // current vertex buffer and index buffer. @@ -622,15 +645,12 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte PrintDecodedVertex(decoded[i], gstate.vertType); } #endif - bool useTexCoord = false; - // Check if anything needs updating if (gstate_c.textureChanged) { if ((gstate.textureMapEnable & 1) && !gstate.isModeClear()) { PSPSetTexture(); - useTexCoord = true; } gstate_c.textureChanged = false; } @@ -647,35 +667,11 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte if (CanUseHardwareTransform(prim)) { SetupDecFmtForDraw(program, dec.GetDecVtxFmt(), decoded); - bool drawIndexed; - GLuint glIndexType; - int indexType = (gstate.vertType & GE_VTYPE_IDX_MASK); - if (forceIndexType != -1) { - indexType = forceIndexType; - } - int numTrans = vertexCount; - switch (indexType) { - case GE_VTYPE_IDX_8BIT: - drawIndexed = true; - glIndexType = GL_UNSIGNED_BYTE; - break; - case GE_VTYPE_IDX_16BIT: - drawIndexed = true; - glIndexType = GL_UNSIGNED_SHORT; - break; - default: - drawIndexed = false; - break; - } - // NOTICE_LOG(G3D,"DrawPrimitive: %i", numTrans); - if (drawIndexed) { - glDrawElements(glprim[prim], numTrans, glIndexType, (GLvoid *)inds); - } else { - glDrawArrays(glprim[prim], 0, numTrans); - } + glDrawElements(glprim[prim], indexGen.VertexCount(), GL_UNSIGNED_SHORT, (GLvoid *)decIndex); DesetupDecFmtForDraw(program, dec.GetDecVtxFmt()); } else { - SoftwareTransformAndDraw(prim, program, forceIndexType, vertexCount, inds, dec.GetDecVtxFmt(), indexLowerBound, indexUpperBound, customUV); + SoftwareTransformAndDraw(prim, program, indexGen.VertexCount(), (void *)decIndex, indexType, dec.GetDecVtxFmt(), + indexGen.MaxIndex(), customUV); } } diff --git a/GPU/GLES/TransformPipeline.h b/GPU/GLES/TransformPipeline.h index 5314e152f6..4c89dfcda3 100644 --- a/GPU/GLES/TransformPipeline.h +++ b/GPU/GLES/TransformPipeline.h @@ -65,4 +65,4 @@ struct Color4 } }; -void SoftwareTransformAndDraw(int prim, LinkedShader *program, int forceIndexType, int vertexCount, void *inds, const DecVtxFormat &decVtxFormat, int indexLowerBound, int indexUpperBound, float *customUV); +// void SoftwareTransformAndDraw(int prim, LinkedShader *program, int vertexCount, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex, float *customUV); diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp index 8f7b7fb0b3..34bef88276 100644 --- a/GPU/GLES/VertexDecoder.cpp +++ b/GPU/GLES/VertexDecoder.cpp @@ -675,7 +675,7 @@ void VertexDecoder::DecodeVerts(u8 *decodedptr, const void *verts, const void *i *indexUpperBound = upperBound; // Decode the vertices within the found bounds, once each - decoded_ = decodedptr + lowerBound * decFmt.stride; + decoded_ = decodedptr; // + lowerBound * decFmt.stride; ptr_ = (const u8*)verts + lowerBound * size; for (int index = lowerBound; index <= upperBound; index++) { diff --git a/GPU/GLES/VertexDecoder.h b/GPU/GLES/VertexDecoder.h index 6e6bc887ea..f664d303a3 100644 --- a/GPU/GLES/VertexDecoder.h +++ b/GPU/GLES/VertexDecoder.h @@ -86,6 +86,7 @@ public: void SetVertexType(u32 vtype); const DecVtxFormat &GetDecVtxFmt() { return decFmt; } + void DecodeVerts(u8 *decoded, const void *verts, const void *inds, int prim, int count, int *indexLowerBound, int *indexUpperBound) const; bool hasColor() const { return col != 0; } int VertexSize() const { return size; }