Module: wine Branch: master Commit: 35dd693a790584f4f14334461e43813d524aa2ba URL: http://source.winehq.org/git/wine.git/?a=commit;h=35dd693a790584f4f14334461e...
Author: Stefan Dösinger stefan@codeweavers.com Date: Sun Apr 8 00:11:09 2007 +0200
d3d9: Fix the circular converted vertex declaration reference.
---
dlls/d3d9/device.c | 7 +++---- dlls/d3d9/tests/visual.c | 7 ------- dlls/d3d9/vertexdeclaration.c | 22 ++++++++++++++++------ 3 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index e9c4078..8fc7511 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -62,8 +62,7 @@ static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9 iface) {
if (ref == 0) { This->inDestruction = TRUE; - if (This->convertedDecl != NULL) - IUnknown_Release(This->convertedDecl); + IDirect3DDevice9_SetVertexDeclaration(iface, NULL); IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface, D3D9CB_DestroySwapChain); IWineD3DDevice_Release(This->WineD3DDevice); HeapFree(GetProcessHeap(), 0, This); @@ -784,14 +783,14 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9 iface, DWORD FVF)
hr = IDirect3DDevice9Impl_CreateVertexDeclaration(iface, elements, &pDecl); if (hr != S_OK) goto exit; - + hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, pDecl); if (hr != S_OK) goto exit; This->convertedDecl = pDecl; - pDecl = NULL;
exit: HeapFree(GetProcessHeap(), 0, elements); + /* If allocated and set correctly, this will reduce the refcount to 0, but not destroy the declaration */ if (pDecl) IUnknown_Release(pDecl); if (hr != S_OK) return hr; } diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 33c4231..bde2a5b 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -259,11 +259,6 @@ static void lighting_test(IDirect3DDevice9 *device)
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE); ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr)); - - /* Hack for a bug in d3d9: SetFVF creates a converted vertex declaration, with a circular refcount. - * This prevents the screen resolution from being restored correctly on device release. Unset the vdecl - */ - IDirect3DDevice9_SetVertexDeclaration(device, NULL); }
static void clear_test(IDirect3DDevice9 *device) @@ -547,8 +542,6 @@ static void fog_test(IDirect3DDevice9 *device) /* Turn off the fog master switch to avoid confusing other tests */ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE); ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr)); - - IDirect3DDevice9_SetVertexDeclaration(device, NULL); }
/* This test verifies the behaviour of cube maps wrt. texture wrapping. diff --git a/dlls/d3d9/vertexdeclaration.c b/dlls/d3d9/vertexdeclaration.c index 84d4359..892f8ac 100644 --- a/dlls/d3d9/vertexdeclaration.c +++ b/dlls/d3d9/vertexdeclaration.c @@ -216,10 +216,15 @@ static ULONG WINAPI IDirect3DVertexDeclaration9Impl_Release(LPDIRECT3DVERTEXDECL TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) { - IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration); - IUnknown_Release(This->parentDevice); - HeapFree(GetProcessHeap(), 0, This->elements); - HeapFree(GetProcessHeap(), 0, This); + IDirect3DDevice9 *parentDevice = This->parentDevice; + BOOL converted = ((IDirect3DDevice9Impl *) parentDevice)->convertedDecl == iface; + + if(!converted) { + IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration); + HeapFree(GetProcessHeap(), 0, This->elements); + HeapFree(GetProcessHeap(), 0, This); + } + IUnknown_Release(parentDevice); } return ref; } @@ -367,12 +372,17 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexDeclaration(LPDIRECT3DDEVICE9 ifa TRACE("(%p) : Relay\n", iface);
if (This->convertedDecl && This->convertedDecl != pDecl) { - IUnknown_Release(This->convertedDecl); + IDirect3DVertexDeclaration9Impl *iDecl = (IDirect3DVertexDeclaration9Impl *) This->convertedDecl; + + /* Will need locking once we claim to be thread safe */ + if(iDecl->ref == 0) { + IUnknown_AddRef(This->convertedDecl); + IUnknown_Release(This->convertedDecl); + } This->convertedDecl = NULL; }
hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, pDeclImpl == NULL ? NULL : pDeclImpl->wineD3DVertexDeclaration); - return hr; }