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
|
typedef struct
|
||||||
{
|
{
|
||||||
Vertex gsvertex[3];
|
Vertex gsvertex[4]; // circular buffer that contains the vertex
|
||||||
u32 rgba;
|
Vertex gsTriFanVertex; // Base of triangle fan primitive vertex
|
||||||
|
u32 rgba; // global color for flat shading texture
|
||||||
float q;
|
float q;
|
||||||
Vertex vertexregs;
|
Vertex vertexregs; // accumulation buffer that collect current vertex data
|
||||||
|
|
||||||
int primC; // number of verts current storing
|
int primC; // number of verts current storing
|
||||||
int primIndex; // current prim index
|
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 prac;
|
||||||
int dthe;
|
int dthe;
|
||||||
|
@ -512,12 +514,14 @@ typedef struct
|
||||||
GSClut clut_buffer;
|
GSClut clut_buffer;
|
||||||
int primNext(int inc = 1)
|
int primNext(int inc = 1)
|
||||||
{
|
{
|
||||||
|
// Note: ARRAY_SIZE(gsvertex) == 2^n => modulo is replaced by an and instruction
|
||||||
return ((primIndex + inc) % ARRAY_SIZE(gsvertex));
|
return ((primIndex + inc) % ARRAY_SIZE(gsvertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
int primPrev(int dec = 1)
|
int primPrev(int dec = 1)
|
||||||
{
|
{
|
||||||
// Note: assert( dec <= ARRAY_SIZE(gsvertex) );
|
// 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));
|
return ((primIndex + (ARRAY_SIZE(gsvertex) - dec)) % ARRAY_SIZE(gsvertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +539,12 @@ typedef struct
|
||||||
vertexregs.y = y;
|
vertexregs.y = y;
|
||||||
vertexregs.z = z;
|
vertexregs.z = z;
|
||||||
vertexregs.f = f;
|
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)
|
inline void add_vertex(u16 x, u16 y, u32 z)
|
||||||
|
@ -543,7 +552,12 @@ typedef struct
|
||||||
vertexregs.x = x;
|
vertexregs.x = x;
|
||||||
vertexregs.y = y;
|
vertexregs.y = y;
|
||||||
vertexregs.z = z;
|
vertexregs.z = z;
|
||||||
gsvertex[primIndex] = vertexregs;
|
if (likely(!new_tri_fan)) {
|
||||||
|
gsvertex[primIndex] = vertexregs;
|
||||||
|
} else {
|
||||||
|
gsTriFanVertex = vertexregs;
|
||||||
|
new_tri_fan = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} GSinternal;
|
} GSinternal;
|
||||||
|
|
||||||
|
|
|
@ -309,7 +309,6 @@ void CALLBACK GSreset()
|
||||||
|
|
||||||
gs.prac = 1;
|
gs.prac = 1;
|
||||||
prim = &gs._prim[0];
|
prim = &gs._prim[0];
|
||||||
gs.nTriFanVert = -1;
|
|
||||||
gs.imageTransfer = -1;
|
gs.imageTransfer = -1;
|
||||||
gs.q = 1;
|
gs.q = 1;
|
||||||
}
|
}
|
||||||
|
@ -324,7 +323,6 @@ void CALLBACK GSgifSoftReset(u32 mask)
|
||||||
|
|
||||||
gs.imageTransfer = -1;
|
gs.imageTransfer = -1;
|
||||||
gs.q = 1;
|
gs.q = 1;
|
||||||
gs.nTriFanVert = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 CALLBACK GSinit()
|
s32 CALLBACK GSinit()
|
||||||
|
|
|
@ -305,12 +305,14 @@ void __gifCall GIFRegHandlerPRIM(const u32 *data)
|
||||||
|
|
||||||
|
|
||||||
gs.primC = 0;
|
gs.primC = 0;
|
||||||
prim->prim = (data[0]) & 0x7;
|
u16 prim_type = (data[0]) & 0x7;
|
||||||
gs._prim[0].prim = (data[0]) & 0x7;
|
prim->prim = prim_type;
|
||||||
gs._prim[1].prim = (data[0]) & 0x7;
|
gs._prim[0].prim = prim_type;
|
||||||
|
gs._prim[1].prim = prim_type;
|
||||||
gs._prim[1]._val = (data[0] >> 3) & 0xff;
|
gs._prim[1]._val = (data[0] >> 3) & 0xff;
|
||||||
|
|
||||||
gs.nTriFanVert = gs.primIndex;
|
gs.new_tri_fan = !(prim_type ^ PRIM_TRIANGLE_FAN);
|
||||||
|
ZZKick->DirtyValidPrevPrim();
|
||||||
|
|
||||||
Prim();
|
Prim();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,18 +57,11 @@ void __forceinline Kick::KickVertex(bool adc)
|
||||||
if (++gs.primC >= (int)g_primmult[prim->prim])
|
if (++gs.primC >= (int)g_primmult[prim->prim])
|
||||||
{
|
{
|
||||||
if (!adc && NoHighlights(prim->ctxt)) DrawPrim(prim->prim);
|
if (!adc && NoHighlights(prim->ctxt)) DrawPrim(prim->prim);
|
||||||
|
else DirtyValidPrevPrim();
|
||||||
|
|
||||||
gs.primC -= g_primsub[prim->prim];
|
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>
|
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)
|
__forceinline void Kick::Output_Vertex(VertexGPU vert, u32 id)
|
||||||
{
|
{
|
||||||
#ifdef WRITE_PRIM_LOGS
|
#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,
|
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));
|
vert.rgba, Clamp(vert.s, -10, 10), Clamp(vert.t, -10, 10), Clamp(vert.q, -10, 10));
|
||||||
#endif
|
#endif
|
||||||
|
@ -140,35 +133,70 @@ void Kick::DrawPrim(u32 prim_type)
|
||||||
u32 last;
|
u32 last;
|
||||||
switch(prim_type) {
|
switch(prim_type) {
|
||||||
case PRIM_POINT:
|
case PRIM_POINT:
|
||||||
assert(gs.primC >= 1);
|
|
||||||
|
|
||||||
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primIndex]);
|
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primIndex]);
|
||||||
curvb.nCount ++;
|
curvb.nCount ++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRIM_LINE:
|
case PRIM_LINE:
|
||||||
case PRIM_LINE_STRIP:
|
|
||||||
assert(gs.primC >= 2);
|
|
||||||
|
|
||||||
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev()]);
|
Set_Vertex<true>(&p[0], gs.gsvertex[gs.primPrev()]);
|
||||||
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primIndex]);
|
Set_Vertex<true>(&p[1], gs.gsvertex[gs.primIndex]);
|
||||||
curvb.nCount += 2;
|
curvb.nCount += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRIM_TRIANGLE:
|
case PRIM_LINE_STRIP:
|
||||||
case PRIM_TRIANGLE_STRIP:
|
if (likely(ValidPrevPrim)) {
|
||||||
case PRIM_TRIANGLE_FAN:
|
assert(curvb.nCount >= 1);
|
||||||
assert(gs.primC >= 3);
|
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[gs.primIndex]);
|
||||||
Set_Vertex<true>(&p[1], gs.gsvertex[1]);
|
curvb.nCount += 2;
|
||||||
Set_Vertex<true>(&p[2], gs.gsvertex[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;
|
curvb.nCount += 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRIM_SPRITE:
|
case PRIM_SPRITE:
|
||||||
assert(gs.primC >= 2);
|
|
||||||
|
|
||||||
prev = gs.primPrev();
|
prev = gs.primPrev();
|
||||||
last = gs.primIndex;
|
last = gs.primIndex;
|
||||||
|
|
||||||
|
@ -206,17 +234,20 @@ void Kick::DrawPrim(u32 prim_type)
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print DEBUG info
|
// Print DEBUG info and code assertion
|
||||||
switch(prim_type) {
|
switch(prim_type) {
|
||||||
case PRIM_TRIANGLE:
|
case PRIM_TRIANGLE:
|
||||||
case PRIM_TRIANGLE_STRIP:
|
case PRIM_TRIANGLE_STRIP:
|
||||||
case PRIM_TRIANGLE_FAN:
|
case PRIM_TRIANGLE_FAN:
|
||||||
|
assert(gs.primC >= 3);
|
||||||
Output_Vertex(p[2],2);
|
Output_Vertex(p[2],2);
|
||||||
case PRIM_LINE:
|
case PRIM_LINE:
|
||||||
case PRIM_LINE_STRIP:
|
case PRIM_LINE_STRIP:
|
||||||
case PRIM_SPRITE:
|
case PRIM_SPRITE:
|
||||||
|
assert(gs.primC >= 2);
|
||||||
Output_Vertex(p[1],1);
|
Output_Vertex(p[1],1);
|
||||||
case PRIM_POINT:
|
case PRIM_POINT:
|
||||||
|
assert(gs.primC >= 1);
|
||||||
Output_Vertex(p[0],0);
|
Output_Vertex(p[0],0);
|
||||||
default: break;
|
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, int i);
|
||||||
template<bool DO_Z_FOG> void Set_Vertex(VertexGPU *p, Vertex &gsvertex);
|
template<bool DO_Z_FOG> void Set_Vertex(VertexGPU *p, Vertex &gsvertex);
|
||||||
void Output_Vertex(VertexGPU vert, u32 id);
|
void Output_Vertex(VertexGPU vert, u32 id);
|
||||||
|
bool ValidPrevPrim;
|
||||||
public:
|
public:
|
||||||
Kick() { }
|
Kick() { }
|
||||||
~Kick() { }
|
~Kick() { }
|
||||||
|
|
||||||
void KickVertex(bool adc);
|
void KickVertex(bool adc);
|
||||||
void DrawPrim(u32 i);
|
void DrawPrim(u32 i);
|
||||||
|
|
||||||
|
inline void DirtyValidPrevPrim() {
|
||||||
|
ValidPrevPrim = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
extern Kick* ZZKick;
|
extern Kick* ZZKick;
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ class CMemoryTarget
|
||||||
int ref;
|
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)
|
inline CMemoryTarget(const CMemoryTarget& r)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue