Henri Verbeet : dxgi: Pass an IWineDXGIFactory pointer to dxgi_get_output_from_window().

Alexandre Julliard julliard at winehq.org
Wed May 5 16:09:01 CDT 2021


Module: wine
Branch: master
Commit: 93077d4b4f7692102aac44c2c2d6da8a11c543cb
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=93077d4b4f7692102aac44c2c2d6da8a11c543cb

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Wed May  5 16:38:49 2021 +0200

dxgi: Pass an IWineDXGIFactory pointer to dxgi_get_output_from_window().

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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

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




More information about the wine-cvs mailing list