From de3bd86fb6eb9f6f6f15a6c8b2c338de6e442845 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 17 Sep 2009 12:35:25 +0200 Subject: [PATCH] wined3d: Don't free D3D cube textures until the wined3d cube texture is destroyed. --- dlls/d3d8/cubetexture.c | 29 +++++++++++++++++++++++------ dlls/d3d9/cubetexture.c | 27 ++++++++++++++++++++++----- dlls/ddraw/ddraw.c | 5 +++-- dlls/wined3d/cubetexture.c | 22 +++++++++------------- dlls/wined3d/device.c | 8 ++++---- dlls/wined3d/wined3d_private.h | 6 ++++-- include/wine/wined3d.idl | 5 ++--- 7 files changed, 67 insertions(+), 35 deletions(-) diff --git a/dlls/d3d8/cubetexture.c b/dlls/d3d8/cubetexture.c index 97454d028eb..d3ec98c1330 100644 --- a/dlls/d3d8/cubetexture.c +++ b/dlls/d3d8/cubetexture.c @@ -46,6 +46,14 @@ static ULONG WINAPI IDirect3DCubeTexture8Impl_AddRef(LPDIRECT3DCUBETEXTURE8 ifac TRACE("(%p) : AddRef from %d\n", This, ref - 1); + if (ref == 1) + { + IUnknown_AddRef(This->parentDevice); + wined3d_mutex_lock(); + IWineD3DCubeTexture_AddRef(This->wineD3DCubeTexture); + wined3d_mutex_unlock(); + } + return ref; } @@ -58,12 +66,10 @@ static ULONG WINAPI IDirect3DCubeTexture8Impl_Release(LPDIRECT3DCUBETEXTURE8 ifa if (ref == 0) { TRACE("Releasing child %p\n", This->wineD3DCubeTexture); - wined3d_mutex_lock(); - IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture); - wined3d_mutex_unlock(); - IUnknown_Release(This->parentDevice); - HeapFree(GetProcessHeap(), 0, This); + wined3d_mutex_lock(); + IWineD3DCubeTexture_Release(This->wineD3DCubeTexture); + wined3d_mutex_unlock(); } return ref; } @@ -313,6 +319,16 @@ static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl = IDirect3DCubeTexture8Impl_AddDirtyRect }; +static void STDMETHODCALLTYPE d3d8_cubetexture_wined3d_object_destroyed(void *parent) +{ + HeapFree(GetProcessHeap(), 0, parent); +} + +static const struct wined3d_parent_ops d3d8_cubetexture_wined3d_parent_ops = +{ + d3d8_cubetexture_wined3d_object_destroyed, +}; + HRESULT cubetexture_init(IDirect3DCubeTexture8Impl *texture, IDirect3DDevice8Impl *device, UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) { @@ -323,7 +339,8 @@ HRESULT cubetexture_init(IDirect3DCubeTexture8Impl *texture, IDirect3DDevice8Imp wined3d_mutex_lock(); hr = IWineD3DDevice_CreateCubeTexture(device->WineD3DDevice, edge_length, levels, usage & WINED3DUSAGE_MASK, - wined3dformat_from_d3dformat(format), pool, &texture->wineD3DCubeTexture, (IUnknown *)texture); + wined3dformat_from_d3dformat(format), pool, &texture->wineD3DCubeTexture, + (IUnknown *)texture, &d3d8_cubetexture_wined3d_parent_ops); wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dlls/d3d9/cubetexture.c b/dlls/d3d9/cubetexture.c index 4727051c7a7..4bab9dfd021 100644 --- a/dlls/d3d9/cubetexture.c +++ b/dlls/d3d9/cubetexture.c @@ -49,6 +49,14 @@ static ULONG WINAPI IDirect3DCubeTexture9Impl_AddRef(LPDIRECT3DCUBETEXTURE9 ifac TRACE("(%p) : AddRef from %d\n", This, ref - 1); + if (ref == 1) + { + IDirect3DDevice9Ex_AddRef(This->parentDevice); + wined3d_mutex_lock(); + IWineD3DCubeTexture_AddRef(This->wineD3DCubeTexture); + wined3d_mutex_unlock(); + } + return ref; } @@ -61,12 +69,10 @@ static ULONG WINAPI IDirect3DCubeTexture9Impl_Release(LPDIRECT3DCUBETEXTURE9 ifa if (ref == 0) { TRACE("Releasing child %p\n", This->wineD3DCubeTexture); - wined3d_mutex_lock(); - IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture); IDirect3DDevice9Ex_Release(This->parentDevice); + wined3d_mutex_lock(); + IWineD3DCubeTexture_Release(This->wineD3DCubeTexture); wined3d_mutex_unlock(); - - HeapFree(GetProcessHeap(), 0, This); } return ref; } @@ -352,6 +358,16 @@ static const IDirect3DCubeTexture9Vtbl Direct3DCubeTexture9_Vtbl = IDirect3DCubeTexture9Impl_AddDirtyRect }; +static void STDMETHODCALLTYPE cubetexture_wined3d_object_destroyed(void *parent) +{ + HeapFree(GetProcessHeap(), 0, parent); +} + +static const struct wined3d_parent_ops d3d9_cubetexture_wined3d_parent_ops = +{ + cubetexture_wined3d_object_destroyed, +}; + HRESULT cubetexture_init(IDirect3DCubeTexture9Impl *texture, IDirect3DDevice9Impl *device, UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) { @@ -362,7 +378,8 @@ HRESULT cubetexture_init(IDirect3DCubeTexture9Impl *texture, IDirect3DDevice9Imp wined3d_mutex_lock(); hr = IWineD3DDevice_CreateCubeTexture(device->WineD3DDevice, edge_length, levels, usage, - wined3dformat_from_d3dformat(format), pool, &texture->wineD3DCubeTexture, (IUnknown *)texture); + wined3dformat_from_d3dformat(format), pool, &texture->wineD3DCubeTexture, + (IUnknown *)texture, &d3d9_cubetexture_wined3d_parent_ops); wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 98c30b4a03c..5434b9ae2cc 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -2620,8 +2620,9 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, */ if(desc2.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) { - hr = IWineD3DDevice_CreateCubeTexture(This->wineD3DDevice, DDSD->dwWidth /* Edgelength */, levels, - 0 /* usage */, Format, Pool, (IWineD3DCubeTexture **)&object->wineD3DTexture, (IUnknown *)object); + hr = IWineD3DDevice_CreateCubeTexture(This->wineD3DDevice, DDSD->dwWidth /* Edgelength */, + levels, 0 /* usage */, Format, Pool, (IWineD3DCubeTexture **)&object->wineD3DTexture, + (IUnknown *)object, &ddraw_null_wined3d_parent_ops); } else { diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c index 744bb7fe615..45a94d34810 100644 --- a/dlls/wined3d/cubetexture.c +++ b/dlls/wined3d/cubetexture.c @@ -174,8 +174,11 @@ static ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface) ULONG ref; TRACE("(%p) : Releasing from %d\n", This, This->resource.ref); ref = InterlockedDecrement(&This->resource.ref); - if (ref == 0) { - IWineD3DCubeTexture_Destroy(iface); + if (!ref) + { + cubetexture_cleanup(This); + This->parent_ops->wined3d_object_destroyed(This->resource.parent); + HeapFree(GetProcessHeap(), 0, This); } return ref; } @@ -318,15 +321,6 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_IsCondNP2(IWineD3DCubeTexture *iface) /* ******************************************* IWineD3DCubeTexture IWineD3DCubeTexture parts follow ******************************************* */ -static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface) -{ - IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; - - cubetexture_cleanup(This); - /* finally delete the object */ - HeapFree(GetProcessHeap(), 0, This); -} - static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) { IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; @@ -435,7 +429,6 @@ static const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = IWineD3DCubeTextureImpl_GetTextureDimensions, IWineD3DCubeTextureImpl_IsCondNP2, /* IWineD3DCubeTexture */ - IWineD3DCubeTextureImpl_Destroy, IWineD3DCubeTextureImpl_GetLevelDesc, IWineD3DCubeTextureImpl_GetCubeMapSurface, IWineD3DCubeTextureImpl_LockRect, @@ -444,7 +437,8 @@ static const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = }; HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels, - IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent) + IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, + IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info); @@ -500,6 +494,8 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN return hr; } + texture->parent_ops = parent_ops; + /* Find the nearest pow2 match. */ pow2_edge_length = 1; while (pow2_edge_length < edge_length) pow2_edge_length <<= 1; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c5b8d971ec8..ee19bbbc4e1 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1066,9 +1066,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface, UIN return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface, - UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format, - WINED3DPOOL Pool, IWineD3DCubeTexture **ppCubeTexture, IUnknown *parent) +static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface, UINT EdgeLength, UINT Levels, + DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, IWineD3DCubeTexture **ppCubeTexture, + IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/ @@ -1082,7 +1082,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface return WINED3DERR_OUTOFVIDEOMEMORY; } - hr = cubetexture_init(object, EdgeLength, Levels, This, Usage, Format, Pool, parent); + hr = cubetexture_init(object, EdgeLength, Levels, This, Usage, Format, Pool, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize cubetexture, returning %#x\n", hr); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 23fc13c3ee6..baf8d367de6 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1839,11 +1839,13 @@ typedef struct IWineD3DCubeTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DCubeTexture */ + const struct wined3d_parent_ops *parent_ops; IWineD3DSurface *surfaces[6][MAX_MIP_LEVELS]; } IWineD3DCubeTextureImpl; -HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels, IWineD3DDeviceImpl *device, - DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent) DECLSPEC_HIDDEN; +HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels, + IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, + IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; typedef struct _WINED3DVOLUMET_DESC { diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index d22b2b6d561..9d170007f48 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -2652,8 +2652,6 @@ interface IWineD3DTexture : IWineD3DBaseTexture ] interface IWineD3DCubeTexture : IWineD3DBaseTexture { - void Destroy( - ); HRESULT GetLevelDesc( [in] UINT level, [out] WINED3DSURFACE_DESC *desc @@ -2975,7 +2973,8 @@ interface IWineD3DDevice : IWineD3DBase [in] WINED3DFORMAT format, [in] WINED3DPOOL pool, [out] IWineD3DCubeTexture **texture, - [in] IUnknown *parent + [in] IUnknown *parent, + [in] const struct wined3d_parent_ops *parent_ops ); HRESULT CreateQuery( [in] WINED3DQUERYTYPE type,