[PATCH 2/2] dxgi: Implement dxgi_output_TakeOwnership.
Zhiyi Zhang
zzhang at codeweavers.com
Wed Oct 23 10:30:30 CDT 2019
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/dxgi/output.c | 13 +++++++++++--
dlls/dxgi/tests/dxgi.c | 20 ++++++++++++--------
dlls/wined3d/directx.c | 31 +++++++++++++++++++++++++++++++
dlls/wined3d/wined3d.spec | 1 +
include/wine/wined3d.h | 1 +
5 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
index 7a387eceef..994944b31b 100644
--- a/dlls/dxgi/output.c
+++ b/dlls/dxgi/output.c
@@ -336,9 +336,18 @@ 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);
+ 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();
+ hr = wined3d_output_take_ownership(output->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 a7517c8b0a..7b661afc10 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -5581,10 +5581,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);
@@ -5594,16 +5598,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. */
@@ -5616,11 +5620,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 3cb54e1ec0..271e94c54c 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -879,6 +879,37 @@ void CDECL wined3d_output_destory(struct wined3d_output *output)
heap_free(output);
}
+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;
+ }
+}
+
void CDECL wined3d_output_release_ownership(const struct wined3d_output *output)
{
D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc = {0};
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index f3ac11ecd1..169c99208b 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -21,6 +21,7 @@
@ cdecl wined3d_incref(ptr)
@ cdecl wined3d_output_create(str ptr)
@ cdecl wined3d_output_destory(ptr)
+@ cdecl wined3d_output_take_ownership(ptr long)
@ cdecl wined3d_output_release_ownership(ptr)
@ cdecl wined3d_register_software_device(ptr ptr)
@ cdecl wined3d_register_window(ptr ptr ptr long)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 9ea9ef37e8..47ec45607d 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2215,6 +2215,7 @@ HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
HRESULT __cdecl wined3d_output_create(const WCHAR *display_name, struct wined3d_output **target);
void __cdecl wined3d_output_destory(struct wined3d_output *output);
+HRESULT __cdecl wined3d_output_take_ownership(const struct wined3d_output *output, BOOL exclusive);
void __cdecl wined3d_output_release_ownership(const struct wined3d_output *output);
HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function);
BOOL __cdecl wined3d_register_window(struct wined3d *wined3d, HWND window,
--
2.23.0
More information about the wine-devel
mailing list