wined3d: Don't free D3D textures until the wined3d texture is destroyed.

This commit is contained in:
Henri Verbeet 2009-09-17 23:03:25 +02:00 committed by Alexandre Julliard
parent 644ab340f8
commit a8e8f763bf
7 changed files with 67 additions and 35 deletions

View File

@ -47,6 +47,14 @@ static ULONG WINAPI IDirect3DTexture8Impl_AddRef(LPDIRECT3DTEXTURE8 iface) {
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
if (ref == 1)
{
IDirect3DDevice8_AddRef(This->parentDevice);
wined3d_mutex_lock();
IWineD3DTexture_AddRef(This->wineD3DTexture);
wined3d_mutex_unlock();
}
return ref;
}
@ -57,12 +65,10 @@ static ULONG WINAPI IDirect3DTexture8Impl_Release(LPDIRECT3DTEXTURE8 iface) {
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
IDirect3DDevice8_Release(This->parentDevice);
wined3d_mutex_lock();
IWineD3DTexture_Destroy(This->wineD3DTexture);
IWineD3DTexture_Release(This->wineD3DTexture);
wined3d_mutex_unlock();
IUnknown_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
@ -312,6 +318,16 @@ static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl =
IDirect3DTexture8Impl_AddDirtyRect
};
static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent)
{
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops =
{
d3d8_texture_wined3d_object_destroyed,
};
HRESULT texture_init(IDirect3DTexture8Impl *texture, IDirect3DDevice8Impl *device,
UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
@ -321,8 +337,9 @@ HRESULT texture_init(IDirect3DTexture8Impl *texture, IDirect3DDevice8Impl *devic
texture->ref = 1;
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateTexture(device->WineD3DDevice, width, height, levels, usage & WINED3DUSAGE_MASK,
wined3dformat_from_d3dformat(format), pool, &texture->wineD3DTexture, (IUnknown *)texture);
hr = IWineD3DDevice_CreateTexture(device->WineD3DDevice, width, height, levels,
usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool,
&texture->wineD3DTexture, (IUnknown *)texture, &d3d8_texture_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View File

@ -49,6 +49,14 @@ static ULONG WINAPI IDirect3DTexture9Impl_AddRef(LPDIRECT3DTEXTURE9 iface) {
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
if (ref == 1)
{
IDirect3DDevice9Ex_AddRef(This->parentDevice);
wined3d_mutex_lock();
IWineD3DTexture_AddRef(This->wineD3DTexture);
wined3d_mutex_unlock();
}
return ref;
}
@ -59,12 +67,10 @@ static ULONG WINAPI IDirect3DTexture9Impl_Release(LPDIRECT3DTEXTURE9 iface) {
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
wined3d_mutex_lock();
IWineD3DTexture_Destroy(This->wineD3DTexture);
wined3d_mutex_unlock();
IDirect3DDevice9Ex_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
wined3d_mutex_lock();
IWineD3DTexture_Release(This->wineD3DTexture);
wined3d_mutex_unlock();
}
return ref;
}
@ -350,6 +356,16 @@ static const IDirect3DTexture9Vtbl Direct3DTexture9_Vtbl =
IDirect3DTexture9Impl_AddDirtyRect
};
static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
{
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
{
d3d9_texture_wined3d_object_destroyed,
};
HRESULT texture_init(IDirect3DTexture9Impl *texture, IDirect3DDevice9Impl *device,
UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
@ -359,8 +375,9 @@ HRESULT texture_init(IDirect3DTexture9Impl *texture, IDirect3DDevice9Impl *devic
texture->ref = 1;
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateTexture(device->WineD3DDevice, width, height, levels, usage & WINED3DUSAGE_MASK,
wined3dformat_from_d3dformat(format), pool, &texture->wineD3DTexture, (IUnknown *)texture);
hr = IWineD3DDevice_CreateTexture(device->WineD3DDevice, width, height, levels,
usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool,
&texture->wineD3DTexture, (IUnknown *)texture, &d3d9_texture_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View File

@ -2627,7 +2627,8 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
else
{
hr = IWineD3DDevice_CreateTexture(This->wineD3DDevice, DDSD->dwWidth, DDSD->dwHeight, levels,
0 /* usage */, Format, Pool, (IWineD3DTexture **)&object->wineD3DTexture, (IUnknown *)object);
0 /* usage */, Format, Pool, (IWineD3DTexture **)&object->wineD3DTexture,
(IUnknown *)object, &ddraw_null_wined3d_parent_ops);
}
This->tex_root = NULL;
}

View File

@ -964,8 +964,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice *
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format,
WINED3DPOOL Pool, IWineD3DTexture **ppTexture, IUnknown *parent)
UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
IWineD3DTexture **ppTexture, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DTextureImpl *object;
@ -983,7 +983,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
return WINED3DERR_OUTOFVIDEOMEMORY;
}
hr = texture_init(object, Width, Height, Levels, This, Usage, Format, Pool, parent);
hr = texture_init(object, Width, Height, Levels, This, Usage, Format, Pool, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize texture, returning %#x\n", hr);

View File

@ -161,8 +161,11 @@ static ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) {
ULONG ref;
TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
ref = InterlockedDecrement(&This->resource.ref);
if (ref == 0) {
IWineD3DTexture_Destroy(iface);
if (!ref)
{
texture_cleanup(This);
This->parent_ops->wined3d_object_destroyed(This->resource.parent);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
@ -323,15 +326,6 @@ static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture *iface) {
/* *******************************************
IWineD3DTexture IWineD3DTexture parts follow
******************************************* */
static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface)
{
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
texture_cleanup(This);
/* free the object */
HeapFree(GetProcessHeap(), 0, This);
}
static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) {
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
@ -432,7 +426,6 @@ static const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
IWineD3DTextureImpl_GetTextureDimensions,
IWineD3DTextureImpl_IsCondNP2,
/* IWineD3DTexture */
IWineD3DTextureImpl_Destroy,
IWineD3DTextureImpl_GetLevelDesc,
IWineD3DTextureImpl_GetSurfaceLevel,
IWineD3DTextureImpl_LockRect,
@ -441,7 +434,8 @@ static const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
};
HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, 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);
@ -515,6 +509,8 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT
return hr;
}
texture->parent_ops = parent_ops;
/* Precalculated scaling for 'faked' non power of two texture coords.
* Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
* is used in combination with texture uploads (RTL_READTEX). The reason is that EXT_PALETTED_TEXTURE

View File

@ -1819,14 +1819,16 @@ typedef struct IWineD3DTextureImpl
IWineD3DBaseTextureClass baseTexture;
/* IWineD3DTexture */
const struct wined3d_parent_ops *parent_ops;
IWineD3DSurface *surfaces[MAX_MIP_LEVELS];
UINT target;
BOOL cond_np2;
} IWineD3DTextureImpl;
HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT levels, IWineD3DDeviceImpl *device,
DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent) DECLSPEC_HIDDEN;
HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT levels,
IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool,
IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
/*****************************************************************************
* IWineD3DCubeTexture implementation structure (extends IWineD3DBaseTextureImpl)

View File

@ -2621,8 +2621,6 @@ interface IWineD3DBaseTexture : IWineD3DResource
]
interface IWineD3DTexture : IWineD3DBaseTexture
{
void Destroy(
);
HRESULT GetLevelDesc(
[in] UINT level,
[out] WINED3DSURFACE_DESC *desc
@ -2941,7 +2939,8 @@ interface IWineD3DDevice : IWineD3DBase
[in] WINED3DFORMAT format,
[in] WINED3DPOOL pool,
[out] IWineD3DTexture **texture,
[in] IUnknown *parent
[in] IUnknown *parent,
[in] const struct wined3d_parent_ops *parent_ops
);
HRESULT CreateVolumeTexture(
[in] UINT width,