dxgi: Implement dxgi_swapchain_GetDevice().
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:
parent
d7b8c2e8f6
commit
282afc4450
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
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 =
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
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)
|
||||||
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
|
||||||
);
|
);
|
||||||
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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue