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
Pipeline::instance(Atomic *atomic)
ObjPipeline::instance(Atomic*)
{
fprintf(stderr, "This pipeline can't instance\n");
}
void
Pipeline::uninstance(Atomic *atomic)
ObjPipeline::uninstance(Atomic*)
{
fprintf(stderr, "This pipeline can't uninstance\n");
}
void
Pipeline::render(Atomic *atomic)
ObjPipeline::render(Atomic*)
{
fprintf(stderr, "This pipeline can't render\n");
}

View File

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

View File

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

View File

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

View File

@ -19,7 +19,12 @@ public:
Pipeline(Pipeline *p);
~Pipeline(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 uninstance(Atomic *atomic);
virtual void render(Atomic *atomic);

View File

@ -45,6 +45,7 @@ public:
uint32 inputStride;
uint32 triStripCount, triListCount;
PipeAttribute *attribs[10];
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
static uint32 getVertCount(uint32 top, uint32 inAttribs,
uint32 outAttribs, uint32 outBufs) {
@ -53,13 +54,11 @@ public:
MatPipeline(uint32 platform);
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 instance(Geometry *g, InstanceData *inst, Mesh *m);
};
class ObjPipeline : public rw::Pipeline
class ObjPipeline : public rw::ObjPipeline
{
public:
MatPipeline *groupPipeline;