[PATCH v3 2/2] dxgi: Implement dxgi_output_TakeOwnership.

Zhiyi Zhang zzhang at codeweavers.com
Tue Oct 29 04:35:08 CDT 2019


Signed-off-by: Zhiyi Zhang <zzhang at 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,
-- 
2.23.0



More information about the wine-devel mailing list