mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
further work on ps2 pipelines
This commit is contained in:
parent
4d461dbfbd
commit
db00759b8c
@ -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");
|
||||
}
|
||||
|
@ -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++)
|
||||
|
192
src/ps2.cpp
192
src/ps2.cpp
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user