fixes to d3d; implemented some allocation counters

This commit is contained in:
aap
2020-04-17 14:34:37 +02:00
parent 7bd6d4649e
commit 206547b404
18 changed files with 293 additions and 40 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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