Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- v3: Make wined3d_adapter owns wined3d_output. Supersede 171976~171977
dlls/dxgi/output.c | 13 ++++++- dlls/wined3d/directx.c | 67 ++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 2 + dlls/wined3d/wined3d_private.h | 12 ++++++ include/wine/wined3d.h | 4 ++ 5 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index a66628cc60..9d50f193e0 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -371,7 +371,18 @@ 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); + struct wined3d_output *wined3d_output; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + if (SUCCEEDED(wined3d_get_adapter_output(output->adapter->factory->wined3d, + output->adapter->ordinal, &wined3d_output))) + { + wined3d_output_release_ownership(wined3d_output); + } + wined3d_mutex_unlock(); }
static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOutput4 *iface, diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 726b1e3775..6c1393b17b 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -74,6 +74,7 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
void wined3d_adapter_cleanup(struct wined3d_adapter *adapter) { + wined3d_output_destroy(&adapter->output); heap_free(adapter->formats); }
@@ -827,6 +828,67 @@ HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned in return WINED3D_OK; }
+HRESULT wined3d_output_create(const WCHAR *adapter_name, struct wined3d_output *output) +{ + D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_desc; + D3DKMT_CREATEDEVICE create_device_desc = {0}; + D3DKMT_CLOSEADAPTER close_adapter_desc; + + TRACE("adapter_name %s, output %p.\n", wine_dbgstr_w(adapter_name), output); + + lstrcpyW(open_adapter_desc.DeviceName, adapter_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; + } + + output->kmt_adapter = open_adapter_desc.hAdapter; + output->kmt_device = create_device_desc.hDevice; + output->vidpn_source_id = open_adapter_desc.VidPnSourceId; + return WINED3D_OK; +} + +void wined3d_output_destroy(const struct wined3d_output *output) +{ + D3DKMT_DESTROYDEVICE destroy_device_desc; + D3DKMT_CLOSEADAPTER close_adapter_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); +} + +HRESULT CDECL wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int adapter_idx, + struct wined3d_output **output) +{ + TRACE("wined3d %p, adapter_idx %u, output %p.\n", wined3d, adapter_idx, output); + + if (adapter_idx >= wined3d->adapter_count) + return WINED3DERR_INVALIDCALL; + + *output = &wined3d->adapters[adapter_idx]->output; + return WINED3D_OK; +} + +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 */
@@ -2722,6 +2784,11 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal, EnumDisplayDevicesW(NULL, ordinal, &display_device, 0); TRACE("Display device: %s.\n", debugstr_w(display_device.DeviceName)); strcpyW(adapter->device_name, display_device.DeviceName); + if (FAILED(wined3d_output_create(adapter->device_name, &adapter->output))) + { + ERR("Failed to create output.\n"); + return FALSE; + }
if (!AllocateLocallyUniqueId(&adapter->luid)) { diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index d0ba31bf4e..66c36dc745 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -15,10 +15,12 @@ @ cdecl wined3d_get_adapter_display_mode(ptr long ptr ptr) @ cdecl wined3d_get_adapter_identifier(ptr long long ptr) @ cdecl wined3d_get_adapter_mode_count(ptr long long long) +@ cdecl wined3d_get_adapter_output(ptr long ptr) @ cdecl wined3d_get_adapter_raster_status(ptr long ptr) @ cdecl wined3d_get_device_caps(ptr long long ptr) @ cdecl wined3d_get_output_desc(ptr long ptr) @ cdecl wined3d_incref(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 eaa6493ac4..85e2cc2e27 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2860,6 +2860,17 @@ struct wined3d_adapter_ops struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value); };
+HRESULT wined3d_output_create(const WCHAR *adapter_name, struct wined3d_output *output) DECLSPEC_HIDDEN; +void wined3d_output_destroy(const struct wined3d_output *output) DECLSPEC_HIDDEN; + +/* The output structure */ +struct wined3d_output +{ + D3DKMT_HANDLE kmt_adapter; + D3DKMT_HANDLE kmt_device; + D3DDDI_VIDEO_PRESENT_SOURCE_ID vidpn_source_id; +}; + /* The adapter structure */ struct wined3d_adapter { @@ -2870,6 +2881,7 @@ struct wined3d_adapter struct wined3d_gl_info gl_info; struct wined3d_d3d_info d3d_info; struct wined3d_driver_info driver_info; + struct wined3d_output output; UINT64 vram_bytes_used; GUID driver_uuid; GUID device_uuid; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index a567cfd2f1..650dffd9f3 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; @@ -2207,6 +2208,9 @@ UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering); HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx, struct wined3d_raster_status *raster_status); +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_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,