diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index a66628cc60d..db5c106948c 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -371,7 +371,16 @@ 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 ((wined3d_output = wined3d_get_adapter_output(output->adapter->factory->wined3d, + output->adapter->ordinal))) + 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 726b1e37754..20130a75b2e 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -62,6 +62,56 @@ const GLenum magLookup[] = GL_NEAREST, GL_NEAREST, GL_LINEAR, }; +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); +} + +static void wined3d_output_cleanup(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); +} + +static HRESULT wined3d_output_init(struct wined3d_output *output, const WCHAR *device_name) +{ + D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME open_adapter_desc; + D3DKMT_CREATEDEVICE create_device_desc = {{0}}; + D3DKMT_CLOSEADAPTER close_adapter_desc; + + TRACE("output %p, device_name %s.\n", output, wine_dbgstr_w(device_name)); + + lstrcpyW(open_adapter_desc.DeviceName, device_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; +} + /* Adjust the amount of used texture memory */ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) { @@ -74,6 +124,7 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) void wined3d_adapter_cleanup(struct wined3d_adapter *adapter) { + wined3d_output_cleanup(&adapter->output); heap_free(adapter->formats); } @@ -827,6 +878,16 @@ HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned in return WINED3D_OK; } +struct wined3d_output * CDECL wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int adapter_idx) +{ + TRACE("wined3d %p, adapter_idx %u.\n", wined3d, adapter_idx); + + if (adapter_idx >= wined3d->adapter_count) + return NULL; + + return &wined3d->adapters[adapter_idx]->output; +} + /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes of the same bpp but different resolutions */ @@ -2715,6 +2776,7 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal, const struct wined3d_adapter_ops *adapter_ops) { DISPLAY_DEVICEW display_device; + HRESULT hr; adapter->ordinal = ordinal; @@ -2722,10 +2784,16 @@ 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(hr = wined3d_output_init(&adapter->output, adapter->device_name))) + { + ERR("Failed to initialise output, hr %#x.\n", hr); + return FALSE; + } if (!AllocateLocallyUniqueId(&adapter->luid)) { ERR("Failed to set adapter LUID (%#x).\n", GetLastError()); + wined3d_output_cleanup(&adapter->output); return FALSE; } TRACE("Allocated LUID %08x:%08x for adapter %p.\n", diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 2b5b6c7667f..771b9597e5d 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -15,6 +15,7 @@ @ 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) @@ -191,6 +192,8 @@ @ cdecl wined3d_device_update_texture(ptr ptr ptr) @ cdecl wined3d_device_validate_device(ptr ptr) +@ cdecl wined3d_output_release_ownership(ptr) + @ cdecl wined3d_palette_create(ptr long long ptr ptr) @ cdecl wined3d_palette_decref(ptr) @ cdecl wined3d_palette_get_entries(ptr long long long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index eaa6493ac40..4f48687f7d6 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2860,6 +2860,13 @@ struct wined3d_adapter_ops struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value); }; +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 +2877,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 cedbb09eba6..1a9551e3926 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2115,11 +2115,12 @@ struct wined3d_parent_ops }; struct wined3d; +struct wined3d_blend_state; struct wined3d_buffer; struct wined3d_device; +struct wined3d_output; struct wined3d_palette; struct wined3d_query; -struct wined3d_blend_state; struct wined3d_rasterizer_state; struct wined3d_rendertarget_view; struct wined3d_resource; @@ -2205,6 +2206,7 @@ HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UI DWORD flags, struct wined3d_adapter_identifier *identifier); UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering); +struct wined3d_output * __cdecl wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int adapter_idx); HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx, struct wined3d_raster_status *raster_status); HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, unsigned int adapter_idx, @@ -2487,6 +2489,8 @@ HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device, struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture); HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes); +void __cdecl wined3d_output_release_ownership(const struct wined3d_output *output); + HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags, unsigned int entry_count, const PALETTEENTRY *entries, struct wined3d_palette **palette); ULONG __cdecl wined3d_palette_decref(struct wined3d_palette *palette);