dxgi: Search all adapters for the containing output of a swapchain.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2020-05-10 23:12:42 +08:00 committed by Alexandre Julliard
parent 0bfc64b0f1
commit 5886f4dee5
1 changed files with 44 additions and 40 deletions

View File

@ -111,11 +111,13 @@ BOOL dxgi_validate_swapchain_desc(const DXGI_SWAP_CHAIN_DESC1 *desc)
return TRUE; 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; DXGI_OUTPUT_DESC desc;
IDXGIAdapter *adapter;
IDXGIOutput *output; IDXGIOutput *output;
unsigned int index;
HMONITOR monitor; HMONITOR monitor;
HRESULT hr; HRESULT hr;
@ -125,25 +127,32 @@ static HRESULT dxgi_get_output_from_window(IDXGIAdapter *adapter, HWND window, I
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
} }
index = 0; for (adapter_idx = 0; SUCCEEDED(hr = IDXGIFactory_EnumAdapters(factory, adapter_idx, &adapter));
while ((hr = IDXGIAdapter_EnumOutputs(adapter, index, &output)) == S_OK) ++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); if (FAILED(hr = IDXGIOutput_GetDesc(output, &desc)))
++index; {
continue; 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) if (desc.Monitor == monitor)
{ {
*dxgi_output = output; *dxgi_output = output;
return S_OK; IDXGIAdapter_Release(adapter);
} return S_OK;
}
IDXGIOutput_Release(output); IDXGIOutput_Release(output);
++index; }
IDXGIAdapter_Release(adapter);
} }
if (hr != DXGI_ERROR_NOT_FOUND) if (hr != DXGI_ERROR_NOT_FOUND)
WARN("Failed to enumerate outputs, hr %#x.\n", hr); 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) static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapChain1 *iface, IDXGIOutput **output)
{ {
struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface);
IDXGIAdapter *adapter; HWND window;
IDXGIDevice *device;
HRESULT hr;
TRACE("iface %p, output %p.\n", iface, output); TRACE("iface %p, output %p.\n", iface, output);
@ -594,24 +601,14 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapCh
return S_OK; return S_OK;
} }
if (SUCCEEDED(hr = d3d11_swapchain_GetDevice(iface, &IID_IDXGIDevice, (void **)&device))) if (!swapchain->factory)
{ {
hr = IDXGIDevice_GetAdapter(device, &adapter); ERR("Implicit swapchain does not store a reference to factory.\n");
IDXGIDevice_Release(device); return E_NOINTERFACE;
} }
if (SUCCEEDED(hr)) window = d3d11_swapchain_get_hwnd(swapchain);
{ return dxgi_get_output_from_window(swapchain->factory, window, output);
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;
} }
static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFrameStatistics(IDXGISwapChain1 *iface, 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); struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
IUnknown *device_parent; IUnknown *device_parent;
IDXGIFactory *factory;
IDXGIAdapter *adapter; IDXGIAdapter *adapter;
HRESULT hr; HRESULT hr;
@ -2436,16 +2434,22 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh
device_parent = vkd3d_get_device_parent(swapchain->device); device_parent = vkd3d_get_device_parent(swapchain->device);
if (SUCCEEDED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter))) if (FAILED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter)))
{
hr = dxgi_get_output_from_window(adapter, swapchain->window, output);
IDXGIAdapter_Release(adapter);
}
else
{ {
WARN("Failed to get adapter, hr %#x.\n", hr); 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; return hr;
} }