From 206547b4044818561b649c897aecc5393bbd9cd4 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 17 Apr 2020 14:34:37 +0200 Subject: [PATCH] fixes to d3d; implemented some allocation counters --- src/camera.cpp | 4 ++ src/clump.cpp | 7 ++ src/d3d/d3d.cpp | 35 ++++++++-- src/d3d/d3d8.cpp | 4 +- src/d3d/d3d9.cpp | 4 +- src/d3d/d3ddevice.cpp | 151 ++++++++++++++++++++++++++++++++++++------ src/d3d/d3dimmed.cpp | 38 +++++++++-- src/d3d/rwd3d.h | 2 +- src/d3d/rwd3dimpl.h | 14 ++++ src/engine.cpp | 14 ++++ src/frame.cpp | 4 ++ src/geometry.cpp | 7 ++ src/image.cpp | 4 ++ src/light.cpp | 4 ++ src/raster.cpp | 6 +- src/rwobjects.h | 24 +++++++ src/texture.cpp | 7 ++ src/world.cpp | 4 ++ 18 files changed, 293 insertions(+), 40 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index b07983e..6901dee 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -12,6 +12,8 @@ namespace rw { +int32 Camera::numAllocated; + PluginList Camera::s_plglist = { sizeof(Camera), sizeof(Camera), nil, nil }; void @@ -279,6 +281,7 @@ Camera::create(void) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; cam->object.object.init(Camera::ID, 0); cam->object.syncCB = cameraSync; cam->beginUpdateCB = defaultBeginUpdateCB; @@ -339,6 +342,7 @@ Camera::destroy(void) if(this->clump) this->inClump.remove(); rwFree(this); + numAllocated--; } void diff --git a/src/clump.cpp b/src/clump.cpp index 24ad720..e164875 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -13,6 +13,9 @@ namespace rw { +int32 Clump::numAllocated; +int32 Atomic::numAllocated; + PluginList Clump::s_plglist = { sizeof(Clump), sizeof(Clump), nil, nil }; PluginList Atomic::s_plglist = { sizeof(Atomic), sizeof(Atomic), nil, nil }; @@ -28,6 +31,7 @@ Clump::create(void) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; clump->object.init(Clump::ID, 0); clump->atomics.init(); clump->lights.init(); @@ -67,6 +71,7 @@ Clump::destroy(void) if(f = this->getFrame(), f) f->destroyHierarchy(); rwFree(this); + numAllocated--; } Clump* @@ -341,6 +346,7 @@ Atomic::create(void) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; atomic->object.object.init(Atomic::ID, 0); atomic->object.syncCB = atomicSync; atomic->geometry = nil; @@ -391,6 +397,7 @@ Atomic::destroy(void) this->inClump.remove(); this->setFrame(nil); rwFree(this); + numAllocated--; } void diff --git a/src/d3d/d3d.cpp b/src/d3d/d3d.cpp index 76f74d7..1416326 100644 --- a/src/d3d/d3d.cpp +++ b/src/d3d/d3d.cpp @@ -116,9 +116,6 @@ enum { }; #endif -void addVidmemRaster(Raster *raster); -void removeVidmemRaster(Raster *raster); - // stolen from d3d8to9 static uint32 calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format) @@ -190,6 +187,8 @@ createIndexBuffer(uint32 length) #ifdef RW_D3D9 IDirect3DIndexBuffer9 *ibuf; d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0); + if(ibuf) + d3d9Globals.numIndexBuffers++; return ibuf; #else return rwNewT(uint8, length, MEMDUR_EVENT | ID_DRIVER); @@ -226,11 +225,16 @@ unlockIndices(void *indexBuffer) } void* -createVertexBuffer(uint32 length, uint32 fvf, int32 pool) +createVertexBuffer(uint32 length, uint32 fvf, bool dynamic) { #ifdef RW_D3D9 IDirect3DVertexBuffer9 *vbuf; - d3ddevice->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, (D3DPOOL)pool, &vbuf, 0); + if(dynamic) + d3ddevice->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, fvf, D3DPOOL_DEFAULT, &vbuf, 0); + else + d3ddevice->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, D3DPOOL_MANAGED, &vbuf, 0); + if(vbuf) + d3d9Globals.numVertexBuffers++; return vbuf; #else (void)fvf; @@ -275,6 +279,8 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format) IDirect3DTexture9 *tex; d3ddevice->CreateTexture(width, height, numlevels, 0, (D3DFORMAT)format, D3DPOOL_MANAGED, &tex, nil); + if(tex) + d3d9Globals.numTextures++; return tex; #else int32 w = width; @@ -344,7 +350,8 @@ deleteObject(void *object) return; #ifdef RW_D3D9 IUnknown *unk = (IUnknown*)object; - unk->Release(); + if(unk->Release() != 0) + printf("something wasn't destroyed\n"); #else rwFree(object); #endif @@ -489,6 +496,15 @@ rasterCreateTexture(Raster *raster) if(natras->format == D3DFMT_P8) natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER); levels = Raster::calculateNumLevels(raster->width, raster->height); +// HACK +// raster <- image has to be done differently to be compatible with RW +// just delete texture here for the moment +if(natras->texture){ + deleteObject(natras->texture); + d3d9Globals.numTextures--; + natras->texture = nil; +} + assert(natras->texture == nil); natras->texture = createTexture(raster->width, raster->height, raster->format & Raster::MIPMAP ? levels : 1, natras->format); @@ -513,7 +529,10 @@ rasterCreateCameraTexture(Raster *raster) raster->format & Raster::MIPMAP ? levels : 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil); + assert(natras->texture == nil); natras->texture = tex; + assert(natras->texture && "couldn't create d3d camera texture"); + d3d9Globals.numTextures++; addVidmemRaster(raster); } @@ -900,8 +919,10 @@ destroyNativeRaster(void *object, int32 offset, int32) #ifdef RW_D3D9 destroyD3D9Raster(raster); #endif - if(natras->texture) + if(natras->texture){ deleteObject(natras->texture); + d3d9Globals.numTextures--; + } rwFree(natras->palette); return object; } diff --git a/src/d3d/d3d8.cpp b/src/d3d/d3d8.cpp index 40756da..601415f 100644 --- a/src/d3d/d3d8.cpp +++ b/src/d3d/d3d8.cpp @@ -151,7 +151,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32) unlockIndices(inst->indexBuffer); inst->managed = 1; - inst->vertexBuffer = createVertexBuffer(inst->stride*inst->numVertices, 0, D3DPOOL_MANAGED); + inst->vertexBuffer = createVertexBuffer(inst->stride*inst->numVertices, 0, false); uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); stream->read(verts, inst->stride*inst->numVertices); unlockVertices(inst->vertexBuffer); @@ -357,7 +357,7 @@ defaultInstanceCB(Geometry *geo, InstanceData *inst) inst->stride = getStride(geo->flags, geo->numTexCoordSets); inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride, - inst->vertexShader, D3DPOOL_MANAGED); + inst->vertexShader, false); inst->managed = 1; uint8 *dst = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); diff --git a/src/d3d/d3d9.cpp b/src/d3d/d3d9.cpp index a4f75ed..ea374ba 100644 --- a/src/d3d/d3d9.cpp +++ b/src/d3d/d3d9.cpp @@ -197,7 +197,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32) continue; // TODO: unset managed flag when using morph targets. // also uses different buffer type and locks differently - s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, 0, D3DPOOL_MANAGED); + s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, 0, false); uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); stream->read(verts, s->stride*header->totalNumVertex); unlockVertices(s->vertexBuffer); @@ -521,7 +521,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) assert(header->vertexDeclaration == nil); header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl); - s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, D3DPOOL_MANAGED); + s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, false); }else getDeclaration(header->vertexDeclaration, dcl); diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index 85be0c2..e4bf4b0 100644 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -34,6 +34,18 @@ static VidmemRaster *vidmemRasters; void addVidmemRaster(Raster *raster); void removeVidmemRaster(Raster *raster); +// Same thing for dynamic vertex buffers +struct DynamicVB +{ + uint32 length; + uint32 fvf; + IDirect3DVertexBuffer9 **buf; + DynamicVB *next; +}; +static DynamicVB *dynamicVBs; +void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); +void removeDynamicVB(IDirect3DVertexBuffer9 **buf); + struct RwRasterStateCache { Raster *raster; Texture::Addressing addressingU; @@ -215,7 +227,7 @@ getSamplerState(uint32 stage, uint32 type, uint32 *value) // Bring D3D device in accordance with saved render states (after a reset) static void -resetD3d9Device(void) +restoreD3d9Device(void) { int32 i; uint32 s, t; @@ -579,6 +591,7 @@ createVertexShader(void *csosrc) void *shdr; if(d3ddevice->CreateVertexShader((DWORD*)csosrc, (IDirect3DVertexShader9**)&shdr) == D3D_OK) return shdr; + d3d9Globals.numVertexShaders++; return nil; } @@ -588,6 +601,7 @@ createPixelShader(void *csosrc) void *shdr; if(d3ddevice->CreatePixelShader((DWORD*)csosrc, (IDirect3DPixelShader9**)&shdr) == D3D_OK) return shdr; + d3d9Globals.numPixelShaders++; return nil; } @@ -680,6 +694,8 @@ endUpdate(Camera *cam) d3ddevice->EndScene(); } +// Manage video memory + void addVidmemRaster(Raster *raster) { @@ -713,8 +729,11 @@ releaseVidmemRasters(void) raster = vmr->raster; natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); if(raster->type == Raster::CAMERATEXTURE){ - deleteObject(natras->texture); - natras->texture = nil; + if(natras->texture){ + deleteObject(natras->texture); + d3d9Globals.numTextures--; + natras->texture = nil; + } } } } @@ -736,10 +755,88 @@ recreateVidmemRasters(void) D3DUSAGE_RENDERTARGET, (D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil); natras->texture = tex; + if(natras->texture) + d3d9Globals.numTextures++; } } } +void +addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf) +{ + DynamicVB *dvb = rwNewT(DynamicVB, 1, ID_DRIVER | MEMDUR_EVENT); + dvb->length = length; + dvb->fvf = fvf; + dvb->buf = buf; + dvb->next = dynamicVBs; + dynamicVBs = dvb; +} + +void +removeDynamicVB(IDirect3DVertexBuffer9 **buf) +{ + DynamicVB **p, *dvb; + for(p = &dynamicVBs; *p; p = &(*p)->next) + if((*p)->buf == buf) + goto found; + return; +found: + dvb = *p; + *p = dvb->next; + rwFree(dvb); +} + +static void +releaseDynamicVBs(void) +{ + DynamicVB *dvb; + for(dvb = dynamicVBs; dvb; dvb = dvb->next){ + if(*dvb->buf){ + deleteObject(*dvb->buf); + d3d9Globals.numVertexBuffers--; + *dvb->buf = nil; + } + } +} + +static void +recreateDynamicVBs(void) +{ + DynamicVB *dvb; + for(dvb = dynamicVBs; dvb; dvb = dvb->next){ + *dvb->buf = (IDirect3DVertexBuffer9*)createVertexBuffer(dvb->length, dvb->fvf, true); + if(*dvb->buf) + d3d9Globals.numVertexBuffers++; + } +} + +static void +releaseVideoMemory(void) +{ + int32 i; + for(i = 0; i < MAXNUMSTAGES; i++) + d3ddevice->SetTexture(i, nil); + d3ddevice->SetVertexDeclaration(nil); + d3ddevice->SetVertexShader(nil); + d3ddevice->SetPixelShader(nil); + d3ddevice->SetIndices(nil); + for(i = 0; i < 2; i++) + d3ddevice->SetStreamSource(0, nil, 0, 0); + + releaseVidmemRasters(); + releaseDynamicVBs(); +} + +static void +restoreVideoMemory(void) +{ + recreateDynamicVBs(); + // important that we get all raster back before restoring state + recreateVidmemRasters(); + + restoreD3d9Device(); +} + static void clearCamera(Camera *cam, RGBA *col, uint32 mode) { @@ -760,11 +857,9 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode) d3d9Globals.present.BackBufferWidth = r.right; d3d9Globals.present.BackBufferHeight = r.bottom; - releaseVidmemRasters(); + releaseVideoMemory(); d3d::d3ddevice->Reset(&d3d9Globals.present); - // important that we get all raster back before restoring state - recreateVidmemRasters(); - resetD3d9Device(); + restoreVideoMemory(); } d3ddevice->Clear(0, 0, mode, c, 1.0f, 0); @@ -783,11 +878,9 @@ showRaster(Raster *raster) res = d3ddevice->TestCooperativeLevel(); // lost while being minimized, not reset once we're back if(res == D3DERR_DEVICENOTRESET){ - releaseVidmemRasters(); + releaseVideoMemory(); d3d::d3ddevice->Reset(&d3d9Globals.present); - // important that we get all raster back before restoring state - recreateVidmemRasters(); - resetD3d9Device(); + restoreVideoMemory(); } } } @@ -965,7 +1058,9 @@ found: static int closeD3D(void) { - d3d9Globals.d3d9->Release(); + ULONG ref = d3d9Globals.d3d9->Release(); + if(ref != 0) + printf("IDirect3D9_Release did not destroy\n"); d3d9Globals.d3d9 = nil; return 1; } @@ -984,21 +1079,21 @@ startD3D(void) D3DFORMAT format, zformat; format = d3d9Globals.modes[d3d9Globals.currentMode].mode.Format; + bool windowed = !(d3d9Globals.modes[d3d9Globals.currentMode].flags & VIDEOMODEEXCLUSIVE); + // Use window size in windowed mode, otherwise get size from video mode - if(d3d9Globals.modes[d3d9Globals.currentMode].flags & VIDEOMODEEXCLUSIVE){ - // this will be much better for restoring after iconification - SetWindowLong(d3d9Globals.window, GWL_STYLE, WS_POPUP); - width = d3d9Globals.modes[d3d9Globals.currentMode].mode.Width; - height = d3d9Globals.modes[d3d9Globals.currentMode].mode.Height; - }else{ + if(windowed){ RECT rect; GetClientRect(d3d9Globals.window, &rect); width = rect.right - rect.left; height = rect.bottom - rect.top; + }else{ + // this will be much better for restoring after iconification + SetWindowLong(d3d9Globals.window, GWL_STYLE, WS_POPUP); + width = d3d9Globals.modes[d3d9Globals.currentMode].mode.Width; + height = d3d9Globals.modes[d3d9Globals.currentMode].mode.Height; } - bool windowed = !(d3d9Globals.modes[d3d9Globals.currentMode].flags & VIDEOMODEEXCLUSIVE); - // See if we can get an alpha channel if(format == D3DFMT_X8R8G8B8){ if(d3d9Globals.d3d9->CheckDeviceType(d3d9Globals.adapter, D3DDEVTYPE_HAL, format, D3DFMT_A8R8G8B8, windowed) == D3D_OK) @@ -1029,6 +1124,9 @@ startD3D(void) d3d9Globals.present.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // d3d9Globals.present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + assert(d3d::d3ddevice == nil); + + BOOL icon = IsIconic(d3d9Globals.window); IDirect3DDevice9 *dev; hr = d3d9Globals.d3d9->CreateDevice(d3d9Globals.adapter, D3DDEVTYPE_HAL, d3d9Globals.window, vp, &d3d9Globals.present, &dev); @@ -1047,6 +1145,13 @@ initD3D(void) // TODO: do some real stuff here + d3d9Globals.numTextures = 0; + d3d9Globals.numVertexShaders = 0; + d3d9Globals.numPixelShaders = 0; + d3d9Globals.numVertexBuffers = 0; + d3d9Globals.numIndexBuffers = 0; + d3d9Globals.numVertexDeclarations = 0; + d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); rwStateCache.alphafunc = ALPHAGREATEREQUAL; d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10); @@ -1229,7 +1334,11 @@ termD3D(void) closeIm3D(); closeIm2D(); - d3d::d3ddevice->Release(); + releaseVideoMemory(); + + ULONG ref = d3d::d3ddevice->Release(); + if(ref != 0) + printf("IDirect3D9Device_Release did not destroy\n"); d3d::d3ddevice = nil; return 1; } diff --git a/src/d3d/d3dimmed.cpp b/src/d3d/d3dimmed.cpp index 9a55bd6..d6f84fc 100644 --- a/src/d3d/d3dimmed.cpp +++ b/src/d3d/d3dimmed.cpp @@ -46,16 +46,30 @@ openIm2D(void) D3DDECL_END() }; d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im2ddecl); - im2dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertex), 0, D3DPOOL_MANAGED); + assert(im2ddecl); + d3d9Globals.numVertexDeclarations++; + im2dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertex), 0, true); + assert(im2dvertbuf); + addDynamicVB(NUMVERTICES*sizeof(Im2DVertex), 0, &im2dvertbuf); im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16)); + assert(im2dindbuf); } void closeIm2D(void) { deleteObject(im2ddecl); + d3d9Globals.numVertexDeclarations--; + im2ddecl = nil; + + removeDynamicVB(&im2dvertbuf); deleteObject(im2dvertbuf); + d3d9Globals.numVertexBuffers--; + im2dvertbuf = nil; + deleteObject(im2dindbuf); + d3d9Globals.numIndexBuffers--; + im2dindbuf = nil; } static Im2DVertex tmpprimbuf[3]; @@ -86,7 +100,7 @@ im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices) // TODO: error return; } - uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_NOSYSLOCK); + uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_DISCARD); memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex)); unlockVertices(im2dvertbuf); @@ -138,7 +152,7 @@ im2DRenderIndexedPrimitive(PrimitiveType primType, memcpy(lockedindices, indices, numIndices*sizeof(uint16)); unlockIndices(im2dindbuf); - uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_NOSYSLOCK); + uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_DISCARD); memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex)); unlockVertices(im2dvertbuf); @@ -199,16 +213,30 @@ openIm3D(void) D3DDECL_END() }; d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im3ddecl); - im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, D3DPOOL_MANAGED); + assert(im3ddecl); + d3d9Globals.numVertexDeclarations++; + im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, true); + assert(im3dvertbuf); + addDynamicVB(NUMVERTICES*sizeof(Im3DVertex), 0, &im3dvertbuf); im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16)); + assert(im3dindbuf); } void closeIm3D(void) { deleteObject(im3ddecl); + d3d9Globals.numVertexDeclarations--; + im3ddecl = nil; + + removeDynamicVB(&im3dvertbuf); deleteObject(im3dvertbuf); + d3d9Globals.numVertexBuffers--; + im3dvertbuf = nil; + deleteObject(im3dindbuf); + d3d9Globals.numIndexBuffers--; + im3dindbuf = nil; } void @@ -225,7 +253,7 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world) convMatrix(&d3dworld, world); d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&d3dworld); - uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_NOSYSLOCK); + uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_DISCARD); memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex)); unlockVertices(im3dvertbuf); diff --git a/src/d3d/rwd3d.h b/src/d3d/rwd3d.h index f4b619d..1e8518b 100644 --- a/src/d3d/rwd3d.h +++ b/src/d3d/rwd3d.h @@ -144,7 +144,7 @@ extern int vertFormatMap[]; void *createIndexBuffer(uint32 length); uint16 *lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags); void unlockIndices(void *indexBuffer); -void *createVertexBuffer(uint32 length, uint32 fvf, int32 pool); +void *createVertexBuffer(uint32 length, uint32 fvf, bool dynamic); uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags); void unlockVertices(void *vertexBuffer); void *createTexture(int32 width, int32 height, int32 levels, uint32 format); diff --git a/src/d3d/rwd3dimpl.h b/src/d3d/rwd3dimpl.h index f42b2a2..b72c3b9 100644 --- a/src/d3d/rwd3dimpl.h +++ b/src/d3d/rwd3dimpl.h @@ -39,10 +39,24 @@ struct D3d9Globals int currentMode; D3DPRESENT_PARAMETERS present; + + int numTextures; + int numVertexShaders; + int numPixelShaders; + int numVertexBuffers; + int numIndexBuffers; + int numVertexDeclarations; }; extern D3d9Globals d3d9Globals; +void addVidmemRaster(Raster *raster); +void removeVidmemRaster(Raster *raster); + +void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); // NB: don't share this pointer +void removeDynamicVB(IDirect3DVertexBuffer9 **buf); + + int findFormatDepth(uint32 format); void destroyD3D9Raster(Raster *raster); #endif diff --git a/src/engine.cpp b/src/engine.cpp index 0b5650e..c8efd2f 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -87,6 +87,20 @@ Engine::init(void) Raster::registerModule(); Texture::registerModule(); + // TODO: reset all allocation counts here. or maybe do that in modules? + Frame::numAllocated = 0; + Image::numAllocated = 0; + Raster::numAllocated = 0; + Texture::numAllocated = 0; + TexDictionary::numAllocated = 0; + Geometry::numAllocated = 0; + Material::numAllocated = 0; + Atomic::numAllocated = 0; + Light::numAllocated = 0; + Camera::numAllocated = 0; + Clump::numAllocated = 0; + World::numAllocated = 0; + // driver plugin attach ps2::registerPlatformPlugins(); xbox::registerPlatformPlugins(); diff --git a/src/frame.cpp b/src/frame.cpp index 0ff9b6f..93a26e5 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -12,6 +12,8 @@ namespace rw { +int32 Frame::numAllocated; + PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil }; static void *frameOpen(void *object, int32 offset, int32 size) { engine->frameDirtyList.init(); return object; } static void *frameClose(void *object, int32 offset, int32 size) { return object; } @@ -30,6 +32,7 @@ Frame::create(void) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; f->object.init(Frame::ID, 0); f->objectList.init(); f->child = nil; @@ -60,6 +63,7 @@ Frame::destroy(void) for(Frame *f = this->child; f; f = f->next) f->object.parent = nil; rwFree(this); + numAllocated--; } void diff --git a/src/geometry.cpp b/src/geometry.cpp index 1db174c..5a993f1 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -15,6 +15,9 @@ namespace rw { +int32 Geometry::numAllocated; +int32 Material::numAllocated; + PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil }; PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), nil, nil }; @@ -29,6 +32,7 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; geo->object.init(Geometry::ID, 0); geo->flags = flags & 0xFF00FFFF; geo->numTexCoordSets = (flags & 0xFF0000) >> 16; @@ -96,6 +100,7 @@ Geometry::destroy(void) rwFree(this->meshHeader); this->matList.deinit(); rwFree(this); + numAllocated--; } } @@ -856,6 +861,7 @@ Material::create(void) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; mat->texture = nil; memset(&mat->color, 0xFF, 4); mat->surfaceProps = defaultSurfaceProps; @@ -891,6 +897,7 @@ Material::destroy(void) if(this->texture) this->texture->destroy(); rwFree(this); + numAllocated--; } } diff --git a/src/image.cpp b/src/image.cpp index 847a0fb..7521595 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -19,6 +19,8 @@ namespace rw { +int32 Image::numAllocated; + // TODO: full 16 bit support Image* @@ -29,6 +31,7 @@ Image::create(int32 width, int32 height, int32 depth) RWERROR((ERR_ALLOC, sizeof(Image))); return nil; } + numAllocated++; img->flags = 0; img->width = width; img->height = height; @@ -45,6 +48,7 @@ Image::destroy(void) { this->free(); rwFree(this); + numAllocated--; } void diff --git a/src/light.cpp b/src/light.cpp index 7220256..4283c81 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -12,6 +12,8 @@ namespace rw { +int32 Light::numAllocated; + PluginList Light::s_plglist = { sizeof(Light), sizeof(Light), nil, nil }; static void @@ -34,6 +36,7 @@ Light::create(int32 type) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; light->object.object.init(Light::ID, type); light->object.syncCB = lightSync; light->radius = 0.0f; @@ -67,6 +70,7 @@ Light::destroy(void) this->inClump.remove(); // we do not remove from world, be careful rwFree(this); + numAllocated--; } void diff --git a/src/raster.cpp b/src/raster.cpp index 3115bfe..496b993 100644 --- a/src/raster.cpp +++ b/src/raster.cpp @@ -19,6 +19,8 @@ namespace rw { +int32 Raster::numAllocated; + struct RasterGlobals { int32 sp; @@ -57,6 +59,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf // TODO: pass arguments through to the driver and create the raster there Raster *raster = (Raster*)rwMalloc(s_plglist.size, MEMDUR_EVENT); // TODO assert(raster != nil); + numAllocated++; raster->parent = raster; raster->offsetX = 0; raster->offsetY = 0; @@ -92,9 +95,8 @@ void Raster::destroy(void) { s_plglist.destruct(this); -// delete[] this->texels; -// delete[] this->palette; rwFree(this); + numAllocated--; } uint8* diff --git a/src/rwobjects.h b/src/rwobjects.h index 8372703..14a558d 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -55,6 +55,8 @@ struct Frame Frame *next; Frame *root; + static int32 numAllocated; + static Frame *create(void); Frame *cloneHierarchy(void); void destroy(void); @@ -130,6 +132,8 @@ struct Image uint8 *pixels; uint8 *palette; + static int32 numAllocated; + static Image *create(int32 width, int32 height, int32 depth); void destroy(void); void allocate(void); @@ -186,6 +190,8 @@ struct Raster Raster *parent; int32 offsetX, offsetY; + static int32 numAllocated; + static Raster *create(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0); void subRaster(Raster *parent, Rect *r); @@ -273,6 +279,8 @@ struct Texture uint32 filterAddressing; // VVVVUUUU FFFFFFFF int32 refCount; + static int32 numAllocated; + static Texture *create(Raster *raster); void destroy(void); static Texture *fromDict(LLLink *lnk){ @@ -318,6 +326,8 @@ struct Material Pipeline *pipeline; int32 refCount; + static int32 numAllocated; + static Material *create(void); Material *clone(void); void destroy(void); @@ -415,6 +425,8 @@ struct Geometry int32 refCount; + static int32 numAllocated; + static Geometry *create(int32 numVerts, int32 numTris, uint32 flags); void destroy(void); void lock(int32 lockFlags); @@ -510,6 +522,8 @@ struct Atomic World *world; ObjectWithFrame::Sync originalSync; + static int32 numAllocated; + static Atomic *create(void); Atomic *clone(void); void destroy(void); @@ -562,6 +576,8 @@ struct Light World *world; ObjectWithFrame::Sync originalSync; + static int32 numAllocated; + static Light *create(int32 type); void destroy(void); void setFrame(Frame *f) { this->object.setFrame(f); } @@ -648,6 +664,8 @@ struct Camera void (*originalBeginUpdate)(Camera*); void (*originalEndUpdate)(Camera*); + static int32 numAllocated; + static Camera *create(void); Camera *clone(void); void destroy(void); @@ -684,6 +702,8 @@ struct Clump World *world; + static int32 numAllocated; + static Clump *create(void); Clump *clone(void); void destroy(void); @@ -721,6 +741,8 @@ struct World LinkList lights; // these have positions (type >= 0x80) LinkList directionalLights; // these do not (type < 0x80) + static int32 numAllocated; + static World *create(void); void destroy(void); void addLight(Light *light); @@ -736,6 +758,8 @@ struct TexDictionary Object object; LinkList textures; + static int32 numAllocated; + static TexDictionary *create(void); void destroy(void); int32 count(void) { return this->textures.count(); } diff --git a/src/texture.cpp b/src/texture.cpp index e292e2d..b9eecea 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -21,6 +21,9 @@ namespace rw { +int32 Texture::numAllocated; +int32 TexDictionary::numAllocated; + PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil }; PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil }; PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil }; @@ -87,6 +90,7 @@ TexDictionary::create(void) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; dict->object.init(TexDictionary::ID, 0); dict->textures.init(); s_plglist.construct(dict); @@ -102,6 +106,7 @@ TexDictionary::destroy(void) Texture::fromDict(lnk)->destroy(); s_plglist.destruct(this); rwFree(this); + numAllocated--; } void @@ -228,6 +233,7 @@ Texture::create(Raster *raster) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; tex->dict = nil; tex->inDict.init(); memset(tex->name, 0, 32); @@ -250,6 +256,7 @@ Texture::destroy(void) if(this->raster) this->raster->destroy(); rwFree(this); + numAllocated--; } } diff --git a/src/world.cpp b/src/world.cpp index fdee70b..126714f 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -13,6 +13,8 @@ namespace rw { +int32 World::numAllocated = 0; + PluginList World::s_plglist = { sizeof(World), sizeof(World), nil, nil }; World* @@ -23,6 +25,7 @@ World::create(void) RWERROR((ERR_ALLOC, s_plglist.size)); return nil; } + numAllocated++; world->object.init(World::ID, 0); world->lights.init(); world->directionalLights.init(); @@ -35,6 +38,7 @@ World::destroy(void) { s_plglist.destruct(this); rwFree(this); + numAllocated--; } void