dxgi: Implement dxgi_swapchain_GetParent().

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2016-04-14 12:20:25 +02:00 committed by Alexandre Julliard
parent 5cd719b867
commit cbf0a1b59a
3 changed files with 46 additions and 23 deletions

View File

@ -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,

View File

@ -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,6 +384,28 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device
{
HRESULT hr;
/**
* A reference to the implicit swapchain is held by the wined3d device.
* In order to avoid circular references we do not keep a reference
* to the device in the implicit swapchain.
*/
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();
@ -384,24 +417,13 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device
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();
/**
* A reference to the implicit swapchain is held by the wined3d device.
* In order to avoid circular references we do not keep a reference
* to the device in the implicit swapchain.
*/
if (!implicit)
{
swapchain->device = &device->IWineDXGIDevice_iface;
IWineDXGIDevice_AddRef(swapchain->device);
}
else
{
swapchain->device = NULL;
}
return S_OK;
}

View File

@ -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);