GregMiscellaneous: zzogl-pg:

* Regoup drawing primitive in one function
* Increase the inital size of the vertex buffer
* various clean


git-svn-id: http://pcsx2.googlecode.com/svn/branches/GregMiscellaneous@3965 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut@gmail.com 2010-10-23 23:02:19 +00:00
parent 02efc340e8
commit b199b57a76
5 changed files with 112 additions and 254 deletions

View File

@ -94,14 +94,7 @@ void __gifCall GIFPackedRegHandlerXYZF2(const u32* data)
gs.gsvertex[gs.primIndex] = gs.vertexregs; gs.gsvertex[gs.primIndex] = gs.vertexregs;
gs.primIndex = gs.primNext(); gs.primIndex = gs.primNext();
if (data[3] & 0x8000) ZZKick->KickVertex(!!(data[3]>>31));
{
ZZKick->KickVERTEX3();
}
else
{
ZZKick->KickVERTEX2();
}
} }
void __gifCall GIFPackedRegHandlerXYZ2(const u32* data) void __gifCall GIFPackedRegHandlerXYZ2(const u32* data)
@ -113,14 +106,7 @@ void __gifCall GIFPackedRegHandlerXYZ2(const u32* data)
gs.gsvertex[gs.primIndex] = gs.vertexregs; gs.gsvertex[gs.primIndex] = gs.vertexregs;
gs.primIndex = gs.primNext(); gs.primIndex = gs.primNext();
if (data[3] & 0x8000) ZZKick->KickVertex(!!(data[3]>>31));
{
ZZKick->KickVERTEX3();
}
else
{
ZZKick->KickVERTEX2();
}
} }
void __gifCall GIFPackedRegHandlerFOG(const u32* data) void __gifCall GIFPackedRegHandlerFOG(const u32* data)
@ -368,7 +354,7 @@ void __gifCall GIFRegHandlerXYZF2(const u32* data)
gs.gsvertex[gs.primIndex] = gs.vertexregs; gs.gsvertex[gs.primIndex] = gs.vertexregs;
gs.primIndex = gs.primNext(); gs.primIndex = gs.primNext();
ZZKick->KickVERTEX2(); ZZKick->KickVertex(false);
} }
void __gifCall GIFRegHandlerXYZ2(const u32* data) void __gifCall GIFRegHandlerXYZ2(const u32* data)
@ -380,7 +366,7 @@ void __gifCall GIFRegHandlerXYZ2(const u32* data)
gs.gsvertex[gs.primIndex] = gs.vertexregs; gs.gsvertex[gs.primIndex] = gs.vertexregs;
gs.primIndex = gs.primNext(); gs.primIndex = gs.primNext();
ZZKick->KickVERTEX2(); ZZKick->KickVertex(false);
} }
void __gifCall GIFRegHandlerTEX0_1(const u32* data) void __gifCall GIFRegHandlerTEX0_1(const u32* data)
@ -428,7 +414,7 @@ void __gifCall GIFRegHandlerXYZF3(const u32* data)
gs.gsvertex[gs.primIndex] = gs.vertexregs; gs.gsvertex[gs.primIndex] = gs.vertexregs;
gs.primIndex = gs.primNext(); gs.primIndex = gs.primNext();
ZZKick->KickVERTEX3(); ZZKick->KickVertex(true);
} }
void __gifCall GIFRegHandlerXYZ3(const u32* data) void __gifCall GIFRegHandlerXYZ3(const u32* data)
@ -440,7 +426,7 @@ void __gifCall GIFRegHandlerXYZ3(const u32* data)
gs.gsvertex[gs.primIndex] = gs.vertexregs; gs.gsvertex[gs.primIndex] = gs.vertexregs;
gs.primIndex = gs.primNext(); gs.primIndex = gs.primNext();
ZZKick->KickVERTEX3(); ZZKick->KickVertex(true);
} }
void __gifCall GIFRegHandlerNOP(const u32* data) void __gifCall GIFRegHandlerNOP(const u32* data)

View File

@ -47,40 +47,17 @@ void Prim()
// Hackish and should be replaced. // Hackish and should be replaced.
bool __forceinline NoHighlights(int i) bool __forceinline NoHighlights(int i)
{ {
// This is hack-code, I still in search of correct reason, why some triangles should not be drawn.
int dummy = 0;
u32 resultA = prim->iip + (2 * (prim->tme)) + (4 * (prim->fge)) + (8 * (prim->abe)) + (16 * (prim->aa1)) + (32 * (prim->fst)) + (64 * (prim->ctxt)) + (128 * (prim->fix));
const pixTest curtest = vb[i].test;
u32 result = curtest.ate + ((curtest.atst) << 1) +((curtest.afail) << 4) + ((curtest.date) << 6) + ((curtest.datm) << 7) + ((curtest.zte) << 8) + ((curtest.ztst)<< 9);
if ((resultA == 0x310a) && (result == 0x0)) return false; // Radiata Stories
//Old code //Old code
return (!(conf.settings().xenosaga_spec) || !vb[i].zbuf.zmsk || prim->iip) ; return (!(conf.settings().xenosaga_spec) || !vb[i].zbuf.zmsk || prim->iip) ;
} }
void Kick::KickVERTEX2() void __forceinline Kick::KickVertex(bool adc)
{ {
FUNCLOG FUNCLOG
if (++gs.primC >= (int)g_primmult[prim->prim])
{
if (NoHighlights(prim->ctxt)) ZZKick->fn(prim->prim);
gs.primC -= g_primsub[prim->prim];
}
}
void Kick::KickVERTEX3()
{
FUNCLOG
if (++gs.primC >= (int)g_primmult[prim->prim]) if (++gs.primC >= (int)g_primmult[prim->prim])
{ {
if (!adc && NoHighlights(prim->ctxt)) DrawPrim(prim->prim);
gs.primC -= g_primsub[prim->prim]; gs.primC -= g_primsub[prim->prim];
if (prim->prim == 5) if (prim->prim == 5)
@ -91,24 +68,7 @@ void Kick::KickVERTEX3()
} }
} }
void __forceinline Kick::KickVertex(bool adc) void Kick::SET_VERTEX(VertexGPU *p, int i)
{
FUNCLOG
if (++gs.primC >= (int)g_primmult[prim->prim])
{
if (!adc && NoHighlights(prim->ctxt)) fn(prim->prim);
gs.primC -= g_primsub[prim->prim];
if (adc && prim->prim == 5)
{
/* tri fans need special processing */
if (gs.nTriFanVert == gs.primIndex) gs.primIndex = gs.primNext();
}
}
}
inline void Kick::SET_VERTEX(VertexGPU *p, int i)
{ {
p->move_x(gs.gsvertex[i], vb[prim->ctxt].offset.x); p->move_x(gs.gsvertex[i], vb[prim->ctxt].offset.x);
p->move_y(gs.gsvertex[i], vb[prim->ctxt].offset.y); p->move_y(gs.gsvertex[i], vb[prim->ctxt].offset.y);
@ -149,134 +109,103 @@ __forceinline void Kick::OUTPUT_VERT(VertexGPU vert, u32 id)
#endif #endif
} }
void Kick::fn(u32 i) void Kick::DrawPrim(u32 prim_type)
{ {
switch (i) VB& curvb = vb[prim->ctxt];
{
case 0: Point(); break;
case 1: Line(); break;
case 2: Line(); break;
case 3: Triangle(); break;
case 4: Triangle(); break;
case 5: TriangleFan(); break;
case 6: Sprite(); break;
default: Dummy(); break;
}
}
void Kick::Point()
{
FUNCLOG
assert(gs.primC >= 1);
VB& curvb = vb[prim->ctxt]; curvb.FlushTexData();
curvb.FlushTexData(); if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
{
assert(vb[prim->ctxt].nCount == 0);
Flush(!prim->ctxt);
}
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) // check enough place is left for the biggest primitive (sprite)
{ // This function is unlikely to be called so do not inline it.
assert(vb[prim->ctxt].nCount == 0); if (unlikely(curvb.nCount + 6 > curvb.nNumVertices))
Flush(!prim->ctxt); curvb.IncreaseVertexBuffer();
}
curvb.NotifyWrite(1); VertexGPU* p = curvb.pBufferData + curvb.nCount;
int last = gs.primNext(2); u32 next;
u32 last;
switch(prim_type) {
case PRIM_POINT:
assert(gs.primC >= 1);
VertexGPU* p = curvb.pBufferData + curvb.nCount; SET_VERTEX(&p[0], gs.primNext(2));
SET_VERTEX(&p[0], last); curvb.nCount ++;
curvb.nCount++; break;
OUTPUT_VERT(p[0], 0); case PRIM_LINE:
} case PRIM_LINE_STRIP:
assert(gs.primC >= 2);
void Kick::Line() SET_VERTEX(&p[0], gs.primNext());
{ SET_VERTEX(&p[1], gs.primNext(2));
FUNCLOG curvb.nCount += 2;
assert(gs.primC >= 2); break;
VB& curvb = vb[prim->ctxt];
curvb.FlushTexData(); case PRIM_TRIANGLE:
case PRIM_TRIANGLE_STRIP:
case PRIM_TRIANGLE_FAN:
assert(gs.primC >= 3);
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) SET_VERTEX(&p[0], 0);
{ SET_VERTEX(&p[1], 1);
assert(vb[prim->ctxt].nCount == 0); SET_VERTEX(&p[2], 2);
Flush(!prim->ctxt); curvb.nCount += 3;
} break;
curvb.NotifyWrite(2); case PRIM_SPRITE:
assert(gs.primC >= 2);
int next = gs.primNext(); next = gs.primNext();
int last = gs.primNext(2); last = gs.primNext(2);
VertexGPU* p = curvb.pBufferData + curvb.nCount; // sprite is too small and AA shows lines (tek4, Mana Khemia)
SET_VERTEX(&p[0], next); gs.gsvertex[last].x += (4 * AA.x);
SET_VERTEX(&p[1], last); gs.gsvertex[last].y += (4 * AA.y);
curvb.nCount += 2; // might be bad sprite (KH dialog text)
//if( gs.gsvertex[next].x == gs.gsvertex[last].x || gs.gsvertex[next].y == gs.gsvertex[last].y )
//return;
OUTPUT_VERT(p[0], 0); // process sprite as 2 triangles. The common diagonal is 0,1 and 3,4
OUTPUT_VERT(p[1], 1); SetKickVertex(&p[0], gs.gsvertex[last], next);
} SetKickVertex(&p[1], gs.gsvertex[last], last);
// Duplicate the vertex
p[3] = p[0];
p[2] = p[0];
p[4] = p[1];
p[5] = p[1];
// Move some vertex x coord to create the others corners of the sprite
p[2].s = p[1].s;
p[2].x = p[1].x;
p[5].s = p[0].s;
p[5].x = p[0].x;
void Kick::Triangle() curvb.nCount += 6;
{ break;
FUNCLOG
assert(gs.primC >= 3);
VB& curvb = vb[prim->ctxt];
curvb.FlushTexData(); default: break;
}
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) // Print DEBUG info
{ switch(prim_type) {
assert(vb[prim->ctxt].nCount == 0); case PRIM_TRIANGLE:
Flush(!prim->ctxt); case PRIM_TRIANGLE_STRIP:
} case PRIM_TRIANGLE_FAN:
OUTPUT_VERT(p[2],2);
curvb.NotifyWrite(3); case PRIM_LINE:
case PRIM_LINE_STRIP:
VertexGPU* p = curvb.pBufferData + curvb.nCount; case PRIM_SPRITE:
SET_VERTEX(&p[0], 0); OUTPUT_VERT(p[1],1);
SET_VERTEX(&p[1], 1); case PRIM_POINT:
SET_VERTEX(&p[2], 2); OUTPUT_VERT(p[0],0);
default: break;
curvb.nCount += 3; }
OUTPUT_VERT(p[0], 0);
OUTPUT_VERT(p[1], 1);
OUTPUT_VERT(p[2], 2);
}
void Kick::TriangleFan()
{
FUNCLOG
assert(gs.primC >= 3);
VB& curvb = vb[prim->ctxt];
curvb.FlushTexData();
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
{
assert(vb[prim->ctxt].nCount == 0);
Flush(!prim->ctxt);
}
curvb.NotifyWrite(3);
VertexGPU* p = curvb.pBufferData + curvb.nCount;
SET_VERTEX(&p[0], 0);
SET_VERTEX(&p[1], 1);
SET_VERTEX(&p[2], 2);
curvb.nCount += 3;
// add 1 to skip the first vertex
if (gs.primIndex == gs.nTriFanVert) gs.primIndex = gs.primNext();
OUTPUT_VERT(p[0], 0);
OUTPUT_VERT(p[1], 1);
OUTPUT_VERT(p[2], 2);
} }
void Kick::SetKickVertex(VertexGPU *p, Vertex &v, int next) void Kick::SetKickVertex(VertexGPU *p, Vertex &v, int next)
@ -285,57 +214,3 @@ void Kick::SetKickVertex(VertexGPU *p, Vertex &v, int next)
p->move_z(v, vb[prim->ctxt].zprimmask); p->move_z(v, vb[prim->ctxt].zprimmask);
p->move_fog(v); p->move_fog(v);
} }
void Kick::Sprite()
{
FUNCLOG
assert(gs.primC >= 2);
VB& curvb = vb[prim->ctxt];
curvb.FlushTexData();
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
{
assert(vb[prim->ctxt].nCount == 0);
Flush(!prim->ctxt);
}
curvb.NotifyWrite(6);
int next = gs.primNext();
int last = gs.primNext(2);
// sprite is too small and AA shows lines (tek4, Mana Khemia)
gs.gsvertex[last].x += (4 * AA.x);
gs.gsvertex[last].y += (4 * AA.y);
// might be bad sprite (KH dialog text)
//if( gs.gsvertex[next].x == gs.gsvertex[last].x || gs.gsvertex[next].y == gs.gsvertex[last].y )
//return;
VertexGPU* p = curvb.pBufferData + curvb.nCount;
// process sprite as 2 triangles. The common diagonal is 0,1 and 3,4
SetKickVertex(&p[0], gs.gsvertex[last], next);
SetKickVertex(&p[1], gs.gsvertex[last], last);
// Duplicate the vertex
p[3] = p[0];
p[2] = p[0];
p[4] = p[1];
p[5] = p[1];
// Move some vertex x coord to create the others corners of the sprite
p[2].s = p[1].s;
p[2].x = p[1].x;
p[5].s = p[0].s;
p[5].x = p[0].x;
curvb.nCount += 6;
OUTPUT_VERT(p[0], 0);
OUTPUT_VERT(p[1], 1);
}
void Kick::Dummy()
{
FUNCLOG
//ZZLog::Greg_Log("Kicking bad primitive: %.8x\n", *(u32*)prim);
}

View File

@ -25,6 +25,17 @@
extern bool __forceinline NoHighlights(int i); extern bool __forceinline NoHighlights(int i);
enum PRIM_TYPE {
PRIM_POINT = 0,
PRIM_LINE,
PRIM_LINE_STRIP,
PRIM_TRIANGLE,
PRIM_TRIANGLE_STRIP,
PRIM_TRIANGLE_FAN,
PRIM_SPRITE,
PRIM_DUMMY
};
class Kick class Kick
{ {
private: private:
@ -36,16 +47,7 @@ class Kick
~Kick() { } ~Kick() { }
void KickVertex(bool adc); void KickVertex(bool adc);
void KickVERTEX2(); void DrawPrim(u32 i);
void KickVERTEX3();
void fn(u32 i);
void Point();
void Line();
void Triangle();
void TriangleFan();
void Sprite();
void Dummy();
}; };
extern Kick* ZZKick; extern Kick* ZZKick;

View File

@ -77,22 +77,17 @@ public:
inline void FlushTexClutting() ; inline void FlushTexClutting() ;
inline void FlushTexSetNewVars(u32 psm) ; inline void FlushTexSetNewVars(u32 psm) ;
// notify VB that nVerts need to be written to pbuf // Increase the size of pbuf
inline void NotifyWrite(int nVerts) void IncreaseVertexBuffer()
{ {
assert(pBufferData != NULL && nCount <= nNumVertices && nVerts > 0); assert(pBufferData != NULL && nCount > nNumVertices);
VertexGPU* ptemp = (VertexGPU*)_aligned_malloc(sizeof(VertexGPU) * nNumVertices * 2, 256);
if (nCount + nVerts > nNumVertices) memcpy_amd(ptemp, pBufferData, sizeof(VertexGPU) * nCount);
{ nNumVertices *= 2;
// recreate except with a bigger count assert(nCount <= nNumVertices);
VertexGPU* ptemp = (VertexGPU*)_aligned_malloc(sizeof(VertexGPU) * nNumVertices * 2, 256); _aligned_free(pBufferData);
memcpy_amd(ptemp, pBufferData, sizeof(VertexGPU) * nCount); pBufferData = ptemp;
nNumVertices *= 2; }
assert(nCount + nVerts <= nNumVertices);
_aligned_free(pBufferData);
pBufferData = ptemp;
}
}
void Init(int nVerts) void Init(int nVerts)
{ {

View File

@ -32,7 +32,7 @@
#define GL_TEXTURE_RECTANGLE GL_TEXTURE_RECTANGLE_NV #define GL_TEXTURE_RECTANGLE GL_TEXTURE_RECTANGLE_NV
#endif #endif
#define VB_BUFFERSIZE 0x400 #define VB_BUFFERSIZE 0x4000
// all textures have this width // all textures have this width
extern int GPU_TEXWIDTH; extern int GPU_TEXWIDTH;