From 789372afa82d0771196160dc538dd3d9791eb669 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 23 Sep 2009 18:42:13 +0200 Subject: [PATCH] wined3d: Don't free D3D pixel shaders until the wined3d pixel shader is destroyed. --- dlls/d3d10core/shader.c | 23 +++++++++++++++++++---- dlls/d3d8/pixelshader.c | 22 +++++++++++++++++++--- dlls/d3d9/pixelshader.c | 25 +++++++++++++++++++++---- dlls/wined3d/device.c | 5 +++-- dlls/wined3d/pixelshader.c | 4 +++- dlls/wined3d/wined3d_private.h | 3 ++- include/wine/wined3d.idl | 3 ++- 7 files changed, 69 insertions(+), 16 deletions(-) diff --git a/dlls/d3d10core/shader.c b/dlls/d3d10core/shader.c index 14f89196b6e..bf7a6aba17c 100644 --- a/dlls/d3d10core/shader.c +++ b/dlls/d3d10core/shader.c @@ -394,6 +394,11 @@ static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *ifac TRACE("%p increasing refcount to %u\n", This, refcount); + if (refcount == 1) + { + IWineD3DPixelShader_AddRef(This->wined3d_shader); + } + return refcount; } @@ -407,8 +412,6 @@ static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *ifa if (!refcount) { IWineD3DPixelShader_Release(This->wined3d_shader); - shader_free_signature(&This->output_signature); - HeapFree(GetProcessHeap(), 0, This); } return refcount; @@ -460,6 +463,18 @@ static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl = d3d10_pixel_shader_SetPrivateDataInterface, }; +static void STDMETHODCALLTYPE d3d10_pixel_shader_wined3d_object_destroyed(void *parent) +{ + struct d3d10_pixel_shader *shader = parent; + shader_free_signature(&shader->output_signature); + HeapFree(GetProcessHeap(), 0, shader); +} + +static const struct wined3d_parent_ops d3d10_pixel_shader_wined3d_parent_ops = +{ + d3d10_pixel_shader_wined3d_object_destroyed, +}; + HRESULT d3d10_pixel_shader_init(struct d3d10_pixel_shader *shader, struct d3d10_device *device, const void *byte_code, SIZE_T byte_code_length) { @@ -478,8 +493,8 @@ HRESULT d3d10_pixel_shader_init(struct d3d10_pixel_shader *shader, struct d3d10_ } hr = IWineD3DDevice_CreatePixelShader(device->wined3d_device, - shader_info.shader_code, &shader->output_signature, - &shader->wined3d_shader, (IUnknown *)shader); + shader_info.shader_code, &shader->output_signature, &shader->wined3d_shader, + (IUnknown *)shader, &d3d10_pixel_shader_wined3d_parent_ops); if (FAILED(hr)) { WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr); diff --git a/dlls/d3d8/pixelshader.c b/dlls/d3d8/pixelshader.c index 3f5ed9ed5fd..f56549522a7 100644 --- a/dlls/d3d8/pixelshader.c +++ b/dlls/d3d8/pixelshader.c @@ -46,6 +46,13 @@ static ULONG WINAPI IDirect3DPixelShader8Impl_AddRef(IDirect3DPixelShader8 *ifac TRACE("(%p) : AddRef from %d\n", This, ref - 1); + if (ref == 1) + { + wined3d_mutex_lock(); + IWineD3DPixelShader_AddRef(This->wineD3DPixelShader); + wined3d_mutex_unlock(); + } + return ref; } @@ -59,8 +66,6 @@ static ULONG WINAPI IDirect3DPixelShader8Impl_Release(IDirect3DPixelShader8 * if wined3d_mutex_lock(); IWineD3DPixelShader_Release(This->wineD3DPixelShader); wined3d_mutex_unlock(); - - HeapFree(GetProcessHeap(), 0, This); } return ref; } @@ -73,6 +78,16 @@ static const IDirect3DPixelShader8Vtbl Direct3DPixelShader8_Vtbl = IDirect3DPixelShader8Impl_Release, }; +static void STDMETHODCALLTYPE d3d8_pixelshader_wined3d_object_destroyed(void *parent) +{ + HeapFree(GetProcessHeap(), 0, parent); +} + +static const struct wined3d_parent_ops d3d8_pixelshader_wined3d_parent_ops = +{ + d3d8_pixelshader_wined3d_object_destroyed, +}; + HRESULT pixelshader_init(IDirect3DPixelShader8Impl *shader, IDirect3DDevice8Impl *device, const DWORD *byte_code, DWORD shader_handle) { @@ -84,7 +99,8 @@ HRESULT pixelshader_init(IDirect3DPixelShader8Impl *shader, IDirect3DDevice8Impl wined3d_mutex_lock(); hr = IWineD3DDevice_CreatePixelShader(device->WineD3DDevice, byte_code, - NULL, &shader->wineD3DPixelShader, (IUnknown *)shader); + NULL, &shader->wineD3DPixelShader, (IUnknown *)shader, + &d3d8_pixelshader_wined3d_parent_ops); wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dlls/d3d9/pixelshader.c b/dlls/d3d9/pixelshader.c index 11f275de3c9..547dc746496 100644 --- a/dlls/d3d9/pixelshader.c +++ b/dlls/d3d9/pixelshader.c @@ -46,6 +46,14 @@ static ULONG WINAPI IDirect3DPixelShader9Impl_AddRef(LPDIRECT3DPIXELSHADER9 ifac TRACE("(%p) : AddRef from %d\n", This, ref - 1); + if (ref == 1) + { + IDirect3DDevice9Ex_AddRef(This->parentDevice); + wined3d_mutex_lock(); + IWineD3DPixelShader_AddRef(This->wineD3DPixelShader); + wined3d_mutex_unlock(); + } + return ref; } @@ -56,12 +64,10 @@ static ULONG WINAPI IDirect3DPixelShader9Impl_Release(LPDIRECT3DPIXELSHADER9 ifa TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { + IDirect3DDevice9Ex_Release(This->parentDevice); wined3d_mutex_lock(); IWineD3DPixelShader_Release(This->wineD3DPixelShader); wined3d_mutex_unlock(); - - IDirect3DDevice9Ex_Release(This->parentDevice); - HeapFree(GetProcessHeap(), 0, This); } return ref; } @@ -107,6 +113,16 @@ static const IDirect3DPixelShader9Vtbl Direct3DPixelShader9_Vtbl = IDirect3DPixelShader9Impl_GetFunction }; +static void STDMETHODCALLTYPE d3d9_pixelshader_wined3d_object_destroyed(void *parent) +{ + HeapFree(GetProcessHeap(), 0, parent); +} + +static const struct wined3d_parent_ops d3d9_pixelshader_wined3d_parent_ops = +{ + d3d9_pixelshader_wined3d_object_destroyed, +}; + HRESULT pixelshader_init(IDirect3DPixelShader9Impl *shader, IDirect3DDevice9Impl *device, const DWORD *byte_code) { HRESULT hr; @@ -116,7 +132,8 @@ HRESULT pixelshader_init(IDirect3DPixelShader9Impl *shader, IDirect3DDevice9Impl wined3d_mutex_lock(); hr = IWineD3DDevice_CreatePixelShader(device->WineD3DDevice, byte_code, - NULL, &shader->wineD3DPixelShader, (IUnknown *)shader); + NULL, &shader->wineD3DPixelShader, (IUnknown *)shader, + &d3d9_pixelshader_wined3d_parent_ops); wined3d_mutex_unlock(); if (FAILED(hr)) { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 5a5389927f6..bda39e1e8e6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1792,7 +1792,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, const DWORD *pFunction, const struct wined3d_shader_signature *output_signature, - IWineD3DPixelShader **ppPixelShader, IUnknown *parent) + IWineD3DPixelShader **ppPixelShader, IUnknown *parent, + const struct wined3d_parent_ops *parent_ops) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DPixelShaderImpl *object; @@ -1805,7 +1806,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface return E_OUTOFMEMORY; } - hr = pixelshader_init(object, This, pFunction, output_signature, parent); + hr = pixelshader_init(object, This, pFunction, output_signature, parent, parent_ops); if (FAILED(hr)) { WARN("Failed to initialize pixel shader, hr %#x.\n", hr); diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index ba7be4b76d7..89d7a130e86 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -71,6 +71,7 @@ static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) if (!refcount) { shader_cleanup((IWineD3DBaseShader *)iface); + This->parent_ops->wined3d_object_destroyed(This->parent); HeapFree(GetProcessHeap(), 0, This); } @@ -424,7 +425,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *device, const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, - IUnknown *parent) + IUnknown *parent, const struct wined3d_parent_ops *parent_ops) { HRESULT hr; @@ -432,6 +433,7 @@ HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *de shader->lpVtbl = &IWineD3DPixelShader_Vtbl; shader->parent = parent; + shader->parent_ops = parent_ops; shader_init(&shader->baseShader, (IWineD3DDevice *)device); list_add_head(&device->shaders, &shader->baseShader.shader_list_entry); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f4e184527fd..66a72b77195 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2813,6 +2813,7 @@ typedef struct IWineD3DPixelShaderImpl { /* IWineD3DPixelShaderImpl */ IUnknown *parent; + const struct wined3d_parent_ops *parent_ops; /* Pixel shader input semantics */ struct wined3d_shader_signature_element input_signature[MAX_REG_INPUT]; @@ -2833,7 +2834,7 @@ typedef struct IWineD3DPixelShaderImpl { HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *device, const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, - IUnknown *parent) DECLSPEC_HIDDEN; + IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures) DECLSPEC_HIDDEN; void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index e4d81447f30..e39a88048e3 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -3013,7 +3013,8 @@ interface IWineD3DDevice : IWineD3DBase [in] const DWORD *function, [in] const struct wined3d_shader_signature *output_signature, [out] IWineD3DPixelShader **shader, - [in] IUnknown *parent + [in] IUnknown *parent, + [in] const struct wined3d_parent_ops *parent_ops ); HRESULT CreatePalette( [in] DWORD flags, -- 2.11.4.GIT