From c509cbcfdb5a8092ea530b6a8940c98e0f6bd0e9 Mon Sep 17 00:00:00 2001 From: Andrew Nguyen Date: Thu, 26 May 2011 22:50:31 -0500 Subject: d3d9: Increment the reference count of the IDirect3D9 instance when creating a device. To: wine-patches Reply-To: wine-devel --- dlls/d3d9/device.c | 15 +++++++++++++++ dlls/d3d9/directx.c | 2 ++ dlls/d3d9/tests/device.c | 12 ++++++++++++ 3 files changed, 29 insertions(+), 0 deletions(-) diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index a95fa16..a7ce3ac 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -249,6 +249,10 @@ static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(IDirect3DDevi if (ref == 0) { unsigned i; + HRESULT hr; + struct wined3d *wined3d; + IDirect3D9 *pD3D9 = NULL; + This->inDestruction = TRUE; wined3d_mutex_lock(); @@ -260,12 +264,23 @@ static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(IDirect3DDevi } HeapFree(GetProcessHeap(), 0, This->convertedDecls); + /* Get the parent IDirect3D9 instance. */ + hr = wined3d_device_get_wined3d(This->wined3d_device, &wined3d); + if (hr == S_OK && wined3d) + { + pD3D9 = wined3d_get_parent(wined3d); + wined3d_decref(wined3d); + } + wined3d_device_uninit_3d(This->wined3d_device); wined3d_device_release_focus_window(This->wined3d_device); wined3d_device_decref(This->wined3d_device); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, This); + + if (pD3D9) + IDirect3D9_Release(pD3D9); } return ref; } diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 791d835..f638453 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -460,6 +460,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3D9Impl_CreateDevice(IDirect3D9Ex TRACE("Created device %p.\n", object); *device = (IDirect3DDevice9 *)object; + IDirect3D9_AddRef(iface); return D3D_OK; } @@ -518,6 +519,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3D9ExImpl_CreateDeviceEx(IDirect3 TRACE("Created device %p.\n", object); *device = &object->IDirect3DDevice9Ex_iface; + IDirect3D9_AddRef(iface); return D3D_OK; } diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 1a74d6e..235b06f 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -423,6 +423,7 @@ static void test_refcount(void) HRESULT hr; HWND hwnd = NULL; IDirect3D9 *pD3d = NULL; + IDirect3D9 *pD3d2 = NULL; IDirect3DDevice9 *pDevice = NULL; IDirect3DVertexBuffer9 *pVertexBuffer = NULL; IDirect3DIndexBuffer9 *pIndexBuffer = NULL; @@ -467,6 +468,8 @@ static void test_refcount(void) ok(hwnd != NULL, "Failed to create window\n"); if (!pD3d || !hwnd) goto cleanup; + CHECK_REFCOUNT( pD3d, 1 ); + IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm ); ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; @@ -484,6 +487,15 @@ static void test_refcount(void) refcount = get_refcount( (IUnknown *)pDevice ); ok(refcount == 1, "Invalid device RefCount %d\n", refcount); + CHECK_REFCOUNT( pD3d, 2 ); + + hr = IDirect3DDevice9_GetDirect3D(pDevice, &pD3d2); + CHECK_CALL( hr, "GetDirect3D", pDevice, refcount ); + + ok(pD3d2 == pD3d, "Expected IDirect3D9 pointers to be equal\n"); + CHECK_REFCOUNT( pD3d, 3 ); + CHECK_RELEASE_REFCOUNT( pD3d, 2 ); + /** * Check refcount of implicit surfaces and implicit swapchain. Findings: * - the container is the device OR swapchain -- 1.7.5.2