diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 0555b3a4b13..aa4a49f4745 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -235,7 +235,9 @@ typedef struct IDirect3DVolume9Impl /* IDirect3DVolume9 fields */ IWineD3DVolume *wineD3DVolume; - + + /* If set forward refcounting to this object */ + IUnknown *forwardReference; } IDirect3DVolume9Impl; /* ------------------- */ @@ -548,4 +550,6 @@ extern ULONG WINAPI D3D9CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface extern ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface); +extern ULONG WINAPI D3D9CB_DestroyVolume(IWineD3DVolume *pVolume); + #endif /* __WINE_D3D9_PRIVATE_H */ diff --git a/dlls/d3d9/volume.c b/dlls/d3d9/volume.c index 1575763c1f6..f9ce7fc021c 100644 --- a/dlls/d3d9/volume.c +++ b/dlls/d3d9/volume.c @@ -42,15 +42,13 @@ static HRESULT WINAPI IDirect3DVolume9Impl_QueryInterface(LPDIRECT3DVOLUME9 ifac static ULONG WINAPI IDirect3DVolume9Impl_AddRef(LPDIRECT3DVOLUME9 iface) { IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; - IUnknown *containerParent = NULL; TRACE("(%p)\n", This); - IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent); - if (containerParent) { - /* Forward to the containerParent */ - TRACE("(%p) : Forwarding to %p\n", This, containerParent); - return IUnknown_AddRef(containerParent); + if (This->forwardReference) { + /* Forward refcounting */ + TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference); + return IUnknown_AddRef(This->forwardReference); } else { /* No container, handle our own refcounting */ ULONG ref = InterlockedIncrement(&This->ref); @@ -61,15 +59,13 @@ static ULONG WINAPI IDirect3DVolume9Impl_AddRef(LPDIRECT3DVOLUME9 iface) { static ULONG WINAPI IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) { IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; - IUnknown *containerParent = NULL; TRACE("(%p)\n", This); - IWineD3DVolume_GetContainerParent(This->wineD3DVolume, &containerParent); - if (containerParent) { - /* Forward to the containerParent */ - TRACE("(%p) : Forwarding to %p\n", This, containerParent); - return IUnknown_Release(containerParent); + if (This->forwardReference) { + /* Forward refcounting */ + TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference); + return IUnknown_Release(This->forwardReference); } else { /* No container, handle our own refcounting */ ULONG ref = InterlockedDecrement(&This->ref); @@ -228,7 +224,18 @@ HRESULT WINAPI D3D9CB_CreateVolume(IUnknown *pDevice, IUnknown *pSuperior, UINT *ppVolume = NULL; } else { *ppVolume = (IWineD3DVolume *)object->wineD3DVolume; + object->forwardReference = pSuperior; } TRACE("(%p) Created volume %p\n", This, *ppVolume); return hrc; } + +ULONG WINAPI D3D9CB_DestroyVolume(IWineD3DVolume *pVolume) { + IDirect3DVolume9Impl* volumeParent; + + IWineD3DVolume_GetParent(pVolume, (IUnknown **) &volumeParent); + /* GetParent's AddRef was forwarded to an object in destruction. + * Releasing it here again would cause an endless recursion. */ + volumeParent->forwardReference = NULL; + return IDirect3DVolume9_Release((IDirect3DVolume9*) volumeParent); +} diff --git a/dlls/d3d9/volumetexture.c b/dlls/d3d9/volumetexture.c index 3397bb799d5..d45ca0e7a2d 100644 --- a/dlls/d3d9/volumetexture.c +++ b/dlls/d3d9/volumetexture.c @@ -58,7 +58,7 @@ static ULONG WINAPI IDirect3DVolumeTexture9Impl_Release(LPDIRECT3DVOLUMETEXTURE9 TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IWineD3DVolumeTexture_Release(This->wineD3DVolumeTexture); + IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D9CB_DestroyVolume); IUnknown_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); }