IndexGenerator cleanup.

This commit is contained in:
Jordan Woyak 2013-02-21 19:10:00 -06:00
parent 677c6229ad
commit 368c78dd5c
4 changed files with 193 additions and 289 deletions

View File

@ -15,6 +15,8 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include <cstddef>
#include "IndexGenerator.h" #include "IndexGenerator.h"
/* /*
@ -33,18 +35,12 @@ u16 *IndexGenerator::Lptr = 0;
u16 *IndexGenerator::BASELptr = 0; u16 *IndexGenerator::BASELptr = 0;
u16 *IndexGenerator::Pptr = 0; u16 *IndexGenerator::Pptr = 0;
u16 *IndexGenerator::BASEPptr = 0; u16 *IndexGenerator::BASEPptr = 0;
int IndexGenerator::numT = 0; u32 IndexGenerator::numT = 0;
int IndexGenerator::numL = 0; u32 IndexGenerator::numL = 0;
int IndexGenerator::numP = 0; u32 IndexGenerator::numP = 0;
int IndexGenerator::index = 0; u32 IndexGenerator::index = 0;
int IndexGenerator::Tadds = 0;
int IndexGenerator::Ladds = 0;
int IndexGenerator::Padds = 0;
IndexGenerator::IndexPrimitiveType IndexGenerator::LastTPrimitive = Prim_None;
IndexGenerator::IndexPrimitiveType IndexGenerator::LastLPrimitive = Prim_None;
bool IndexGenerator::used = false;
void IndexGenerator::Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr) void IndexGenerator::Start(u16* Triangleptr, u16* Lineptr, u16* Pointptr)
{ {
Tptr = Triangleptr; Tptr = Triangleptr;
Lptr = Lineptr; Lptr = Lineptr;
@ -56,288 +52,220 @@ void IndexGenerator::Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr)
numT = 0; numT = 0;
numL = 0; numL = 0;
numP = 0; numP = 0;
Tadds = 0;
Ladds = 0;
Padds = 0;
LastTPrimitive = Prim_None;
LastLPrimitive = Prim_None;
} }
// Triangles
void IndexGenerator::AddList(int numVerts) void IndexGenerator::AddIndices(int primitive, u32 numVerts)
{ {
//if we have no vertices return //switch (primitive)
if(numVerts <= 0) return; //{
int numTris = numVerts / 3; //case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
//case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
//case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
//case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
//case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
//case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
//case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
//}
static void (*const primitive_table[])(u32) =
{
IndexGenerator::AddQuads,
NULL,
IndexGenerator::AddList,
IndexGenerator::AddStrip,
IndexGenerator::AddFan,
IndexGenerator::AddLineList,
IndexGenerator::AddLineStrip,
IndexGenerator::AddPoints,
};
primitive_table[primitive](numVerts);
index += numVerts;
}
// Triangles
void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3)
{
*Tptr++ = index1;
*Tptr++ = index2;
*Tptr++ = index3;
++numT;
}
void IndexGenerator::AddList(u32 const numVerts)
{
auto const numTris = numVerts / 3;
if (!numTris) if (!numTris)
{ {
//if we have less than 3 verts if (2 == numVerts)
if(numVerts == 1)
{ {
// discard // We have two verts. Render a degenerated triangle.
index++; WriteTriangle(index, index + 1, index);
return;
}
else
{
//we have two verts render a degenerated triangle
numTris = 1;
*Tptr++ = index;
*Tptr++ = index+1;
*Tptr++ = index;
} }
} }
else else
{ {
for (int i = 0; i < numTris; i++) for (u32 i = 0; i != numTris; ++i)
{ {
*Tptr++ = index+i*3; WriteTriangle(index + i * 3, index + i * 3 + 1, index + i * 3 + 2);
*Tptr++ = index+i*3+1;
*Tptr++ = index+i*3+2;
} }
int baseRemainingverts = numVerts - numVerts % 3;
auto const base_remaining_verts = numTris * 3;
switch (numVerts % 3) switch (numVerts % 3)
{ {
case 2: case 2:
//whe have 2 remaining verts use strip method // We have 2 remaining verts. Use strip method
*Tptr++ = index + baseRemainingverts - 1; WriteTriangle(
*Tptr++ = index + baseRemainingverts; index + base_remaining_verts - 1,
*Tptr++ = index + baseRemainingverts + 1; index + base_remaining_verts,
numTris++; index + base_remaining_verts + 1);
break; break;
case 1: case 1:
//whe have 1 remaining verts use strip method this is only a conjeture // We have 1 remaining vert. Use strip method this is only a conjeture
*Tptr++ = index + baseRemainingverts - 2; WriteTriangle(
*Tptr++ = index + baseRemainingverts - 1; index + base_remaining_verts - 2,
*Tptr++ = index + baseRemainingverts; index + base_remaining_verts - 1,
numTris++; index + base_remaining_verts);
break; break;
default: default:
break; break;
}; };
} }
index += numVerts;
numT += numTris;
Tadds++;
LastTPrimitive = Prim_List;
} }
void IndexGenerator::AddStrip(int numVerts) void IndexGenerator::AddStrip(u32 const numVerts)
{ {
if(numVerts <= 0) return; if (numVerts < 3)
int numTris = numVerts - 2;
if (numTris < 1)
{ {
//if we have less than 3 verts if (2 == numVerts)
if(numVerts == 1)
{ {
// discard // We have two verts. Render a degenerated triangle.
index++; WriteTriangle(index, index + 1, index);
return;
}
else
{
//we have two verts render a degenerated triangle
numTris = 1;
*Tptr++ = index;
*Tptr++ = index+1;
*Tptr++ = index;
} }
} }
else else
{ {
bool wind = false; bool wind = false;
for (int i = 0; i < numTris; i++) for (u32 i = 2; i < numVerts; ++i)
{ {
*Tptr++ = index+i; WriteTriangle(
*Tptr++ = index+i+(wind?2:1); index + i - 2,
*Tptr++ = index+i+(wind?1:2); index + i - !wind,
wind = !wind; index + i - wind);
wind ^= true;
} }
} }
index += numVerts;
numT += numTris;
Tadds++;
LastTPrimitive = Prim_Strip;
}
void IndexGenerator::AddFan(int numVerts)
{
if(numVerts <= 0) return;
int numTris = numVerts - 2;
if (numTris < 1)
{
//if we have less than 3 verts
if(numVerts == 1)
{
//Discard
index++;
return;
}
else
{
//we have two verts render a degenerated triangle
numTris = 1;
*Tptr++ = index;
*Tptr++ = index+1;
*Tptr++ = index;
}
}
else
{
for (int i = 0; i < numTris; i++)
{
*Tptr++ = index;
*Tptr++ = index+i+1;
*Tptr++ = index+i+2;
}
}
index += numVerts;
numT += numTris;
Tadds++;
LastTPrimitive = Prim_Fan;
} }
void IndexGenerator::AddQuads(int numVerts) void IndexGenerator::AddFan(u32 numVerts)
{ {
if(numVerts <= 0) return; if (numVerts < 3)
int numTris = (numVerts/4)*2;
if (numTris == 0)
{ {
//if we have less than 3 verts if (2 == numVerts)
if(numVerts == 1)
{ {
//discard // We have two verts. Render a degenerated triangle.
index++; WriteTriangle(index, index + 1, index);
return;
}
else
{
if(numVerts == 2)
{
//we have two verts render a degenerated triangle
numTris = 1;
*Tptr++ = index;
*Tptr++ = index + 1;
*Tptr++ = index;
}
else
{
//we have 3 verts render a full triangle
numTris = 1;
*Tptr++ = index;
*Tptr++ = index + 1;
*Tptr++ = index + 2;
}
} }
} }
else else
{ {
for (int i = 0; i < numTris / 2; i++) for (u32 i = 2; i < numVerts; ++i)
{ {
*Tptr++ = index+i*4; WriteTriangle(index, index + i - 1, index + i);
*Tptr++ = index+i*4+1;
*Tptr++ = index+i*4+2;
*Tptr++ = index+i*4;
*Tptr++ = index+i*4+2;
*Tptr++ = index+i*4+3;
} }
int baseRemainingverts = numVerts - numVerts % 4; }
}
void IndexGenerator::AddQuads(u32 numVerts)
{
auto const numQuads = numVerts / 4;
if (!numQuads)
{
if (2 == numVerts)
{
// We have two verts. Render a degenerated triangle.
WriteTriangle(index, index + 1, index);
}
else if (3 == numVerts);
{
// We have 3 verts. Render a full triangle.
WriteTriangle(index, index + 1, index + 2);
}
}
else
{
for (u32 i = 0; i != numQuads; ++i)
{
WriteTriangle(index + i * 4, index + i * 4 + 1, index + i * 4 + 2);
WriteTriangle(index + i * 4, index + i * 4 + 2, index + i * 4 + 3);
}
auto const base_remaining_verts = numQuads * 4;
switch (numVerts % 4) switch (numVerts % 4)
{ {
case 3: case 3:
//whe have 3 remaining verts use strip method // We have 3 remaining verts. Use strip method.
*Tptr++ = index + baseRemainingverts; WriteTriangle(
*Tptr++ = index + baseRemainingverts + 1; index + base_remaining_verts,
*Tptr++ = index + baseRemainingverts + 2; index + base_remaining_verts + 1,
numTris++; index + base_remaining_verts + 2);
break; break;
case 2: case 2:
//whe have 2 remaining verts use strip method // We have 3 remaining verts. Use strip method.
*Tptr++ = index + baseRemainingverts - 1; WriteTriangle(
*Tptr++ = index + baseRemainingverts; index + base_remaining_verts - 1,
*Tptr++ = index + baseRemainingverts + 1; index + base_remaining_verts,
numTris++; index + base_remaining_verts + 1);
break; break;
case 1: case 1:
//whe have 1 remaining verts use strip method this is only a conjeture // We have 1 remaining verts use strip method. This is only a conjeture.
*Tptr++ = index + baseRemainingverts - 2; WriteTriangle(
*Tptr++ = index + baseRemainingverts - 1; base_remaining_verts - 2,
*Tptr++ = index + baseRemainingverts; index + base_remaining_verts - 1,
numTris++; index + base_remaining_verts);
break; break;
default: default:
break; break;
}; };
} }
index += numVerts;
numT += numTris;
Tadds++;
LastTPrimitive = Prim_List;
} }
// Lines
//Lines void IndexGenerator::AddLineList(u32 numVerts)
void IndexGenerator::AddLineList(int numVerts)
{ {
if(numVerts <= 0) return; auto const numLines = numVerts / 2;
int numLines = numVerts / 2; for (u32 i = 0; i != numLines; ++i)
if (!numLines)
{ {
//Discard *Lptr++ = index + i * 2;
index++; *Lptr++ = index + i * 2 + 1;
return; ++numL;
} }
else
{
for (int i = 0; i < numLines; i++)
{
*Lptr++ = index+i*2;
*Lptr++ = index+i*2+1;
}
if((numVerts & 1) != 0)
{
//use line strip for remaining vert
*Lptr++ = index + numLines * 2 - 1;
*Lptr++ = index + numLines * 2;
}
}
index += numVerts;
numL += numLines;
Ladds++;
LastLPrimitive = Prim_List;
} }
void IndexGenerator::AddLineStrip(int numVerts) void IndexGenerator::AddLineStrip(u32 numVerts)
{ {
int numLines = numVerts - 1; for (u32 i = 1; i < numVerts; ++i)
if (numLines <= 0)
{ {
if(numVerts == 1) *Lptr++ = index + i - 1;
{ *Lptr++ = index + i;
index++; ++numL;
} }
return;
}
for (int i = 0; i < numLines; i++)
{
*Lptr++ = index+i;
*Lptr++ = index+i+1;
}
index += numVerts;
numL += numLines;
Ladds++;
LastLPrimitive = Prim_Strip;
} }
// Points
void IndexGenerator::AddPoints(u32 numVerts)
//Points
void IndexGenerator::AddPoints(int numVerts)
{ {
for (int i = 0; i < numVerts; i++) for (u32 i = 0; i != numVerts; ++i)
{ {
*Pptr++ = index+i; *Pptr++ = index + i;
++numP;
} }
index += numVerts;
numP += numVerts;
Padds++;
} }

View File

@ -25,53 +25,58 @@
class IndexGenerator class IndexGenerator
{ {
public: public:
//Init // Init
static void Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr); static void Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr);
//Triangles
static void AddList(int numVerts);
static void AddStrip(int numVerts);
static void AddFan(int numVerts);
static void AddQuads(int numVerts);
//Lines
static void AddLineList(int numVerts);
static void AddLineStrip(int numVerts);
//Points
static void AddPoints(int numVerts);
//Interface
static int GetNumTriangles() {used = true; return numT;}
static int GetNumLines() {used = true;return numL;}
static int GetNumPoints() {used = true;return numP;}
static int GetNumVerts() {return index;} //returns numprimitives
static int GetNumAdds() {return Tadds + Ladds + Padds;}
static int GetTriangleindexLen() {return (int)(Tptr - BASETptr);}
static int GetLineindexLen() {return (int)(Lptr - BASELptr);}
static int GetPointindexLen() {return (int)(Pptr - BASEPptr);}
static void AddIndices(int primitive, u32 numVertices);
// Interface
static u32 GetNumTriangles() {return numT;}
static u32 GetNumLines() {return numL;}
static u32 GetNumPoints() {return numP;}
// returns numprimitives
static u32 GetNumVerts() {return index;}
static u32 GetTriangleindexLen() {return (u32)(Tptr - BASETptr);}
static u32 GetLineindexLen() {return (u32)(Lptr - BASELptr);}
static u32 GetPointindexLen() {return (u32)(Pptr - BASEPptr);}
/*
enum IndexPrimitiveType enum IndexPrimitiveType
{ {
Prim_None = 0, Prim_None = 0,
Prim_List, Prim_List,
Prim_Strip, Prim_Strip,
Prim_Fan Prim_Fan
} ; };
*/
private: private:
// Triangles
static void AddList(u32 numVerts);
static void AddStrip(u32 numVerts);
static void AddFan(u32 numVerts);
static void AddQuads(u32 numVerts);
static void WriteTriangle(u32 index1, u32 index2, u32 index3);
// Lines
static void AddLineList(u32 numVerts);
static void AddLineStrip(u32 numVerts);
// Points
static void AddPoints(u32 numVerts);
static u16 *Tptr; static u16 *Tptr;
static u16 *BASETptr; static u16 *BASETptr;
static u16 *Lptr; static u16 *Lptr;
static u16 *BASELptr; static u16 *BASELptr;
static u16 *Pptr; static u16 *Pptr;
static u16 *BASEPptr; static u16 *BASEPptr;
static int numT; // TODO: redundant variables
static int numL; static u32 numT;
static int numP; static u32 numL;
static int index; static u32 numP;
static int Tadds; static u32 index;
static int Ladds;
static int Padds;
static IndexPrimitiveType LastTPrimitive;
static IndexPrimitiveType LastLPrimitive;
static bool used;
}; };
#endif // _INDEXGENERATOR_H #endif // _INDEXGENERATOR_H

View File

@ -59,34 +59,6 @@ VertexManager::~VertexManager()
ResetBuffer(); ResetBuffer();
} }
void VertexManager::AddIndices(int primitive, int numVertices)
{
//switch (primitive)
//{
//case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
//case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
//case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
//case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
//case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
//case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
//case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
//}
static void (*const primitive_table[])(int) =
{
IndexGenerator::AddQuads,
NULL,
IndexGenerator::AddList,
IndexGenerator::AddStrip,
IndexGenerator::AddFan,
IndexGenerator::AddLineList,
IndexGenerator::AddLineStrip,
IndexGenerator::AddPoints,
};
primitive_table[primitive](numVertices);
}
int VertexManager::GetRemainingSize() int VertexManager::GetRemainingSize()
{ {
return (int)(s_pEndBufferPointer - s_pCurBufferPointer); return (int)(s_pEndBufferPointer - s_pCurBufferPointer);
@ -119,7 +91,7 @@ int VertexManager::GetRemainingVertices(int primitive)
} }
} }
void VertexManager::AddVertices(int primitive, int numVertices) void VertexManager::AddVertices(int primitive, u32 numVertices)
{ {
if (numVertices <= 0) if (numVertices <= 0)
return; return;
@ -132,7 +104,7 @@ void VertexManager::AddVertices(int primitive, int numVertices)
ADDSTAT(stats.thisFrame.numPrims, numVertices); ADDSTAT(stats.thisFrame.numPrims, numVertices);
INCSTAT(stats.thisFrame.numPrimitiveJoins); INCSTAT(stats.thisFrame.numPrimitiveJoins);
AddIndices(primitive, numVertices); IndexGenerator::AddIndices(primitive, numVertices);
} }
void VertexManager::Flush() void VertexManager::Flush()

View File

@ -27,7 +27,7 @@ public:
VertexManager(); VertexManager();
virtual ~VertexManager(); // needs to be virtual for DX11's dtor virtual ~VertexManager(); // needs to be virtual for DX11's dtor
static void AddVertices(int _primitive, int _numVertices); static void AddVertices(int _primitive, u32 _numVertices);
// TODO: protected? // TODO: protected?
static u8 *s_pBaseBufferPointer; static u8 *s_pBaseBufferPointer;
@ -63,7 +63,6 @@ protected:
void DoStateShared(PointerWrap& p); void DoStateShared(PointerWrap& p);
private: private:
static void AddIndices(int primitive, int numVertices);
//virtual void Draw(u32 stride, bool alphapass) = 0; //virtual void Draw(u32 stride, bool alphapass) = 0;
// temp // temp
virtual void vFlush() = 0; virtual void vFlush() = 0;