Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/dxgi/output.c | 18 ++++++++++++++++-- dlls/dxgi/tests/dxgi.c | 20 ++++++++++++-------- dlls/wined3d/directx.c | 31 +++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 1 + 5 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 9d50f193e0..9aae518541 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -364,9 +364,23 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_WaitForVBlank(IDXGIOutput4 *iface)
static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput4 *iface, IUnknown *device, BOOL exclusive) { - FIXME("iface %p, device %p, exclusive %d stub!\n", iface, device, exclusive); + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + struct wined3d_output *wined3d_output; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, device %p, exclusive %d.\n", iface, device, exclusive); + + if (!device) + return DXGI_ERROR_INVALID_CALL; + + wined3d_mutex_lock(); + if (SUCCEEDED(hr = wined3d_get_adapter_output(output->adapter->factory->wined3d, + output->adapter->ordinal, &wined3d_output))) + { + hr = wined3d_output_take_ownership(wined3d_output, exclusive); + } + wined3d_mutex_unlock(); + return hr; }
static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput4 *iface) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index cbb5806e2d..b05e7f8bf9 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -5611,10 +5611,14 @@ static void test_output_ownership(IUnknown *device, BOOL is_d3d12) wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_SUCCESS, FALSE); else wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_GRAPHICS_PRESENT_OCCLUDED, TRUE); + hr = IDXGIOutput_TakeOwnership(output, NULL, FALSE); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); + hr = IDXGIOutput_TakeOwnership(output, NULL, TRUE); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); hr = IDXGIOutput_TakeOwnership(output, device, FALSE); todo_wine ok(hr == (is_d3d12 ? E_NOINTERFACE : E_INVALIDARG), "Got unexpected hr %#x.\n", hr); hr = IDXGIOutput_TakeOwnership(output, device, TRUE); - todo_wine ok(hr == (is_d3d12 ? E_NOINTERFACE : S_OK), "Got unexpected hr %#x.\n", hr); + todo_wine_if(is_d3d12) ok(hr == (is_d3d12 ? E_NOINTERFACE : S_OK), "Got unexpected hr %#x.\n", hr); IDXGIOutput_ReleaseOwnership(output); wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_SUCCESS, FALSE);
@@ -5624,16 +5628,16 @@ static void test_output_ownership(IUnknown *device, BOOL is_d3d12) goto done;
hr = IDXGIOutput_TakeOwnership(output, device, FALSE); - todo_wine ok(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, "Got unexpected hr %#x.\n", hr); + ok(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, "Got unexpected hr %#x.\n", hr); IDXGIOutput_ReleaseOwnership(output);
hr = IDXGIOutput_TakeOwnership(output, device, TRUE); - todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); /* Note that the "exclusive" parameter to IDXGIOutput_TakeOwnership() * seems to behave opposite to what's described by MSDN. */ - wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_GRAPHICS_PRESENT_OCCLUDED, TRUE); + wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_GRAPHICS_PRESENT_OCCLUDED, FALSE); hr = IDXGIOutput_TakeOwnership(output, device, FALSE); - todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); IDXGIOutput_ReleaseOwnership(output);
/* Swapchain in windowed mode. */ @@ -5646,11 +5650,11 @@ static void test_output_ownership(IUnknown *device, BOOL is_d3d12) wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_SUCCESS, FALSE);
hr = IDXGIOutput_TakeOwnership(output, device, FALSE); - todo_wine ok(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, "Got unexpected hr %#x.\n", hr); + ok(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, "Got unexpected hr %#x.\n", hr);
hr = IDXGIOutput_TakeOwnership(output, device, TRUE); - todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); - wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_GRAPHICS_PRESENT_OCCLUDED, TRUE); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_GRAPHICS_PRESENT_OCCLUDED, FALSE); IDXGIOutput_ReleaseOwnership(output); wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_SUCCESS, FALSE);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 6c1393b17b..5999a88137 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -889,6 +889,37 @@ void CDECL wined3d_output_release_ownership(const struct wined3d_output *output) D3DKMTSetVidPnSourceOwner(&set_owner_desc); }
+HRESULT CDECL wined3d_output_take_ownership(const struct wined3d_output *output, BOOL exclusive) +{ + D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc; + D3DKMT_VIDPNSOURCEOWNER_TYPE owner_type; + NTSTATUS status; + + TRACE("output %p, exclusive %d.\n", output, exclusive); + + owner_type = exclusive ? D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE : D3DKMT_VIDPNSOURCEOWNER_SHARED; + set_owner_desc.pType = &owner_type; + set_owner_desc.pVidPnSourceId = &output->vidpn_source_id; + set_owner_desc.VidPnSourceCount = 1; + set_owner_desc.hDevice = output->kmt_device; + status = D3DKMTSetVidPnSourceOwner(&set_owner_desc); + + switch (status) + { + case STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE: + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + case STATUS_INVALID_PARAMETER: + return E_INVALIDARG; + case STATUS_PROCEDURE_NOT_FOUND: + return E_NOINTERFACE; + case STATUS_SUCCESS: + return S_OK; + default: + FIXME("Unhandled error %#x.\n", status); + return E_FAIL; + } +} + /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes of the same bpp but different resolutions */
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 66c36dc745..0909bffd78 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -21,6 +21,7 @@ @ cdecl wined3d_get_output_desc(ptr long ptr) @ cdecl wined3d_incref(ptr) @ cdecl wined3d_output_release_ownership(ptr) +@ cdecl wined3d_output_take_ownership(ptr long) @ cdecl wined3d_register_software_device(ptr ptr) @ cdecl wined3d_register_window(ptr ptr ptr long) @ cdecl wined3d_set_adapter_display_mode(ptr long ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 650dffd9f3..2fc7f818cd 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2211,6 +2211,7 @@ HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, HRESULT __cdecl wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_output **output); void __cdecl wined3d_output_release_ownership(const struct wined3d_output *output); +HRESULT __cdecl wined3d_output_take_ownership(const struct wined3d_output *output, BOOL exclusive); HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, unsigned int adapter_idx, enum wined3d_device_type device_type, struct wined3d_caps *caps); HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=58632
Your paranoid android.
=== w1064v1809_2scr (32 bit report) ===
dxgi: dxgi.c:2230: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2230: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2230: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2234: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2234: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2234: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2291: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2291: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2291: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2305: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2305: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2305: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2308: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2308: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2308: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2846: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2846: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2846: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2850: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2850: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2850: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2846: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2846: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2846: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2850: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2850: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(800,600). dxgi.c:2850: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(800,600).
=== w1064v1809_ar (32 bit report) ===
dxgi: dxgi.c:2450: Test failed: Got unexpected hr 0x887a0022. dxgi.c:2453: Test failed: Got unexpected hr 0x887a0022.