Commit 282afc44 authored by Józef Kucia's avatar Józef Kucia Committed by Alexandre Julliard

dxgi: Implement dxgi_swapchain_GetDevice().

parent d7b8c2e8
...@@ -5064,7 +5064,7 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent ...@@ -5064,7 +5064,7 @@ static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent
return E_FAIL; return E_FAIL;
} }
hr = IWineDXGIDevice_create_swapchain(wine_device, desc, swapchain); hr = IWineDXGIDevice_create_swapchain(wine_device, desc, TRUE, swapchain);
IWineDXGIDevice_Release(wine_device); IWineDXGIDevice_Release(wine_device);
if (FAILED(hr)) if (FAILED(hr))
{ {
......
...@@ -310,31 +310,29 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *ifa ...@@ -310,31 +310,29 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *ifa
} }
static HRESULT STDMETHODCALLTYPE dxgi_device_create_swapchain(IWineDXGIDevice *iface, static HRESULT STDMETHODCALLTYPE dxgi_device_create_swapchain(IWineDXGIDevice *iface,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **wined3d_swapchain) struct wined3d_swapchain_desc *desc, BOOL implicit, struct wined3d_swapchain **wined3d_swapchain)
{ {
struct dxgi_device *This = impl_from_IWineDXGIDevice(iface); struct dxgi_device *device = impl_from_IWineDXGIDevice(iface);
struct dxgi_swapchain *object; struct dxgi_swapchain *object;
HRESULT hr; HRESULT hr;
TRACE("iface %p, desc %p, wined3d_swapchain %p.\n", TRACE("iface %p, desc %p, wined3d_swapchain %p.\n",
iface, desc, wined3d_swapchain); iface, desc, wined3d_swapchain);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
if (!object)
{ {
ERR("Failed to allocate DXGI swapchain object memory\n"); ERR("Failed to allocate DXGI swapchain object memory\n");
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
hr = dxgi_swapchain_init(object, This, desc); if (FAILED(hr = dxgi_swapchain_init(object, device, desc, implicit)))
if (FAILED(hr))
{ {
WARN("Failed to initialize swapchain, hr %#x.\n", hr); WARN("Failed to initialize swapchain, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object); HeapFree(GetProcessHeap(), 0, object);
return hr; return hr;
} }
TRACE("Created IDXGISwapChain %p\n", object); TRACE("Created IDXGISwapChain %p.\n", object);
*wined3d_swapchain = object->wined3d_swapchain; *wined3d_swapchain = object->wined3d_swapchain;
return S_OK; return S_OK;
......
...@@ -157,10 +157,11 @@ struct dxgi_swapchain ...@@ -157,10 +157,11 @@ struct dxgi_swapchain
LONG refcount; LONG refcount;
struct wined3d_private_store private_store; struct wined3d_private_store private_store;
struct wined3d_swapchain *wined3d_swapchain; struct wined3d_swapchain *wined3d_swapchain;
IWineDXGIDevice *device;
}; };
HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device, HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device,
struct wined3d_swapchain_desc *desc) DECLSPEC_HIDDEN; struct wined3d_swapchain_desc *desc, BOOL implicit) DECLSPEC_HIDDEN;
/* IDXGISurface */ /* IDXGISurface */
struct dxgi_surface struct dxgi_surface
......
...@@ -246,7 +246,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa ...@@ -246,7 +246,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT; wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT;
wined3d_desc.auto_restore_display_mode = TRUE; wined3d_desc.auto_restore_display_mode = TRUE;
hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, &wined3d_swapchain); hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, FALSE, &wined3d_swapchain);
IWineDXGIDevice_Release(dxgi_device); IWineDXGIDevice_Release(dxgi_device);
if (FAILED(hr)) if (FAILED(hr))
{ {
......
...@@ -70,16 +70,19 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_AddRef(IDXGISwapChain *iface) ...@@ -70,16 +70,19 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_AddRef(IDXGISwapChain *iface)
static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface) static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface)
{ {
struct dxgi_swapchain *This = impl_from_IDXGISwapChain(iface); struct dxgi_swapchain *swapchain = impl_from_IDXGISwapChain(iface);
ULONG refcount = InterlockedDecrement(&This->refcount); ULONG refcount = InterlockedDecrement(&swapchain->refcount);
TRACE("%p decreasing refcount to %u\n", This, refcount); TRACE("%p decreasing refcount to %u.\n", swapchain, refcount);
if (!refcount) if (!refcount)
{ {
IWineDXGIDevice *device = swapchain->device;
wined3d_mutex_lock(); wined3d_mutex_lock();
wined3d_swapchain_decref(This->wined3d_swapchain); wined3d_swapchain_decref(swapchain->wined3d_swapchain);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
if (device)
IWineDXGIDevice_Release(device);
} }
return refcount; return refcount;
...@@ -128,9 +131,18 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetParent(IDXGISwapChain *iface, ...@@ -128,9 +131,18 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetParent(IDXGISwapChain *iface,
static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetDevice(IDXGISwapChain *iface, REFIID riid, void **device) static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetDevice(IDXGISwapChain *iface, REFIID riid, void **device)
{ {
FIXME("iface %p, riid %s, device %p stub!\n", iface, debugstr_guid(riid), device); struct dxgi_swapchain *swapchain = impl_from_IDXGISwapChain(iface);
return E_NOTIMPL; TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device);
if (!swapchain->device)
{
ERR("Implicit swapchain does not store reference to device.\n");
*device = NULL;
return E_NOINTERFACE;
}
return IWineDXGIDevice_QueryInterface(swapchain->device, riid, device);
} }
/* IDXGISwapChain methods */ /* IDXGISwapChain methods */
...@@ -334,7 +346,7 @@ static const struct wined3d_parent_ops dxgi_swapchain_wined3d_parent_ops = ...@@ -334,7 +346,7 @@ static const struct wined3d_parent_ops dxgi_swapchain_wined3d_parent_ops =
}; };
HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device, HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device,
struct wined3d_swapchain_desc *desc) struct wined3d_swapchain_desc *desc, BOOL implicit)
{ {
HRESULT hr; HRESULT hr;
...@@ -353,5 +365,20 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device ...@@ -353,5 +365,20 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device
} }
wined3d_mutex_unlock(); 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; return S_OK;
} }
...@@ -479,7 +479,7 @@ static void test_create_swapchain(void) ...@@ -479,7 +479,7 @@ static void test_create_swapchain(void)
refcount = get_refcount((IUnknown *)factory); refcount = get_refcount((IUnknown *)factory);
todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount); todo_wine ok(refcount == 4, "Got unexpected refcount %u.\n", refcount);
refcount = get_refcount((IUnknown *)device); refcount = get_refcount((IUnknown *)device);
todo_wine ok(refcount == 3, "Got unexpected refcount %u.\n", refcount); ok(refcount == 3, "Got unexpected refcount %u.\n", refcount);
hr = IDXGISwapChain_GetDesc(swapchain, NULL); hr = IDXGISwapChain_GetDesc(swapchain, NULL);
ok(hr == E_INVALIDARG, "GetDesc unexpectedly returned %#x.\n", hr); ok(hr == E_INVALIDARG, "GetDesc unexpectedly returned %#x.\n", hr);
......
...@@ -36,6 +36,7 @@ interface IWineDXGIDevice : IDXGIDevice1 ...@@ -36,6 +36,7 @@ interface IWineDXGIDevice : IDXGIDevice1
); );
HRESULT create_swapchain( HRESULT create_swapchain(
[in] struct wined3d_swapchain_desc *desc, [in] struct wined3d_swapchain_desc *desc,
[in] BOOL implicit,
[out] struct wined3d_swapchain **wined3d_swapchain [out] struct wined3d_swapchain **wined3d_swapchain
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment