[PATCH v2] dxgi: Search all adapters for the containing output of a swapchain.
Zhiyi Zhang
zzhang at codeweavers.com
Sun May 10 10:12:42 CDT 2020
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
v2: Fix a d3d12 test failure. Supersede 184920
dlls/dxgi/swapchain.c | 84 ++++++++++++++++++++++---------------------
1 file changed, 44 insertions(+), 40 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index f57183879d4..81ba50942ad 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -111,11 +111,13 @@ BOOL dxgi_validate_swapchain_desc(const DXGI_SWAP_CHAIN_DESC1 *desc)
return TRUE;
}
-static HRESULT dxgi_get_output_from_window(IDXGIAdapter *adapter, HWND window, IDXGIOutput **dxgi_output)
+static HRESULT dxgi_get_output_from_window(IDXGIFactory *factory, HWND window,
+ IDXGIOutput **dxgi_output)
{
+ unsigned int adapter_idx, output_idx;
DXGI_OUTPUT_DESC desc;
+ IDXGIAdapter *adapter;
IDXGIOutput *output;
- unsigned int index;
HMONITOR monitor;
HRESULT hr;
@@ -125,25 +127,32 @@ static HRESULT dxgi_get_output_from_window(IDXGIAdapter *adapter, HWND window, I
return DXGI_ERROR_INVALID_CALL;
}
- index = 0;
- while ((hr = IDXGIAdapter_EnumOutputs(adapter, index, &output)) == S_OK)
+ for (adapter_idx = 0; SUCCEEDED(hr = IDXGIFactory_EnumAdapters(factory, adapter_idx, &adapter));
+ ++adapter_idx)
{
- if (FAILED(hr = IDXGIOutput_GetDesc(output, &desc)))
+ for (output_idx = 0; SUCCEEDED(hr = IDXGIAdapter_EnumOutputs(adapter, output_idx,
+ &output)); ++output_idx)
{
- WARN("Failed to get output desc %u, hr %#x.\n", index, hr);
- ++index;
- continue;
- }
+ if (FAILED(hr = IDXGIOutput_GetDesc(output, &desc)))
+ {
+ WARN("Adapter %u output %u: Failed to get output desc, hr %#x.\n", adapter_idx,
+ output_idx, hr);
+ IDXGIOutput_Release(output);
+ continue;
+ }
- if (desc.Monitor == monitor)
- {
- *dxgi_output = output;
- return S_OK;
- }
+ if (desc.Monitor == monitor)
+ {
+ *dxgi_output = output;
+ IDXGIAdapter_Release(adapter);
+ return S_OK;
+ }
- IDXGIOutput_Release(output);
- ++index;
+ IDXGIOutput_Release(output);
+ }
+ IDXGIAdapter_Release(adapter);
}
+
if (hr != DXGI_ERROR_NOT_FOUND)
WARN("Failed to enumerate outputs, hr %#x.\n", hr);
@@ -582,9 +591,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeTarget(IDXGISwapChain1 *i
static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapChain1 *iface, IDXGIOutput **output)
{
struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface);
- IDXGIAdapter *adapter;
- IDXGIDevice *device;
- HRESULT hr;
+ HWND window;
TRACE("iface %p, output %p.\n", iface, output);
@@ -594,24 +601,14 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapCh
return S_OK;
}
- if (SUCCEEDED(hr = d3d11_swapchain_GetDevice(iface, &IID_IDXGIDevice, (void **)&device)))
+ if (!swapchain->factory)
{
- hr = IDXGIDevice_GetAdapter(device, &adapter);
- IDXGIDevice_Release(device);
+ ERR("Implicit swapchain does not store a reference to factory.\n");
+ return E_NOINTERFACE;
}
- if (SUCCEEDED(hr))
- {
- HWND hwnd = d3d11_swapchain_get_hwnd(swapchain);
- hr = dxgi_get_output_from_window(adapter, hwnd, output);
- IDXGIAdapter_Release(adapter);
- }
- else
- {
- WARN("Failed to get adapter, hr %#x.\n", hr);
- }
-
- return hr;
+ window = d3d11_swapchain_get_hwnd(swapchain);
+ return dxgi_get_output_from_window(swapchain->factory, window, output);
}
static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFrameStatistics(IDXGISwapChain1 *iface,
@@ -2423,6 +2420,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh
{
struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
IUnknown *device_parent;
+ IDXGIFactory *factory;
IDXGIAdapter *adapter;
HRESULT hr;
@@ -2436,16 +2434,22 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh
device_parent = vkd3d_get_device_parent(swapchain->device);
- if (SUCCEEDED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter)))
- {
- hr = dxgi_get_output_from_window(adapter, swapchain->window, output);
- IDXGIAdapter_Release(adapter);
- }
- else
+ if (FAILED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter)))
{
WARN("Failed to get adapter, hr %#x.\n", hr);
+ return hr;
}
+ if (FAILED(hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory)))
+ {
+ WARN("Failed to get factory, hr %#x.\n", hr);
+ IDXGIAdapter_Release(adapter);
+ return hr;
+ }
+
+ hr = dxgi_get_output_from_window(factory, swapchain->window, output);
+ IDXGIFactory_Release(factory);
+ IDXGIAdapter_Release(adapter);
return hr;
}
--
2.25.1
More information about the wine-devel
mailing list