diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 914dec58357..f98b33421d5 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -177,7 +177,8 @@ struct IDirect3DDevice8Impl IDirect3DDevice8 IDirect3DDevice8_iface; struct wined3d_device_parent device_parent; LONG ref; - struct wined3d_device *wined3d_device; + struct wined3d_device *wined3d_device; + IDirect3D8 *d3d_parent; struct d3d8_handle_table handle_table; /* FVF management */ @@ -189,7 +190,7 @@ struct IDirect3DDevice8Impl BOOL lost; }; -HRESULT device_init(IDirect3DDevice8Impl *device, struct wined3d *wined3d, UINT adapter, +HRESULT device_init(IDirect3DDevice8Impl *device, IDirect3D8Impl *parent, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) DECLSPEC_HIDDEN; /* ---------------- */ diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index aa85c61c398..6266bfa26ba 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -301,6 +301,7 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(IDirect3DDevice8 *iface) if (ref == 0) { unsigned i; + IDirect3D8 *parent = This->d3d_parent; TRACE("Releasing wined3d device %p.\n", This->wined3d_device); @@ -320,6 +321,8 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(IDirect3DDevice8 *iface) HeapFree(GetProcessHeap(), 0, This); wined3d_mutex_unlock(); + + IDirect3D8_Release(parent); } return ref; } @@ -373,8 +376,6 @@ static HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(IDirect3D static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(IDirect3DDevice8 *iface, IDirect3D8 **ppD3D8) { IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface); - struct wined3d *wined3d; - HRESULT hr; TRACE("iface %p, d3d8 %p.\n", iface, ppD3D8); @@ -382,24 +383,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(IDirect3DDevice8 *iface, return D3DERR_INVALIDCALL; } - wined3d_mutex_lock(); - hr = wined3d_device_get_wined3d(This->wined3d_device, &wined3d); - if (SUCCEEDED(hr) && wined3d) - { - *ppD3D8 = wined3d_get_parent(wined3d); - IDirect3D8_AddRef(*ppD3D8); - wined3d_decref(wined3d); - } - else - { - FIXME("Call to IWineD3DDevice_GetDirect3D failed\n"); - *ppD3D8 = NULL; - } - wined3d_mutex_unlock(); - - TRACE("(%p) returning %p\n",This , *ppD3D8); - - return hr; + return IDirect3D8_QueryInterface(This->d3d_parent, &IID_IDirect3D8, (void **)ppD3D8); } static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS8 *pCaps) @@ -3095,7 +3079,7 @@ static void setup_fpu(void) #endif } -HRESULT device_init(IDirect3DDevice8Impl *device, struct wined3d *wined3d, UINT adapter, +HRESULT device_init(IDirect3DDevice8Impl *device, IDirect3D8Impl *parent, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) { WINED3DPRESENT_PARAMETERS wined3d_parameters; @@ -3209,6 +3193,9 @@ HRESULT device_init(IDirect3DDevice8Impl *device, struct wined3d *wined3d, UINT goto err; } + device->d3d_parent = &parent->IDirect3D8_iface; + IDirect3D8_AddRef(device->d3d_parent); + return D3D_OK; err: diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 249399e8452..266b68e7334 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -368,7 +368,7 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(IDirect3D8 *iface, UINT adapte return E_OUTOFMEMORY; } - hr = device_init(object, This->WineD3D, adapter, device_type, focus_window, flags, parameters); + hr = device_init(object, This, This->WineD3D, adapter, device_type, focus_window, flags, parameters); if (FAILED(hr)) { WARN("Failed to initialize device, hr %#x.\n", hr); diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 3bb70b7d1c9..9a4369b09d1 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -343,6 +343,7 @@ static void test_refcount(void) HRESULT hr; HWND hwnd = NULL; IDirect3D8 *pD3d = NULL; + IDirect3D8 *pD3d2 = NULL; IDirect3DDevice8 *pDevice = NULL; IDirect3DVertexBuffer8 *pVertexBuffer = NULL; IDirect3DIndexBuffer8 *pIndexBuffer = NULL; @@ -381,6 +382,8 @@ static void test_refcount(void) ok(hwnd != NULL, "Failed to create window\n"); if (!pD3d || !hwnd) goto cleanup; + CHECK_REFCOUNT( pD3d, 1 ); + IDirect3D8_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm ); ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; @@ -401,6 +404,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 = IDirect3DDevice8_GetDirect3D(pDevice, &pD3d2); + CHECK_CALL( hr, "GetDirect3D", pDevice, refcount ); + + ok(pD3d2 == pD3d, "Expected IDirect3D8 pointers to be equal\n"); + CHECK_REFCOUNT( pD3d, 3 ); + CHECK_RELEASE_REFCOUNT( pD3d, 2 ); + /** * Check refcount of implicit surfaces. Findings: * - the container is the device