mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-28 12:35:37 +00:00
Smarter draw call joining, fixing MH vertex glitches. Thanks bovine for identifying the issue.
This commit is contained in:
parent
09d2e4b15d
commit
b4977610cc
@ -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;
|
||||
|
@ -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_; }
|
||||
|
||||
|
@ -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
|
||||
u32 indexType = dc.indexType;
|
||||
void *inds = dc.inds;
|
||||
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.inds, dc.prim, dc.vertexCount, indexLowerBound, indexUpperBound);
|
||||
dc.verts, dc.prim, indexLowerBound, indexUpperBound);
|
||||
collectedVerts += indexUpperBound - indexLowerBound + 1;
|
||||
switch (dc.prim) {
|
||||
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
|
||||
}
|
||||
} 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.
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
u32 indexType = dc.indexType;
|
||||
int vertexCount = dc.vertexCount;
|
||||
void *inds = dc.inds;
|
||||
switch (indexType) {
|
||||
case GE_VTYPE_IDX_NONE >> GE_VTYPE_IDX_SHIFT:
|
||||
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
|
||||
}
|
||||
break;
|
||||
|
||||
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
|
||||
}
|
||||
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;
|
||||
// 4. Advance indexgen vertex counter.
|
||||
indexGen.Advance(indexUpperBound - indexLowerBound + 1);
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user