wined3d: Don't free D3D buffers until the wined3d buffer is destroyed.

This commit is contained in:
Henri Verbeet 2009-09-17 23:03:32 +02:00 committed by Alexandre Julliard
parent b1bf50d751
commit 93b0600829
12 changed files with 135 additions and 41 deletions

View File

@ -53,6 +53,8 @@ static ULONG STDMETHODCALLTYPE d3d10_buffer_AddRef(ID3D10Buffer *iface)
TRACE("%p increasing refcount to %u\n", This, refcount);
if (refcount == 1) IWineD3DBuffer_AddRef(This->wined3d_buffer);
return refcount;
}
@ -66,7 +68,6 @@ static ULONG STDMETHODCALLTYPE d3d10_buffer_Release(ID3D10Buffer *iface)
if (!refcount)
{
IWineD3DBuffer_Release(This->wined3d_buffer);
HeapFree(GetProcessHeap(), 0, This);
}
return refcount;
@ -166,6 +167,16 @@ static const struct ID3D10BufferVtbl d3d10_buffer_vtbl =
d3d10_buffer_GetDesc,
};
static void STDMETHODCALLTYPE d3d10_buffer_wined3d_object_released(void *parent)
{
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d10_buffer_wined3d_parent_ops =
{
d3d10_buffer_wined3d_object_released,
};
HRESULT d3d10_buffer_init(struct d3d10_buffer *buffer, struct d3d10_device *device,
const D3D10_BUFFER_DESC *desc, const D3D10_SUBRESOURCE_DATA *data)
{
@ -184,7 +195,8 @@ HRESULT d3d10_buffer_init(struct d3d10_buffer *buffer, struct d3d10_device *devi
wined3d_desc.misc_flags = desc->MiscFlags;
hr = IWineD3DDevice_CreateBuffer(device->wined3d_device, &wined3d_desc,
data ? data->pSysMem : NULL, (IUnknown *)buffer, &buffer->wined3d_buffer);
data ? data->pSysMem : NULL, (IUnknown *)buffer, &d3d10_buffer_wined3d_parent_ops,
&buffer->wined3d_buffer);
if (FAILED(hr))
{
WARN("Failed to create wined3d buffer, hr %#x.\n", hr);

View File

@ -46,6 +46,14 @@ static ULONG WINAPI IDirect3DIndexBuffer8Impl_AddRef(LPDIRECT3DINDEXBUFFER8 ifac
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
if (ref == 1)
{
IDirect3DDevice8_AddRef(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_AddRef(This->wineD3DIndexBuffer);
wined3d_mutex_unlock();
}
return ref;
}
@ -56,12 +64,10 @@ static ULONG WINAPI IDirect3DIndexBuffer8Impl_Release(LPDIRECT3DINDEXBUFFER8 ifa
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
IDirect3DDevice8_Release(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
wined3d_mutex_unlock();
IUnknown_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
@ -228,6 +234,16 @@ static const IDirect3DIndexBuffer8Vtbl Direct3DIndexBuffer8_Vtbl =
IDirect3DIndexBuffer8Impl_GetDesc
};
static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
{
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
{
d3d8_indexbuffer_wined3d_object_destroyed,
};
HRESULT indexbuffer_init(IDirect3DIndexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
@ -238,8 +254,9 @@ HRESULT indexbuffer_init(IDirect3DIndexBuffer8Impl *buffer, IDirect3DDevice8Impl
buffer->format = wined3dformat_from_d3dformat(format);
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateIndexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
(WINED3DPOOL)pool, &buffer->wineD3DIndexBuffer, (IUnknown *)buffer);
hr = IWineD3DDevice_CreateIndexBuffer(device->WineD3DDevice, size,
usage & WINED3DUSAGE_MASK, (WINED3DPOOL)pool, &buffer->wineD3DIndexBuffer,
(IUnknown *)buffer, &d3d8_indexbuffer_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View File

@ -47,6 +47,14 @@ static ULONG WINAPI IDirect3DVertexBuffer8Impl_AddRef(LPDIRECT3DVERTEXBUFFER8 if
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
if (ref == 1)
{
IDirect3DDevice8_AddRef(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_AddRef(This->wineD3DVertexBuffer);
wined3d_mutex_unlock();
}
return ref;
}
@ -57,12 +65,10 @@ static ULONG WINAPI IDirect3DVertexBuffer8Impl_Release(LPDIRECT3DVERTEXBUFFER8 i
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
IDirect3DDevice8_Release(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
wined3d_mutex_unlock();
IUnknown_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
@ -231,6 +237,16 @@ static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
IDirect3DVertexBuffer8Impl_GetDesc
};
static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
{
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
{
d3d8_vertexbuffer_wined3d_object_destroyed,
};
HRESULT vertexbuffer_init(IDirect3DVertexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
{
@ -241,8 +257,9 @@ HRESULT vertexbuffer_init(IDirect3DVertexBuffer8Impl *buffer, IDirect3DDevice8Im
buffer->fvf = fvf;
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateVertexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
0, (WINED3DPOOL)pool, &buffer->wineD3DVertexBuffer, (IUnknown *)buffer);
hr = IWineD3DDevice_CreateVertexBuffer(device->WineD3DDevice, size,
usage & WINED3DUSAGE_MASK, 0, (WINED3DPOOL)pool, &buffer->wineD3DVertexBuffer,
(IUnknown *)buffer, &d3d8_vertexbuffer_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View File

@ -47,6 +47,14 @@ static ULONG WINAPI IDirect3DIndexBuffer9Impl_AddRef(LPDIRECT3DINDEXBUFFER9 ifac
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
if (ref == 1)
{
IDirect3DDevice9Ex_AddRef(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_AddRef(This->wineD3DIndexBuffer);
wined3d_mutex_unlock();
}
return ref;
}
@ -57,12 +65,10 @@ static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 ifa
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
IDirect3DDevice9Ex_Release(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
wined3d_mutex_unlock();
IDirect3DDevice9Ex_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
@ -230,6 +236,16 @@ static const IDirect3DIndexBuffer9Vtbl Direct3DIndexBuffer9_Vtbl =
IDirect3DIndexBuffer9Impl_GetDesc
};
static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *parent)
{
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops =
{
d3d9_indexbuffer_wined3d_object_destroyed,
};
HRESULT indexbuffer_init(IDirect3DIndexBuffer9Impl *buffer, IDirect3DDevice9Impl *device,
UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
@ -240,8 +256,9 @@ HRESULT indexbuffer_init(IDirect3DIndexBuffer9Impl *buffer, IDirect3DDevice9Impl
buffer->format = wined3dformat_from_d3dformat(format);
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateIndexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
(WINED3DPOOL)pool, &buffer->wineD3DIndexBuffer, (IUnknown *)buffer);
hr = IWineD3DDevice_CreateIndexBuffer(device->WineD3DDevice, size,
usage & WINED3DUSAGE_MASK, (WINED3DPOOL)pool, &buffer->wineD3DIndexBuffer,
(IUnknown *)buffer, &d3d9_indexbuffer_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View File

@ -48,6 +48,14 @@ static ULONG WINAPI IDirect3DVertexBuffer9Impl_AddRef(LPDIRECT3DVERTEXBUFFER9 if
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
if (ref == 1)
{
IDirect3DDevice9Ex_AddRef(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_AddRef(This->wineD3DVertexBuffer);
wined3d_mutex_unlock();
}
return ref;
}
@ -58,12 +66,10 @@ static ULONG WINAPI IDirect3DVertexBuffer9Impl_Release(LPDIRECT3DVERTEXBUFFER9 i
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) {
IDirect3DDevice9Ex_Release(This->parentDevice);
wined3d_mutex_lock();
IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
wined3d_mutex_unlock();
IDirect3DDevice9Ex_Release(This->parentDevice);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
@ -233,6 +239,16 @@ static const IDirect3DVertexBuffer9Vtbl Direct3DVertexBuffer9_Vtbl =
IDirect3DVertexBuffer9Impl_GetDesc
};
static void STDMETHODCALLTYPE d3d9_vertexbuffer_wined3d_object_destroyed(void *parent)
{
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops =
{
d3d9_vertexbuffer_wined3d_object_destroyed,
};
HRESULT vertexbuffer_init(IDirect3DVertexBuffer9Impl *buffer, IDirect3DDevice9Impl *device,
UINT size, UINT usage, DWORD fvf, D3DPOOL pool)
{
@ -243,8 +259,9 @@ HRESULT vertexbuffer_init(IDirect3DVertexBuffer9Impl *buffer, IDirect3DDevice9Im
buffer->fvf = fvf;
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateVertexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
0 /* fvf for ddraw only */, (WINED3DPOOL)pool, &buffer->wineD3DVertexBuffer, (IUnknown *)buffer);
hr = IWineD3DDevice_CreateVertexBuffer(device->WineD3DDevice, size,
usage & WINED3DUSAGE_MASK, 0, (WINED3DPOOL)pool, &buffer->wineD3DVertexBuffer,
(IUnknown *)buffer, &d3d9_vertexbuffer_wined3d_parent_ops);
wined3d_mutex_unlock();
if (FAILED(hr))
{

View File

@ -64,7 +64,7 @@ static const DDDEVICEIDENTIFIER2 deviceidentifier =
static void STDMETHODCALLTYPE ddraw_null_wined3d_object_destroyed(void *parent) {}
static const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops =
const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops =
{
ddraw_null_wined3d_object_destroyed,
};

View File

@ -39,6 +39,8 @@
#endif
#include "wine/wined3d.h"
extern const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops DECLSPEC_HIDDEN;
/*****************************************************************************
* IParent - a helper interface
*****************************************************************************/

View File

@ -824,7 +824,8 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface,
* takes the pointer and avoids the memcpy
*/
hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, 0x40000 /* Length. Don't know how long it should be */,
WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &object->indexbuffer, (IUnknown *)IndexBufferParent);
WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &object->indexbuffer, (IUnknown *)IndexBufferParent,
&ddraw_null_wined3d_parent_ops);
if(FAILED(hr))
{
@ -1023,7 +1024,7 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface,
get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices,
Desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0, Desc->dwFVF,
Desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT,
&object->wineD3DVertexBuffer, (IUnknown *)object);
&object->wineD3DVertexBuffer, (IUnknown *)object, &ddraw_null_wined3d_parent_ops);
if(hr != D3D_OK)
{
ERR("(%p) IWineD3DDevice::CreateVertexBuffer failed with hr=%08x\n", This, hr);

View File

@ -635,6 +635,7 @@ static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface)
{
buffer_UnLoad(iface);
resource_cleanup((IWineD3DResource *)iface);
This->parent_ops->wined3d_object_destroyed(This->resource.parent);
HeapFree(GetProcessHeap(), 0, This);
}
@ -1059,8 +1060,9 @@ static const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
buffer_GetDesc,
};
HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage,
WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, const char *data, IUnknown *parent)
HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint,
const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info);
HRESULT hr;
@ -1080,6 +1082,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, U
WARN("Failed to initialize resource, hr %#x\n", hr);
return hr;
}
buffer->parent_ops = parent_ops;
buffer->buffer_type_hint = bind_hint;
TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage,

View File

@ -442,8 +442,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetParent(IWineD3DDevice *iface, IUnkno
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
struct wined3d_buffer_desc *desc, const void *data, IUnknown *parent, IWineD3DBuffer **buffer)
static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, struct wined3d_buffer_desc *desc,
const void *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops, IWineD3DBuffer **buffer)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
struct wined3d_buffer *object;
@ -460,9 +460,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
FIXME("Ignoring access flags (pool)\n");
hr = buffer_init(object, This, desc->byte_width, desc->usage,
WINED3DFMT_UNKNOWN, WINED3DPOOL_MANAGED, GL_ARRAY_BUFFER_ARB,
data, parent);
hr = buffer_init(object, This, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN,
WINED3DPOOL_MANAGED, GL_ARRAY_BUFFER_ARB, data, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize buffer, hr %#x.\n", hr);
@ -478,8 +477,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage,
DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer, IUnknown *parent)
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size,
DWORD Usage, DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer,
IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
struct wined3d_buffer *object;
@ -505,7 +505,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
return WINED3DERR_OUTOFVIDEOMEMORY;
}
hr = buffer_init(object, This, Size, Usage, WINED3DFMT_VERTEXDATA, Pool, GL_ARRAY_BUFFER_ARB, NULL, parent);
hr = buffer_init(object, This, Size, Usage, WINED3DFMT_VERTEXDATA,
Pool, GL_ARRAY_BUFFER_ARB, NULL, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize buffer, hr %#x.\n", hr);
@ -548,7 +549,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface,
UINT Length, DWORD Usage, WINED3DPOOL Pool, IWineD3DBuffer **ppIndexBuffer, IUnknown *parent)
UINT Length, DWORD Usage, WINED3DPOOL Pool, IWineD3DBuffer **ppIndexBuffer,
IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
struct wined3d_buffer *object;
@ -565,7 +567,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
return WINED3DERR_OUTOFVIDEOMEMORY;
}
hr = buffer_init(object, This, Length, Usage, WINED3DFMT_UNKNOWN, Pool, GL_ELEMENT_ARRAY_BUFFER_ARB, NULL, parent);
hr = buffer_init(object, This, Length, Usage, WINED3DFMT_UNKNOWN,
Pool, GL_ELEMENT_ARRAY_BUFFER_ARB, NULL, parent, parent_ops);
if (FAILED(hr))
{
WARN("Failed to initialize buffer, hr %#x\n", hr);

View File

@ -2416,6 +2416,7 @@ struct wined3d_buffer
const struct IWineD3DBufferVtbl *vtbl;
IWineD3DResourceClass resource;
const struct wined3d_parent_ops *parent_ops;
struct wined3d_buffer_desc desc;
GLuint buffer_object;
@ -2441,8 +2442,9 @@ struct wined3d_buffer
const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object) DECLSPEC_HIDDEN;
BYTE *buffer_get_sysmem(struct wined3d_buffer *This) DECLSPEC_HIDDEN;
HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage,
WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, const char *data, IUnknown *parent) DECLSPEC_HIDDEN;
HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint,
const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
/* IWineD3DRendertargetView */
struct wined3d_rendertarget_view

View File

@ -2888,6 +2888,7 @@ interface IWineD3DDevice : IWineD3DBase
[in] struct wined3d_buffer_desc *desc,
[in] const void *data,
[in] IUnknown *parent,
[in] const struct wined3d_parent_ops *parent_ops,
[out] IWineD3DBuffer **buffer
);
HRESULT CreateVertexBuffer(
@ -2896,14 +2897,16 @@ interface IWineD3DDevice : IWineD3DBase
[in] DWORD fvf,
[in] WINED3DPOOL pool,
[out] IWineD3DBuffer **vertex_buffer,
[in] IUnknown *parent
[in] IUnknown *parent,
[in] const struct wined3d_parent_ops *parent_ops
);
HRESULT CreateIndexBuffer(
[in] UINT length,
[in] DWORD usage,
[in] WINED3DPOOL pool,
[out] IWineD3DBuffer **index_buffer,
[in] IUnknown *parent
[in] IUnknown *parent,
[in] const struct wined3d_parent_ops *parent_ops
);
HRESULT CreateStateBlock(
[in] WINED3DSTATEBLOCKTYPE type,