From: Józef Kucia Subject: [PATCH 11/11] dxgi/tests: Implement dxgi_swapchain_GetParent(). Message-Id: <1460456986-5082-11-git-send-email-jkucia@codeweavers.com> Date: Tue, 12 Apr 2016 12:29:46 +0200 In-Reply-To: <1460456986-5082-1-git-send-email-jkucia@codeweavers.com> References: <1460456986-5082-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/dxgi/dxgi_private.h | 1 + dlls/dxgi/swapchain.c | 56 +++++++++++++++++++++++++++++++++--------------- dlls/dxgi/tests/device.c | 12 +++++------ 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index aca17ba..129f6b4 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -156,6 +156,7 @@ struct dxgi_swapchain struct wined3d_private_store private_store; struct wined3d_swapchain *wined3d_swapchain; IWineDXGIDevice *device; + IDXGIFactory *factory; }; HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device, diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index da705e4..921fcdf 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -78,6 +78,8 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface) if (!refcount) { IWineDXGIDevice *device = swapchain->device; + if (swapchain->factory) + IDXGIFactory_Release(swapchain->factory); wined3d_mutex_lock(); wined3d_swapchain_decref(swapchain->wined3d_swapchain); wined3d_mutex_unlock(); @@ -122,9 +124,18 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetPrivateData(IDXGISwapChain *i static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetParent(IDXGISwapChain *iface, REFIID riid, void **parent) { - FIXME("iface %p, riid %s, parent %p stub!\n", iface, debugstr_guid(riid), parent); + struct dxgi_swapchain *swapchain = impl_from_IDXGISwapChain(iface); - return E_NOTIMPL; + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + if (!swapchain->factory) + { + ERR("Implicit swapchain does not store reference to parent.\n"); + *parent = NULL; + return E_NOINTERFACE; + } + + return IDXGIFactory_QueryInterface(swapchain->factory, riid, parent); } /* IDXGIDeviceSubObject methods */ @@ -373,21 +384,6 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device { HRESULT hr; - swapchain->IDXGISwapChain_iface.lpVtbl = &dxgi_swapchain_vtbl; - swapchain->refcount = 1; - wined3d_mutex_lock(); - wined3d_private_store_init(&swapchain->private_store); - - if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, - &dxgi_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain))) - { - WARN("Failed to create wined3d swapchain, hr %#x.\n", hr); - wined3d_private_store_cleanup(&swapchain->private_store); - wined3d_mutex_unlock(); - return hr; - } - wined3d_mutex_unlock(); - /** * A reference to the implicit swapchain is held by the wined3d device. * In order to avoid circular references we do not keep a reference @@ -395,13 +391,39 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device */ if (!implicit) { + if (FAILED(hr = IDXGIAdapter1_GetParent(device->adapter, &IID_IDXGIFactory, + (void **)&swapchain->factory))) + { + WARN("Failed to get adapter parent, hr %#x.\n", hr); + return hr; + } swapchain->device = &device->IWineDXGIDevice_iface; IWineDXGIDevice_AddRef(swapchain->device); } else { swapchain->device = NULL; + swapchain->factory = NULL; } + swapchain->IDXGISwapChain_iface.lpVtbl = &dxgi_swapchain_vtbl; + swapchain->refcount = 1; + wined3d_mutex_lock(); + wined3d_private_store_init(&swapchain->private_store); + + if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, + &dxgi_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain))) + { + WARN("Failed to create wined3d swapchain, hr %#x.\n", hr); + wined3d_private_store_cleanup(&swapchain->private_store); + wined3d_mutex_unlock(); + if (swapchain->factory) + IDXGIFactory_Release(swapchain->factory); + if (swapchain->device) + IWineDXGIDevice_Release(swapchain->device); + return hr; + } + wined3d_mutex_unlock(); + return S_OK; } diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index ab294f8..5808b64 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -485,15 +485,15 @@ static void test_create_swapchain(void) ok(hr == E_INVALIDARG, "GetDesc unexpectedly returned %#x.\n", hr); hr = IDXGISwapChain_GetParent(swapchain, &IID_IUnknown, (void **)&parent); - todo_wine ok(SUCCEEDED(hr), "GetParent failed %#x.\n", hr); - todo_wine ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent); - if (SUCCEEDED(hr)) refcount = IUnknown_Release(parent); + ok(SUCCEEDED(hr), "GetParent failed %#x.\n", hr); + ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent); + refcount = IUnknown_Release(parent); todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount); hr = IDXGISwapChain_GetParent(swapchain, &IID_IDXGIFactory, (void **)&parent); - todo_wine ok(SUCCEEDED(hr), "GetParent failed %#x.\n", hr); - todo_wine ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent); - if (SUCCEEDED(hr)) refcount = IUnknown_Release(parent); + ok(SUCCEEDED(hr), "GetParent failed %#x.\n", hr); + ok(parent == (IUnknown *)factory, "Got unexpected parent interface pointer %p.\n", parent); + refcount = IUnknown_Release(parent); todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount); IDXGISwapChain_Release(swapchain); -- 2.4.10