further work on ps2 pipelines

This commit is contained in:
aap 2015-08-02 19:31:01 +02:00
parent 4d461dbfbd
commit db00759b8c
6 changed files with 130 additions and 92 deletions

View File

@ -37,19 +37,19 @@ Pipeline::dump(void)
} }
void void
Pipeline::instance(Atomic *atomic) ObjPipeline::instance(Atomic*)
{ {
fprintf(stderr, "This pipeline can't instance\n"); fprintf(stderr, "This pipeline can't instance\n");
} }
void void
Pipeline::uninstance(Atomic *atomic) ObjPipeline::uninstance(Atomic*)
{ {
fprintf(stderr, "This pipeline can't uninstance\n"); fprintf(stderr, "This pipeline can't uninstance\n");
} }
void void
Pipeline::render(Atomic *atomic) ObjPipeline::render(Atomic*)
{ {
fprintf(stderr, "This pipeline can't render\n"); fprintf(stderr, "This pipeline can't render\n");
} }

View File

@ -549,7 +549,7 @@ skinRights(void *object, int32, int32, uint32)
void void
registerSkinPlugin(void) registerSkinPlugin(void)
{ {
Pipeline *defpipe = new Pipeline(PLATFORM_NULL); ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
defpipe->pluginID = ID_SKIN; defpipe->pluginID = ID_SKIN;
defpipe->pluginData = 1; defpipe->pluginData = 1;
for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++)
@ -881,7 +881,7 @@ getSizeMaterialMatFX(void *object, int32 offset, int32)
void void
registerMatFXPlugin(void) registerMatFXPlugin(void)
{ {
Pipeline *defpipe = new Pipeline(PLATFORM_NULL); ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
defpipe->pluginID = ID_MATFX; defpipe->pluginID = ID_MATFX;
defpipe->pluginData = 0; defpipe->pluginData = 0;
for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++)

View File

@ -240,47 +240,6 @@ PipeAttribute attribWeights = {
AT_V4_32 | AT_RW AT_V4_32 | AT_RW
}; };
MatPipeline::MatPipeline(uint32 platform)
: rw::Pipeline(platform)
{
for(int i = 0; i < 10; i++)
this->attribs[i] = NULL;
}
void
MatPipeline::dump(void)
{
if(this->platform != PLATFORM_PS2)
return;
PipeAttribute *a;
for(uint i = 0; i < nelem(this->attribs); i++){
a = this->attribs[i];
if(a)
printf("%d %s: %x\n", i, a->name, a->attrib);
}
printf("stride: %x\n", this->inputStride);
printf("triSCount: %x\n", this->triStripCount);
printf("triLCount: %x\n", this->triListCount);
printf("vifOffset: %x\n", this->vifOffset);
}
void
MatPipeline::setTriBufferSizes(uint32 inputStride, uint32 stripCount)
{
this->inputStride = inputStride;
this->triListCount = stripCount/12*12;
PipeAttribute *a;
for(uint i = 0; i < nelem(this->attribs); i++){
a = this->attribs[i];
if(a && a->attrib & AT_RW)
goto brokenout;
}
this->triStripCount = stripCount/4*4;
return;
brokenout:
this->triStripCount = (stripCount-2)/4*4+2;
}
static uint32 static uint32
attribSize(uint32 unpack) attribSize(uint32 unpack)
{ {
@ -383,16 +342,57 @@ instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n)
return (uint32*)p; return (uint32*)p;
} }
MatPipeline::MatPipeline(uint32 platform)
: rw::Pipeline(platform), instanceCB(NULL)
{
for(int i = 0; i < 10; i++)
this->attribs[i] = NULL;
}
void
MatPipeline::dump(void)
{
if(this->platform != PLATFORM_PS2)
return;
PipeAttribute *a;
for(uint i = 0; i < nelem(this->attribs); i++){
a = this->attribs[i];
if(a)
printf("%d %s: %x\n", i, a->name, a->attrib);
}
printf("stride: %x\n", this->inputStride);
printf("triSCount: %x\n", this->triStripCount);
printf("triLCount: %x\n", this->triListCount);
printf("vifOffset: %x\n", this->vifOffset);
}
void
MatPipeline::setTriBufferSizes(uint32 inputStride, uint32 stripCount)
{
this->inputStride = inputStride;
this->triListCount = stripCount/12*12;
PipeAttribute *a;
for(uint i = 0; i < nelem(this->attribs); i++){
a = this->attribs[i];
if(a && a->attrib & AT_RW)
goto brokenout;
}
this->triStripCount = stripCount/4*4;
return;
brokenout:
this->triStripCount = (stripCount-2)/4*4+2;
}
uint32 markcnt = 0xf790; uint32 markcnt = 0xf790;
static void void
instanceMat(MatPipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m) MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
{ {
PipeAttribute *a; PipeAttribute *a;
uint32 numAttribs = 0; uint32 numAttribs = 0;
uint32 numBrokenAttribs = 0; uint32 numBrokenAttribs = 0;
for(uint i = 0; i < nelem(pipe->attribs); i++) for(uint i = 0; i < nelem(this->attribs); i++)
if(a = pipe->attribs[i]) if(a = this->attribs[i])
if(a->attrib & AT_RW) if(a->attrib & AT_RW)
numBrokenAttribs++; numBrokenAttribs++;
else else
@ -401,23 +401,23 @@ instanceMat(MatPipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m)
uint32 totalVerts = 0; uint32 totalVerts = 0;
uint32 batchVertCount, lastBatchVertCount; uint32 batchVertCount, lastBatchVertCount;
if(g->meshHeader->flags == 1){ // tristrip if(g->meshHeader->flags == 1){ // tristrip
for(uint i = 0; i < m->numIndices; i += pipe->triStripCount-2){ for(uint i = 0; i < m->numIndices; i += this->triStripCount-2){
numBatches++; numBatches++;
totalVerts += m->numIndices-i < pipe->triStripCount ? totalVerts += m->numIndices-i < this->triStripCount ?
m->numIndices-i : pipe->triStripCount; m->numIndices-i : this->triStripCount;
} }
batchVertCount = pipe->triStripCount; batchVertCount = this->triStripCount;
lastBatchVertCount = totalVerts%pipe->triStripCount; lastBatchVertCount = totalVerts%this->triStripCount;
}else{ // trilist }else{ // trilist
numBatches = (m->numIndices+pipe->triListCount-1) / numBatches = (m->numIndices+this->triListCount-1) /
pipe->triListCount; this->triListCount;
totalVerts = m->numIndices; totalVerts = m->numIndices;
batchVertCount = pipe->triListCount; batchVertCount = this->triListCount;
lastBatchVertCount = totalVerts%pipe->triListCount; lastBatchVertCount = totalVerts%this->triListCount;
} }
uint32 batchSize = getBatchSize(pipe, batchVertCount); uint32 batchSize = getBatchSize(this, batchVertCount);
uint32 lastBatchSize = getBatchSize(pipe, lastBatchVertCount); uint32 lastBatchSize = getBatchSize(this, lastBatchVertCount);
uint32 size = 0; uint32 size = 0;
if(numBrokenAttribs == 0) if(numBrokenAttribs == 0)
size = 1 + batchSize*(numBatches-1) + lastBatchSize; size = 1 + batchSize*(numBatches-1) + lastBatchSize;
@ -426,28 +426,26 @@ instanceMat(MatPipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m)
(1+batchSize)*(numBatches-1) + 1+lastBatchSize; (1+batchSize)*(numBatches-1) + 1+lastBatchSize;
/* figure out size and addresses of broken out sections */ /* figure out size and addresses of broken out sections */
uint32 attribPos[nelem(pipe->attribs)]; uint32 attribPos[nelem(this->attribs)];
uint32 size2 = 0; uint32 size2 = 0;
for(uint i = 0; i < nelem(pipe->attribs); i++) for(uint i = 0; i < nelem(this->attribs); i++)
if((a = pipe->attribs[i]) && a->attrib & AT_RW){ if((a = this->attribs[i]) && a->attrib & AT_RW){
attribPos[i] = size2 + size; attribPos[i] = size2 + size;
size2 += QWC(m->numIndices*attribSize(a->attrib)); size2 += QWC(m->numIndices*attribSize(a->attrib));
} }
/*
printf("attribs: %d %d\n", numAttribs, numBrokenAttribs);
printf("numIndices: %d\n", m->numIndices);
printf("%d %d, %x %x\n", numBatches, totalVerts,
batchVertCount, lastBatchVertCount);
printf("%x %x\n", batchSize, lastBatchSize);
printf("size: %x, %x\n", size, size2);
*/
inst->dataSize = (size+size2)<<4; inst->dataSize = (size+size2)<<4;
inst->arePointersFixed = numBrokenAttribs == 0; inst->arePointersFixed = numBrokenAttribs == 0;
// TODO: force alignment // TODO: force alignment
inst->data = new uint8[inst->dataSize]; inst->data = new uint8[inst->dataSize];
/* make array of addresses of broken out sections */
uint8 *datap[nelem(this->attribs)];
uint8 **dp = datap;
for(uint i = 0; i < nelem(this->attribs); i++)
if((a = this->attribs[i]) && a->attrib & AT_RW)
*dp++ = inst->data + attribPos[i]*0x10;
uint32 idx = 0; uint32 idx = 0;
uint32 *p = (uint32*)inst->data; uint32 *p = (uint32*)inst->data;
if(numBrokenAttribs == 0){ if(numBrokenAttribs == 0){
@ -465,13 +463,13 @@ instanceMat(MatPipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m)
bsize = lastBatchSize; bsize = lastBatchSize;
nverts = lastBatchVertCount; nverts = lastBatchVertCount;
} }
for(uint i = 0; i < nelem(pipe->attribs); i++) for(uint i = 0; i < nelem(this->attribs); i++)
if((a = pipe->attribs[i]) && a->attrib & AT_RW){ if((a = this->attribs[i]) && a->attrib & AT_RW){
uint32 atsz = attribSize(a->attrib); uint32 atsz = attribSize(a->attrib);
*p++ = 0x30000000 | QWC(nverts*atsz); *p++ = 0x30000000 | QWC(nverts*atsz);
*p++ = attribPos[i]; *p++ = attribPos[i];
*p++ = 0x01000100 | *p++ = 0x01000100 |
pipe->inputStride; // STCYCL this->inputStride; // STCYCL
*p++ = (a->attrib&0xFF004000) *p++ = (a->attrib&0xFF004000)
| 0x8000 | nverts << 16 | i; // UNPACK | 0x8000 | nverts << 16 | i; // UNPACK
@ -492,12 +490,12 @@ instanceMat(MatPipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m)
*p++ = 0x0; *p++ = 0x0;
} }
for(uint i = 0; i < nelem(pipe->attribs); i++) for(uint i = 0; i < nelem(this->attribs); i++)
if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){ if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){
*p++ = 0x07000000 | markcnt++; // MARK (SA: NOP) *p++ = 0x07000000 | markcnt++; // MARK (SA: NOP)
*p++ = 0x05000000; // STMOD *p++ = 0x05000000; // STMOD
*p++ = 0x01000100 | *p++ = 0x01000100 |
pipe->inputStride; // STCYCL this->inputStride; // STCYCL
*p++ = (a->attrib&0xFF004000) *p++ = (a->attrib&0xFF004000)
| 0x8000 | nverts << 16 | i; // UNPACK | 0x8000 | nverts << 16 | i; // UNPACK
@ -529,10 +527,14 @@ instanceMat(MatPipeline *pipe, Geometry *g, InstanceData *inst, Mesh *m)
*p++ = 0x06000000; // MSKPATH3; SA: FLUSH *p++ = 0x06000000; // MSKPATH3; SA: FLUSH
} }
} }
if(instanceCB)
instanceCB(this, g, m, datap, numBrokenAttribs);
} }
ObjPipeline::ObjPipeline(uint32 platform) ObjPipeline::ObjPipeline(uint32 platform)
: rw::Pipeline(platform), groupPipeline(NULL) { } : rw::ObjPipeline(platform), groupPipeline(NULL) { }
void void
ObjPipeline::instance(Atomic *atomic) ObjPipeline::instance(Atomic *atomic)
@ -552,12 +554,11 @@ ObjPipeline::instance(Atomic *atomic)
MatPipeline *m; MatPipeline *m;
m = this->groupPipeline ? m = this->groupPipeline ?
m = this->groupPipeline : this->groupPipeline :
(MatPipeline*)mesh->material->pipeline; (MatPipeline*)mesh->material->pipeline;
if(m == NULL) if(m == NULL)
m = defaultMatPipe; m = defaultMatPipe;
instanceMat(m, geometry, instance, mesh); m->instance(geometry, instance, mesh);
//printf("\n");
} }
geometry->geoflags |= Geometry::NATIVE; geometry->geoflags |= Geometry::NATIVE;
} }
@ -628,6 +629,8 @@ makeDefaultPipeline(void)
return defaultObjPipe; return defaultObjPipe;
} }
static void skinInstanceCB(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
ObjPipeline* ObjPipeline*
makeSkinPipeline(void) makeSkinPipeline(void)
{ {
@ -642,6 +645,7 @@ makeSkinPipeline(void)
uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2); uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2);
pipe->setTriBufferSizes(5, vertCount); pipe->setTriBufferSizes(5, vertCount);
pipe->vifOffset = pipe->inputStride*vertCount; pipe->vifOffset = pipe->inputStride*vertCount;
pipe->instanceCB = skinInstanceCB;
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
opipe->pluginID = ID_SKIN; opipe->pluginID = ID_SKIN;
@ -760,6 +764,36 @@ getSizeNativeSkin(void *object, int32 offset)
return size; return size;
} }
static void
skinInstanceCB(MatPipeline *pipe, Geometry *g, Mesh *m, uint8 **data, int32 n)
{
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
if(skin == NULL || n < 1)
return;
float *weights = (float*)data[0];
uint32 *indices = (uint32*)data[0];
uint16 j;
for(uint32 i = 0; i < m->numIndices; i++){
j = m->indices[i];
*weights++ = skin->weights[j*4+0];
*indices &= ~0x3FF;
*indices++ |= skin->indices[j*4+0] && skin->weights[j*4+0] ?
(skin->indices[j*4+0]+1) << 2 : 0;
*weights++ = skin->weights[j*4+1];
*indices &= ~0x3FF;
*indices++ |= skin->indices[j*4+1] && skin->weights[j*4+1] ?
(skin->indices[j*4+1]+1) << 2 : 0;
*weights++ = skin->weights[j*4+2];
*indices &= ~0x3FF;
*indices++ |= skin->indices[j*4+2] && skin->weights[j*4+2] ?
(skin->indices[j*4+2]+1) << 2 : 0;
*weights++ = skin->weights[j*4+3];
*indices &= ~0x3FF;
*indices++ |= skin->indices[j*4+3] && skin->weights[j*4+3] ?
(skin->indices[j*4+3]+1) << 2 : 0;
}
}
// ADC // ADC
@ -825,7 +859,7 @@ atomicPDSRights(void *object, int32, int32, uint32 data)
{ {
Atomic *a = (Atomic*)object; Atomic *a = (Atomic*)object;
// TODO: lookup pipeline by data // TODO: lookup pipeline by data
a->pipeline = new Pipeline(PLATFORM_PS2); a->pipeline = new ObjPipeline(PLATFORM_PS2);
a->pipeline->pluginID = ID_PDS; a->pipeline->pluginID = ID_PDS;
a->pipeline->pluginData = data; a->pipeline->pluginData = data;
} }

View File

@ -226,7 +226,7 @@ struct MatFXGlobals
{ {
int32 atomicOffset; int32 atomicOffset;
int32 materialOffset; int32 materialOffset;
Pipeline *pipelines[NUM_PLATFORMS]; ObjPipeline *pipelines[NUM_PLATFORMS];
}; };
extern MatFXGlobals matFXGlobals; extern MatFXGlobals matFXGlobals;
void registerMatFXPlugin(void); void registerMatFXPlugin(void);
@ -323,7 +323,7 @@ struct Skin
struct SkinGlobals struct SkinGlobals
{ {
int32 offset; int32 offset;
Pipeline *pipelines[NUM_PLATFORMS]; ObjPipeline *pipelines[NUM_PLATFORMS];
}; };
extern SkinGlobals skinGlobals; extern SkinGlobals skinGlobals;
void registerSkinPlugin(void); void registerSkinPlugin(void);
@ -351,7 +351,7 @@ struct Atomic : PluginBase<Atomic>, Object
Frame *frame; Frame *frame;
Geometry *geometry; Geometry *geometry;
Clump *clump; Clump *clump;
Pipeline *pipeline; ObjPipeline *pipeline;
Atomic(void); Atomic(void);
Atomic(Atomic *a); Atomic(Atomic *a);

View File

@ -19,7 +19,12 @@ public:
Pipeline(Pipeline *p); Pipeline(Pipeline *p);
~Pipeline(void); ~Pipeline(void);
virtual void dump(void); virtual void dump(void);
// TODO: this is bad, maybe split obj and mat pipelines? };
class ObjPipeline : public Pipeline
{
public:
ObjPipeline(uint32 platform) : Pipeline(platform) {}
virtual void instance(Atomic *atomic); virtual void instance(Atomic *atomic);
virtual void uninstance(Atomic *atomic); virtual void uninstance(Atomic *atomic);
virtual void render(Atomic *atomic); virtual void render(Atomic *atomic);

View File

@ -45,6 +45,7 @@ public:
uint32 inputStride; uint32 inputStride;
uint32 triStripCount, triListCount; uint32 triStripCount, triListCount;
PipeAttribute *attribs[10]; PipeAttribute *attribs[10];
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
static uint32 getVertCount(uint32 top, uint32 inAttribs, static uint32 getVertCount(uint32 top, uint32 inAttribs,
uint32 outAttribs, uint32 outBufs) { uint32 outAttribs, uint32 outBufs) {
@ -53,13 +54,11 @@ public:
MatPipeline(uint32 platform); MatPipeline(uint32 platform);
virtual void dump(void); virtual void dump(void);
// virtual void instance(Atomic *atomic);
// virtual void uninstance(Atomic *atomic);
/// virtual void render(Atomic *atomic);
void setTriBufferSizes(uint32 inputStride, uint32 stripCount); void setTriBufferSizes(uint32 inputStride, uint32 stripCount);
void instance(Geometry *g, InstanceData *inst, Mesh *m);
}; };
class ObjPipeline : public rw::Pipeline class ObjPipeline : public rw::ObjPipeline
{ {
public: public:
MatPipeline *groupPipeline; MatPipeline *groupPipeline;