From db00759b8c3b8bc13692ccb562d0dc998604f510 Mon Sep 17 00:00:00 2001 From: aap Date: Sun, 2 Aug 2015 19:31:01 +0200 Subject: [PATCH] further work on ps2 pipelines --- src/pipeline.cpp | 6 +- src/plugins.cpp | 4 +- src/ps2.cpp | 192 ++++++++++++++++++++++++++++------------------- src/rwobjects.h | 6 +- src/rwpipeline.h | 7 +- src/rwps2.h | 7 +- 6 files changed, 130 insertions(+), 92 deletions(-) diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 02aa35d..a05573c 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -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"); } diff --git a/src/plugins.cpp b/src/plugins.cpp index 2883faf..ac89125 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -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++) diff --git a/src/ps2.cpp b/src/ps2.cpp index ddac10c..f1488b8 100644 --- a/src/ps2.cpp +++ b/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; } diff --git a/src/rwobjects.h b/src/rwobjects.h index 25ca75f..889b6b4 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -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, Object Frame *frame; Geometry *geometry; Clump *clump; - Pipeline *pipeline; + ObjPipeline *pipeline; Atomic(void); Atomic(Atomic *a); diff --git a/src/rwpipeline.h b/src/rwpipeline.h index c5cc223..861d714 100644 --- a/src/rwpipeline.h +++ b/src/rwpipeline.h @@ -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); diff --git a/src/rwps2.h b/src/rwps2.h index 8b1fde7..3823e72 100644 --- a/src/rwps2.h +++ b/src/rwps2.h @@ -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;