[PATCH v2 1/2] dxgi: Implement dxgi_output_ReleaseOwnership.
Zhiyi Zhang
zzhang at codeweavers.com
Thu Oct 24 07:46:39 CDT 2019
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
v2: Fix a typo. Supersede 171911~171912
dlls/dxgi/dxgi_private.h | 1 +
dlls/dxgi/output.c | 22 +++++++++---
dlls/wined3d/directx.c | 62 ++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d.spec | 3 ++
dlls/wined3d/wined3d_private.h | 7 ++++
include/wine/wined3d.h | 4 +++
6 files changed, 95 insertions(+), 4 deletions(-)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 5b93449834..6506b3a392 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -146,6 +146,7 @@ struct dxgi_output
LONG refcount;
struct wined3d_private_store private_store;
struct dxgi_adapter *adapter;
+ struct wined3d_output *wined3d_output;
};
HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output) DECLSPEC_HIDDEN;
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
index abe1aef950..1faf202e24 100644
--- a/dlls/dxgi/output.c
+++ b/dlls/dxgi/output.c
@@ -203,6 +203,7 @@ static ULONG STDMETHODCALLTYPE dxgi_output_Release(IDXGIOutput4 *iface)
if (!refcount)
{
+ wined3d_output_destroy(output->wined3d_output);
wined3d_private_store_cleanup(&output->private_store);
IWineDXGIAdapter_Release(&output->adapter->IWineDXGIAdapter_iface);
heap_free(output);
@@ -342,7 +343,13 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput4 *iface,
static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput4 *iface)
{
- FIXME("iface %p stub!\n", iface);
+ struct dxgi_output *output = impl_from_IDXGIOutput4(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_output_release_ownership(output->wined3d_output);
+ wined3d_mutex_unlock();
}
static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOutput4 *iface,
@@ -530,13 +537,21 @@ struct dxgi_output *unsafe_impl_from_IDXGIOutput(IDXGIOutput *iface)
return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput4_iface);
}
-static void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter)
+static HRESULT dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter)
{
+ struct wined3d_output_desc wined3d_desc;
+
output->IDXGIOutput4_iface.lpVtbl = &dxgi_output_vtbl;
output->refcount = 1;
wined3d_private_store_init(&output->private_store);
output->adapter = adapter;
IWineDXGIAdapter_AddRef(&output->adapter->IWineDXGIAdapter_iface);
+
+ wined3d_mutex_lock();
+ wined3d_get_output_desc(output->adapter->factory->wined3d, output->adapter->ordinal, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ return wined3d_output_create(wined3d_desc.device_name, &output->wined3d_output);
}
HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output)
@@ -544,6 +559,5 @@ HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **ou
if (!(*output = heap_alloc_zero(sizeof(**output))))
return E_OUTOFMEMORY;
- dxgi_output_init(*output, adapter);
- return S_OK;
+ return dxgi_output_init(*output, adapter);
}
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 726b1e3775..03c8781386 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -827,6 +827,68 @@ HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned in
return WINED3D_OK;
}
+HRESULT CDECL wined3d_output_create(const WCHAR *display_name, struct wined3d_output **target)
+{
+ D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_desc;
+ D3DKMT_CREATEDEVICE create_device_desc = {0};
+ D3DKMT_DESTROYDEVICE destroy_device_desc;
+ D3DKMT_CLOSEADAPTER close_adapter_desc;
+ struct wined3d_output *output;
+
+ TRACE("display_name %s, target %p.\n", wine_dbgstr_w(display_name), target);
+
+ lstrcpyW(open_adapter_desc.DeviceName, display_name);
+ if (D3DKMTOpenAdapterFromGdiDisplayName(&open_adapter_desc))
+ return E_INVALIDARG;
+
+ create_device_desc.u.hAdapter = open_adapter_desc.hAdapter;
+ if (D3DKMTCreateDevice(&create_device_desc))
+ {
+ close_adapter_desc.hAdapter = open_adapter_desc.hAdapter;
+ D3DKMTCloseAdapter(&close_adapter_desc);
+ return E_FAIL;
+ }
+
+ if (!(output = heap_alloc(sizeof(*output))))
+ {
+ destroy_device_desc.hDevice = create_device_desc.hDevice;
+ D3DKMTDestroyDevice(&destroy_device_desc);
+ close_adapter_desc.hAdapter = open_adapter_desc.hAdapter;
+ D3DKMTCloseAdapter(&close_adapter_desc);
+ return E_OUTOFMEMORY;
+ }
+
+ output->kmt_adapter = open_adapter_desc.hAdapter;
+ output->kmt_device = create_device_desc.hDevice;
+ output->vidpn_source_id = open_adapter_desc.VidPnSourceId;
+ *target = output;
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_output_destroy(struct wined3d_output *output)
+{
+ D3DKMT_CLOSEADAPTER close_adapter_desc;
+ D3DKMT_DESTROYDEVICE destroy_device_desc;
+
+ TRACE("output %p.\n", output);
+
+ destroy_device_desc.hDevice = output->kmt_device;
+ D3DKMTDestroyDevice(&destroy_device_desc);
+ close_adapter_desc.hAdapter = output->kmt_adapter;
+ D3DKMTCloseAdapter(&close_adapter_desc);
+ heap_free(output);
+}
+
+void CDECL wined3d_output_release_ownership(const struct wined3d_output *output)
+{
+ D3DKMT_SETVIDPNSOURCEOWNER set_owner_desc = {0};
+
+ TRACE("output %p.\n", output);
+
+ set_owner_desc.hDevice = output->kmt_device;
+ D3DKMTSetVidPnSourceOwner(&set_owner_desc);
+}
+
/* 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 2df6c510b1..2e3a642813 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -19,6 +19,9 @@
@ cdecl wined3d_get_device_caps(ptr long long ptr)
@ cdecl wined3d_get_output_desc(ptr long ptr)
@ cdecl wined3d_incref(ptr)
+@ cdecl wined3d_output_create(str ptr)
+@ cdecl wined3d_output_destroy(ptr)
+@ cdecl wined3d_output_release_ownership(ptr)
@ 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/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 307f7a42ad..de99b2a8d0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2952,6 +2952,13 @@ BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx
void install_gl_compat_wrapper(struct wined3d_gl_info *gl_info, enum wined3d_gl_extension ext) DECLSPEC_HIDDEN;
+struct wined3d_output
+{
+ D3DKMT_HANDLE kmt_adapter;
+ D3DKMT_HANDLE kmt_device;
+ D3DDDI_VIDEO_PRESENT_SOURCE_ID vidpn_source_id;
+};
+
enum wined3d_projection_type
{
WINED3D_PROJECTION_NONE = 0,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 57f5775409..b75b544d11 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2120,6 +2120,7 @@ struct wined3d_device;
struct wined3d_palette;
struct wined3d_query;
struct wined3d_blend_state;
+struct wined3d_output;
struct wined3d_rasterizer_state;
struct wined3d_rendertarget_view;
struct wined3d_resource;
@@ -2212,6 +2213,9 @@ HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, unsigned
HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx,
struct wined3d_output_desc *desc);
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
+HRESULT __cdecl wined3d_output_create(const WCHAR *display_name, struct wined3d_output **target);
+void __cdecl wined3d_output_destroy(struct wined3d_output *output);
+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,
struct wined3d_device *device, unsigned int flags);
--
2.23.0
More information about the wine-devel
mailing list