Since the factory and adapter interfaces may be wrapped, calling IDXGIAdapter_EnumOutputs() on a wrapped adapter may in turn return a wrapped output interface. Things would go poorly from there, so make sure we have a unwrapped interface here. Alternatively, we could have allowed output interfaces to be wrapped, but tests show that e.g. IDXGISwapChain_SetFullscreenState() fails when passed a wrapped output interface.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/dxgi/device.c | 11 +++++++++-- dlls/dxgi/dxgi_private.h | 2 +- dlls/dxgi/swapchain.c | 14 +++++++------- dlls/dxgi/tests/dxgi.c | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index 74260f9b769..07773052582 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -428,13 +428,20 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDX struct dxgi_device *device = impl_from_IWineDXGISwapChainFactory(iface); struct wined3d_swapchain_desc wined3d_desc; struct IDXGIOutput *containing_output; + struct dxgi_factory *dxgi_factory; struct d3d11_swapchain *object; HRESULT hr;
TRACE("iface %p, factory %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n", iface, factory, window, desc, fullscreen_desc, output, swapchain);
- if (FAILED(hr = dxgi_get_output_from_window(factory, window, &containing_output))) + if (!(dxgi_factory = unsafe_impl_from_IDXGIFactory(factory))) + { + WARN("Factory %p is not a valid dxgi factory.\n", factory); + return E_FAIL; + } + + if (FAILED(hr = dxgi_get_output_from_window(&dxgi_factory->IWineDXGIFactory_iface, window, &containing_output))) { WARN("Failed to get output from window %p, hr %#x.\n", window, hr); return hr; @@ -544,7 +551,7 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l }
window = dxgi_factory_get_device_window(dxgi_factory); - if (FAILED(hr = dxgi_get_output_from_window(factory, window, &output))) + if (FAILED(hr = dxgi_get_output_from_window(&dxgi_factory->IWineDXGIFactory_iface, window, &output))) { ERR("Failed to get output from window %p.\n", window); wined3d_device_decref(device->wined3d_device); diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index 8037b401a7f..34e53af2138 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -96,7 +96,7 @@ void wined3d_display_mode_from_dxgi1(struct wined3d_display_mode *wined3d_mode, DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) DECLSPEC_HIDDEN; unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE usage) DECLSPEC_HIDDEN; unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) DECLSPEC_HIDDEN; -HRESULT dxgi_get_output_from_window(IDXGIFactory *factory, HWND window, IDXGIOutput **dxgi_output) +HRESULT dxgi_get_output_from_window(IWineDXGIFactory *factory, HWND window, IDXGIOutput **dxgi_output) DECLSPEC_HIDDEN; HRESULT wined3d_swapchain_desc_from_dxgi(struct wined3d_swapchain_desc *wined3d_desc, IDXGIOutput *dxgi_containing_output, HWND window, const DXGI_SWAP_CHAIN_DESC1 *dxgi_desc, diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 585be83634c..5b3ca5b5762 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -111,7 +111,7 @@ BOOL dxgi_validate_swapchain_desc(const DXGI_SWAP_CHAIN_DESC1 *desc) return TRUE; }
-HRESULT dxgi_get_output_from_window(IDXGIFactory *factory, HWND window, IDXGIOutput **dxgi_output) +HRESULT dxgi_get_output_from_window(IWineDXGIFactory *factory, HWND window, IDXGIOutput **dxgi_output) { unsigned int adapter_idx, output_idx; DXGI_OUTPUT_DESC desc; @@ -126,7 +126,7 @@ HRESULT dxgi_get_output_from_window(IDXGIFactory *factory, HWND window, IDXGIOut return DXGI_ERROR_INVALID_CALL; }
- for (adapter_idx = 0; SUCCEEDED(hr = IDXGIFactory_EnumAdapters(factory, adapter_idx, &adapter)); + for (adapter_idx = 0; SUCCEEDED(hr = IWineDXGIFactory_EnumAdapters(factory, adapter_idx, &adapter)); ++adapter_idx) { for (output_idx = 0; SUCCEEDED(hr = IDXGIAdapter_EnumOutputs(adapter, output_idx, @@ -585,7 +585,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapCh }
window = d3d11_swapchain_get_hwnd(swapchain); - return dxgi_get_output_from_window((IDXGIFactory *)swapchain->factory, window, output); + return dxgi_get_output_from_window(swapchain->factory, window, output); }
static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFrameStatistics(IDXGISwapChain1 *iface, @@ -2453,7 +2453,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh { struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain4(iface); IUnknown *device_parent; - IDXGIFactory *factory; + IWineDXGIFactory *factory; IDXGIAdapter *adapter; HRESULT hr;
@@ -2473,7 +2473,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh return hr; }
- if (FAILED(hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory))) + if (FAILED(hr = IDXGIAdapter_GetParent(adapter, &IID_IWineDXGIFactory, (void **)&factory))) { WARN("Failed to get factory, hr %#x.\n", hr); IDXGIAdapter_Release(adapter); @@ -2481,7 +2481,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh }
hr = dxgi_get_output_from_window(factory, swapchain->window, output); - IDXGIFactory_Release(factory); + IWineDXGIFactory_Release(factory); IDXGIAdapter_Release(adapter); return hr; } @@ -3041,7 +3041,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return DXGI_ERROR_UNSUPPORTED; }
- if (FAILED(hr = dxgi_get_output_from_window((IDXGIFactory *)factory, window, &output))) + if (FAILED(hr = dxgi_get_output_from_window(factory, window, &output))) { WARN("Failed to get output from window %p, hr %#x.\n", window, hr); return hr; diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index b10a19c3db9..57547f1b540 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -5465,8 +5465,8 @@ static void test_object_wrapping(void)
hr = IDXGIAdapter_GetDesc(&wrapper.IDXGIAdapter_iface, &desc); ok(hr == S_OK, "Failed to get adapter desc, hr %#x.\n", hr); - todo_wine ok(!wrapper.factory.wrapped_adapter_count, - "Got unexpected wrapped adapter count %u.\n", wrapper.factory.wrapped_adapter_count); + ok(!wrapper.factory.wrapped_adapter_count, "Got unexpected wrapped adapter count %u.\n", + wrapper.factory.wrapped_adapter_count); ok(!wrapper.wrapped_output_count, "Got unexpected wrapped output count %u.\n", wrapper.wrapped_output_count);
refcount = IDXGIAdapter_Release(&wrapper.IDXGIAdapter_iface);