mirror of https://github.com/PCSX2/pcsx2.git
GregMiscellaneous: zzogl-pg:
* use a size of 4 for the gsvertex array (allow compiler to optimize a % into an and) * Reuse previous computed vertex for _strip & _fan primitives git-svn-id: http://pcsx2.googlecode.com/svn/branches/GregMiscellaneous@3973 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
9f2e92f31b
commit
3c6dd04c19
|
@ -471,14 +471,16 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
Vertex gsvertex[3];
|
||||
u32 rgba;
|
||||
Vertex gsvertex[4]; // circular buffer that contains the vertex
|
||||
Vertex gsTriFanVertex; // Base of triangle fan primitive vertex
|
||||
u32 rgba; // global color for flat shading texture
|
||||
float q;
|
||||
Vertex vertexregs;
|
||||
Vertex vertexregs; // accumulation buffer that collect current vertex data
|
||||
|
||||
int primC; // number of verts current storing
|
||||
int primIndex; // current prim index
|
||||
int nTriFanVert;
|
||||
int nTriFanVert; // remember the index of the base of triangle fan
|
||||
int new_tri_fan; // 1 if we process a new triangle fan primitive. 0 otherwise
|
||||
|
||||
int prac;
|
||||
int dthe;
|
||||
|
@ -512,12 +514,14 @@ typedef struct
|
|||
GSClut clut_buffer;
|
||||
int primNext(int inc = 1)
|
||||
{
|
||||
// Note: ARRAY_SIZE(gsvertex) == 2^n => modulo is replaced by an and instruction
|
||||
return ((primIndex + inc) % ARRAY_SIZE(gsvertex));
|
||||
}
|
||||
|
||||
int primPrev(int dec = 1)
|
||||
{
|
||||
// Note: assert( dec <= ARRAY_SIZE(gsvertex) );
|
||||
// Note: ARRAY_SIZE(gsvertex) == 2^n => modulo is replaced by an and instruction
|
||||
return ((primIndex + (ARRAY_SIZE(gsvertex) - dec)) % ARRAY_SIZE(gsvertex));
|
||||
}
|
||||
|
||||
|
@ -535,7 +539,12 @@ typedef struct
|
|||
vertexregs.y = y;
|
||||
vertexregs.z = z;
|
||||
vertexregs.f = f;
|
||||
gsvertex[primIndex] = vertexregs;
|
||||
if (likely(!new_tri_fan)) {
|
||||
gsvertex[primIndex] = vertexregs;
|
||||
} else {
|
||||
gsTriFanVertex = vertexregs;
|
||||
new_tri_fan = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void add_vertex(u16 x, u16 y, u32 z)
|
||||
|
@ -543,7 +552,12 @@ typedef struct
|
|||
vertexregs.x = x;
|
||||
vertexregs.y = y;
|
||||
vertexregs.z = z;
|
||||
gsvertex[primIndex] = vertexregs;
|
||||
if (likely(!new_tri_fan)) {
|
||||
gsvertex[primIndex] = vertexregs;
|
||||
} else {
|
||||
gsTriFanVertex = vertexregs;
|
||||
new_tri_fan = false;
|
||||
}
|
||||
}
|
||||
} GSinternal;
|
||||
|
||||
|
|
|
@ -309,7 +309,6 @@ void CALLBACK GSreset()
|
|||
|
||||
gs.prac = 1;
|
||||
prim = &gs._prim[0];
|
||||
gs.nTriFanVert = -1;
|
||||
gs.imageTransfer = -1;
|
||||
gs.q = 1;
|
||||
}
|
||||
|
@ -324,7 +323,6 @@ void CALLBACK GSgifSoftReset(u32 mask)
|
|||
|
||||
gs.imageTransfer = -1;
|
||||
gs.q = 1;
|
||||
gs.nTriFanVert = -1;
|
||||
}
|
||||
|
||||
s32 CALLBACK GSinit()
|
||||
|
|
|
@ -305,12 +305,14 @@ void __gifCall GIFRegHandlerPRIM(const u32 *data)
|
|||
|
||||
|
||||
gs.primC = 0;
|
||||
prim->prim = (data[0]) & 0x7;
|
||||
gs._prim[0].prim = (data[0]) & 0x7;
|
||||
gs._prim[1].prim = (data[0]) & 0x7;
|
||||
u16 prim_type = (data[0]) & 0x7;
|
||||
prim->prim = prim_type;
|
||||
gs._prim[0].prim = prim_type;
|
||||
gs._prim[1].prim = prim_type;
|
||||
gs._prim[1]._val = (data[0] >> 3) & 0xff;
|
||||
|
||||
gs.nTriFanVert = gs.primIndex;
|
||||
gs.new_tri_fan = !(prim_type ^ PRIM_TRIANGLE_FAN);
|
||||
ZZKick->DirtyValidPrevPrim();
|
||||
|
||||
Prim();
|
||||
}
|
||||
|
|
|
@ -57,18 +57,11 @@ void __forceinline Kick::KickVertex(bool adc)
|
|||
if (++gs.primC >= (int)g_primmult[prim->prim])
|
||||
{
|
||||
if (!adc && NoHighlights(prim->ctxt)) DrawPrim(prim->prim);
|
||||
else DirtyValidPrevPrim();
|
||||
|
||||
gs.primC -= g_primsub[prim->prim];
|
||||
|
||||
gs.primIndex = gs.primNext();
|
||||
if (prim->prim == 5)
|
||||
{
|
||||
/* tri fans need special processing */
|
||||
if (gs.nTriFanVert == gs.primIndex) gs.primIndex = gs.primNext();
|
||||
}
|
||||
} else {
|
||||
gs.primIndex = gs.primNext();
|
||||
}
|
||||
gs.primIndex = gs.primNext();
|
||||
}
|
||||
|
||||
template<bool DO_Z_FOG>
|
||||
|
@ -111,7 +104,7 @@ void Kick::Set_Vertex(VertexGPU *p, Vertex & gsvertex)
|
|||
__forceinline void Kick::Output_Vertex(VertexGPU vert, u32 id)
|
||||
{
|
||||
#ifdef WRITE_PRIM_LOGS
|
||||
ZZLog::Prim_Log("%c%d(%d): xyzf=(%4d,%4d,0x%x,%3d), rgba=0x%8.8x, stq = (%2.5f,%2.5f,%2.5f)\n",
|
||||
ZZLog::Prim_Log("%c%d(%d): xyzf=(%4d,%4d,0x%x,%3d), rgba=0x%8.8x, stq = (%2.5f,%2.5f,%2.5f)",
|
||||
id == 0 ? '*' : ' ', id, prim->prim, vert.x / 8, vert.y / 8, vert.z, vert.f / 128,
|
||||
vert.rgba, Clamp(vert.s, -10, 10), Clamp(vert.t, -10, 10), Clamp(vert.q, -10, 10));
|
||||
#endif
|
||||
|
@ -140,35 +133,70 @@ void Kick::DrawPrim(u32 prim_type)
|
|||
u32 last;
|
||||
switch(prim_type) {
|
||||
case PRIM_POINT:
|
||||
assert(gs.primC >= 1);
|
||||
|
||||
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primIndex]);
|
||||
curvb.nCount ++;
|
||||
break;
|
||||
|
||||
case PRIM_LINE:
|
||||
case PRIM_LINE_STRIP:
|
||||
assert(gs.primC >= 2);
|
||||
|
||||
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev()]);
|
||||
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primIndex]);
|
||||
curvb.nCount += 2;
|
||||
break;
|
||||
|
||||
case PRIM_TRIANGLE:
|
||||
case PRIM_TRIANGLE_STRIP:
|
||||
case PRIM_TRIANGLE_FAN:
|
||||
assert(gs.primC >= 3);
|
||||
case PRIM_LINE_STRIP:
|
||||
if (likely(ValidPrevPrim)) {
|
||||
assert(curvb.nCount >= 1);
|
||||
p[0] = p[-1];
|
||||
} else {
|
||||
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev()]);
|
||||
ValidPrevPrim = true;
|
||||
}
|
||||
|
||||
Set_Vertex<true>(&p[0], gs.gsvertex[0]);
|
||||
Set_Vertex<true>(&p[1], gs.gsvertex[1]);
|
||||
Set_Vertex<true>(&p[2], gs.gsvertex[2]);
|
||||
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primIndex]);
|
||||
curvb.nCount += 2;
|
||||
break;
|
||||
|
||||
case PRIM_TRIANGLE:
|
||||
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev(2)]);
|
||||
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primPrev()]);
|
||||
Set_Vertex<true>(&p[2], gs.gsvertex[gs.primIndex]);
|
||||
curvb.nCount += 3;
|
||||
break;
|
||||
|
||||
case PRIM_TRIANGLE_STRIP:
|
||||
if (likely(ValidPrevPrim)) {
|
||||
assert(curvb.nCount >= 2);
|
||||
p[0] = p[-2];
|
||||
p[1] = p[-1];
|
||||
} else {
|
||||
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev(2)]);
|
||||
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primPrev()]);
|
||||
ValidPrevPrim = true;
|
||||
}
|
||||
|
||||
Set_Vertex<true>(&p[2], gs.gsvertex[gs.primIndex]);
|
||||
curvb.nCount += 3;
|
||||
break;
|
||||
|
||||
case PRIM_TRIANGLE_FAN:
|
||||
if (likely(ValidPrevPrim)) {
|
||||
assert(curvb.nCount >= 2);
|
||||
VertexGPU* TriFanVert = curvb.pBufferData + gs.nTriFanVert;
|
||||
p[0] = TriFanVert[0];
|
||||
p[1] = p[-1];
|
||||
} else {
|
||||
Set_Vertex<true>(&p[0], gs.gsTriFanVertex);
|
||||
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primPrev(1)]);
|
||||
ValidPrevPrim = true;
|
||||
// Remenber the base for future processing
|
||||
gs.nTriFanVert = curvb.nCount;
|
||||
}
|
||||
|
||||
Set_Vertex<true>(&p[2], gs.gsvertex[gs.primIndex]);
|
||||
curvb.nCount += 3;
|
||||
break;
|
||||
|
||||
case PRIM_SPRITE:
|
||||
assert(gs.primC >= 2);
|
||||
|
||||
prev = gs.primPrev();
|
||||
last = gs.primIndex;
|
||||
|
||||
|
@ -206,17 +234,20 @@ void Kick::DrawPrim(u32 prim_type)
|
|||
default: break;
|
||||
}
|
||||
|
||||
// Print DEBUG info
|
||||
// Print DEBUG info and code assertion
|
||||
switch(prim_type) {
|
||||
case PRIM_TRIANGLE:
|
||||
case PRIM_TRIANGLE_STRIP:
|
||||
case PRIM_TRIANGLE_FAN:
|
||||
assert(gs.primC >= 3);
|
||||
Output_Vertex(p[2],2);
|
||||
case PRIM_LINE:
|
||||
case PRIM_LINE_STRIP:
|
||||
case PRIM_SPRITE:
|
||||
assert(gs.primC >= 2);
|
||||
Output_Vertex(p[1],1);
|
||||
case PRIM_POINT:
|
||||
assert(gs.primC >= 1);
|
||||
Output_Vertex(p[0],0);
|
||||
default: break;
|
||||
}
|
||||
|
|
|
@ -42,12 +42,17 @@ class Kick
|
|||
// template<bool DO_Z_FOG> void Set_Vertex(VertexGPU *p, int i);
|
||||
template<bool DO_Z_FOG> void Set_Vertex(VertexGPU *p, Vertex &gsvertex);
|
||||
void Output_Vertex(VertexGPU vert, u32 id);
|
||||
bool ValidPrevPrim;
|
||||
public:
|
||||
Kick() { }
|
||||
~Kick() { }
|
||||
|
||||
void KickVertex(bool adc);
|
||||
void DrawPrim(u32 i);
|
||||
|
||||
inline void DirtyValidPrevPrim() {
|
||||
ValidPrevPrim = 0;
|
||||
}
|
||||
};
|
||||
extern Kick* ZZKick;
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ class CMemoryTarget
|
|||
int ref;
|
||||
};
|
||||
|
||||
inline CMemoryTarget() : ptex(NULL), starty(0), height(0), realy(0), realheight(0), usedstamp(0), psm(0), cpsm(0), channels(0), clearminy(0), clearmaxy(0), validatecount(0), clutsize(0), clut(NULL) {}
|
||||
inline CMemoryTarget() : ptex(NULL), starty(0), height(0), realy(0), realheight(0), usedstamp(0), psm(0), cpsm(0), channels(0), clearminy(0), clearmaxy(0), validatecount(0), clut(NULL), clutsize(0) {}
|
||||
|
||||
inline CMemoryTarget(const CMemoryTarget& r)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue