[PATCH v9 0/1] MR11398: d3d11: Fail D3D11_CREATE_DEVICE_VIDEO_SUPPORT until support (bug #50277)
Fix for UnityPlayer.dll calls to D3D11_CREATE_DEVICE_VIDEO_SUPPORT until supported. Forces UnityPlayer.dll software video decoding which skips all the cross-device multi-thread calls involving dxgi_resource_GetSharedHandle and d3d11_device_OpenSharedResource. https://bugs.winehq.org/show_bug.cgi?id=50277#c46 -- v9: wined3d: support WINE_D3D_CONFIG=no_create_flags=0x800 (MR-11398) https://gitlab.winehq.org/wine/wine/-/merge_requests/11398
From: Stian Low <wineryyyyy@gmail.com> --- dlls/dxgi/device.c | 4 ++-- dlls/dxgi/dxgi_main.c | 2 +- dlls/dxgi/dxgi_private.h | 2 +- dlls/wined3d/directx.c | 17 ++++++++++++++++- dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_main.c | 3 +++ dlls/wined3d/wined3d_private.h | 1 + include/wine/wined3d.h | 1 + 8 files changed, 26 insertions(+), 5 deletions(-) diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index eedcc81d845..15f2127eee1 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -485,7 +485,7 @@ static const struct IWineDXGISwapChainFactoryVtbl dxgi_swapchain_factory_vtbl = }; HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer, - IDXGIFactory *factory, IDXGIAdapter *adapter, + IDXGIFactory *factory, IDXGIAdapter *adapter, unsigned int flags, const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) { struct wined3d_device_parent *wined3d_device_parent; @@ -541,7 +541,7 @@ HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *l IWineDXGIDeviceParent_Release(dxgi_device_parent); if (FAILED(hr = wined3d_device_create(dxgi_factory->wined3d, - dxgi_adapter->wined3d_adapter, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4, + dxgi_adapter->wined3d_adapter, WINED3D_DEVICE_TYPE_HAL, NULL, flags, 4, (const enum wined3d_feature_level *)feature_levels, level_count, wined3d_device_parent, &device->wined3d_device))) { diff --git a/dlls/dxgi/dxgi_main.c b/dlls/dxgi/dxgi_main.c index ca1fb525535..36ce309db37 100644 --- a/dlls/dxgi/dxgi_main.c +++ b/dlls/dxgi/dxgi_main.c @@ -191,7 +191,7 @@ HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, I return E_OUTOFMEMORY; } - hr = dxgi_device_init(dxgi_device, &d3d10_layer, factory, adapter, feature_levels, level_count); + hr = dxgi_device_init(dxgi_device, &d3d10_layer, factory, adapter, flags, feature_levels, level_count); if (FAILED(hr)) { WARN("Failed to initialize device, hr %#lx.\n", hr); diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index ed82d366799..679854afd3c 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -138,7 +138,7 @@ struct dxgi_device }; HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer, - IDXGIFactory *factory, IDXGIAdapter *adapter, + IDXGIFactory *factory, IDXGIAdapter *adapter, unsigned int flags, const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count); /* IDXGIOutput */ diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index e75c3cf625e..4ce8bd5ced5 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1862,6 +1862,11 @@ HRESULT CDECL wined3d_output_get_raster_status(const struct wined3d_output *outp return WINED3D_OK; } +unsigned int CDECL wined3d_device_create_flags_forced_unsupported(void) +{ + return wined3d_settings.no_create_flags; +} + HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d_adapter *adapter, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id) @@ -2790,11 +2795,21 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, struct wined3d_adap struct wined3d_device *object; HRESULT hr; - TRACE("wined3d %p, adapter %p, device_type %#x, focus_window %p, flags %#x, " + FIXME("wined3d %p, adapter %p, device_type %#x, focus_window %p, flags %#x, " "surface_alignment %u, feature_levels %p, feature_level_count %u, device_parent %p, device %p.\n", wined3d, adapter, device_type, focus_window, flags, surface_alignment, feature_levels, feature_level_count, device_parent, device); + /* Support forcing unsupported d3d device creation flags to allow + * UnityPlayer.dll to fallback to software video decoding until support for + * resource sharing needed otherwise for D3D11_CREATE_DEVICE_VIDEO_SUPPORT: + * https://bugs.winehq.org/buglist.cgi?quicksearch=%2211398%22 */ + if (flags != (flags & ~wined3d_device_create_flags_forced_unsupported())) + { + FIXME("Failing due to d3d device creation flags 0x%x forced unsupported.\n", wined3d_device_create_flags_forced_unsupported()); + return E_FAIL; + } + if (FAILED(hr = adapter->adapter_ops->adapter_create_device(wined3d, adapter, device_type, focus_window, flags, surface_alignment, feature_levels, feature_level_count, device_parent, &object))) diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index da7db0c2184..ea6b0430367 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -2,6 +2,7 @@ @ stdcall wined3d_mutex_unlock() @ cdecl wined3d_calculate_format_pitch(ptr long long) +@ cdecl wined3d_device_create_flags_forced_unsupported() @ cdecl wined3d_check_depth_stencil_match(ptr long long long long) @ cdecl wined3d_check_device_format(ptr ptr long long long long long long) @ cdecl wined3d_check_device_format_conversion(ptr long long long) diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 91d8dd567ff..dc07d962dff 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -129,6 +129,7 @@ struct wined3d_settings wined3d_settings = .max_sm_cs = UINT_MAX, .renderer = WINED3D_RENDERER_AUTO, .shader_backend = WINED3D_SHADER_BACKEND_AUTO, + .no_create_flags = 0, }; enum wined3d_renderer CDECL wined3d_get_renderer(void) @@ -344,6 +345,8 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) { if (!get_config_key_dword(hkey, appkey, env, "csmt", &wined3d_settings.cs_multithreaded)) ERR_(winediag)("Setting multithreaded command stream to %#x.\n", wined3d_settings.cs_multithreaded); + if (!get_config_key_dword(hkey, appkey, env, "no_create_flags", &wined3d_settings.no_create_flags)) + ERR_(winediag)("Force D3D device creation without support for flags %#x.\n", wined3d_settings.no_create_flags); if (!get_config_key_dword(hkey, appkey, env, "MaxVersionGL", &tmpvalue)) { ERR_(winediag)("Setting maximum allowed wined3d GL version to %u.%u.\n", diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9537670f7c5..8f6d777168c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -466,6 +466,7 @@ struct wined3d_settings { unsigned int cs_multithreaded; unsigned int max_gl_version; + unsigned int no_create_flags; unsigned short pci_vendor_id; unsigned short pci_device_id; /* Memory tracking and object counting. */ diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 49c6672fa3f..3f042a9dc50 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2335,6 +2335,7 @@ void __stdcall wined3d_mutex_unlock(void); unsigned int __cdecl wined3d_calculate_format_pitch(const struct wined3d_adapter *adapter, enum wined3d_format_id format_id, unsigned int width); +unsigned int __cdecl wined3d_device_create_flags_forced_unsupported(void); HRESULT __cdecl wined3d_check_depth_stencil_match(const struct wined3d_adapter *adapter, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11398
Latest push supports `WINE_D3D_CONFIG=no_create_flags=0x800` for all versions of d3d via impl for wined3d vs only d3d11 which is still the only use case found so far. Fixes Hollow Knight Silksong crash for Unity 6000.0.50f1, UnityPlayer 2018.3.0a1 (same crash for 2 different versions including GOG-89650): - https://unity.com/releases/editor/whats-new/6000.0.50f1 6000.0.50f1 is 2025 release but UnityPlayer may be 2018. I did not find 2018 docs but 2019 args seem to apply but none fix crash: - https://docs.unity3d.com/2019.4/Documentation/Manual/PlayerCommandLineArgume... `-force-opengl` `-force-glcore` `-force-vulkan` all throw `Failed to initialize player` popup error preventing launch which may be separate bugs. `-force-d3d12` shows damavand instead of VKD3D which may also be a separate bug. MR-11404 does not fix crash which seems to indicate that this merge has wider/independent scope from `GetSharedHandle` speculated by @zfigura as a better solution and justification for rejecting this merge. Silksong is the first game I've found so far not fixed via MR-11404 as alternative to this merge which minimally supports `GetSharedHandle` only via `WINE_D3D_CONFIG=csmt=0x2,renderer=vulkan` for now until ready. Silksong logs d3d device create flag `0x820` but not `GetSharedHandle` which seems to explain why MR-11404 does not fix and apply: - `0024:fixme:dxgi:DXGID3D10CreateDevice Ignoring flags 0x820.` This seems to backup my theory that despite `D3D11_CREATE_DEVICE_VIDEO_SUPPORT` currently allowed, it is not technically fully supported if at all. I will work to support whatever may be missing to satisfy `D3D11_CREATE_DEVICE_VIDEO_SUPPORT` via a separate merge request. In the meantime I still think this merge request is valid and useful in the same way as the other `WINE_D3D_CONFIG` options and UnityPlayer args like `-force-d3d11` etc. Therefore this merge may be even less out of question now as @hverbeet suggested may be the case earlier. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11398#note_147538
On Sat Aug 1 09:15:08 2026 +0000, Stian Low wrote:
Latest push supports `WINE_D3D_CONFIG=no_create_flags=0x800` for all versions of d3d via impl for wined3d vs only d3d11 which is still the only use case found so far. Fixes Hollow Knight Silksong crash for Unity 6000.0.50f1, UnityPlayer 2018.3.0a1 (same crash for 2 different versions including GOG-89650): - https://unity.com/releases/editor/whats-new/6000.0.50f1 6000.0.50f1 is 2025 release but UnityPlayer may be 2018. I did not find 2018 docs but 2019 args seem to apply but none fix crash: - https://docs.unity3d.com/2019.4/Documentation/Manual/PlayerCommandLineArgume... `-force-opengl` `-force-glcore` `-force-vulkan` all throw `Failed to initialize player` popup error preventing launch which may be separate bugs. `-force-d3d12` shows damavand instead of VKD3D which may also be a separate bug. MR-11404 does not fix crash which seems to indicate that this merge has wider/independent scope from `GetSharedHandle` speculated by @zfigura as a better solution and justification for rejecting this merge. Silksong is the first game I've found so far not fixed via MR-11404 as alternative to this merge which minimally supports `GetSharedHandle` only via `WINE_D3D_CONFIG=csmt=0x2,renderer=vulkan` for now until ready. Silksong logs d3d device create flag `0x820` but not `GetSharedHandle` which seems to explain why MR-11404 does not fix and apply: - `0024:fixme:dxgi:DXGID3D10CreateDevice Ignoring flags 0x820.` This seems to backup my theory that despite `D3D11_CREATE_DEVICE_VIDEO_SUPPORT` currently allowed, it is not technically fully supported if at all. I will work to support whatever may be missing to satisfy `D3D11_CREATE_DEVICE_VIDEO_SUPPORT` via a separate merge request. In the meantime I still think this merge request is valid and useful in the same way as the other `WINE_D3D_CONFIG` options and UnityPlayer args like `-force-d3d11` etc. Therefore this merge may be even less out of question now as @hverbeet suggested may be the case earlier. Silksong launch crash without `WINE_D3D_CONFIG=no_create_flags=0x800`
{width=900 height=563} {width=900 height=563} -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11398#note_147539
On Sat Aug 1 09:15:08 2026 +0000, Stian Low wrote:
Silksong launch crash without `WINE_D3D_CONFIG=no_create_flags=0x800` {width=900 height=563} {width=900 height=563} Silksong launch crash fixed via `WINE_D3D_CONFIG=no_create_flags=0x800` for both renderer=gl and vulkan including fixing videos otherwise bugged also:
{width=900 height=563} {width=900 height=563} -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11398#note_147540
On Sat Aug 1 09:20:37 2026 +0000, Stian Low wrote:
Silksong launch crash fixed via `WINE_D3D_CONFIG=no_create_flags=0x800` for both renderer=gl and vulkan including fixing videos otherwise bugged also: {width=900 height=563} {width=900 height=563} Silksong crashes for wine-11.14-4dbf7bef7a0 because `d3d11_device_CreateFence` returns `E_NOTIMPL` which is fixed by returning `S_OK` which seems to allow the game to work including videos for both renderer=gl and vulkan.
renderer=gl drops to steady 30fps as if intended only during video vs vulkan which stays at 60fps. Both games run at 60fps during gameplay. Therefore MR-11398 is not a workaround for Silksong in the same way as the other video bug duplicates for Haven. `d3d11_device_CreateFence` impl may be included as part of MR-11404 to support `GetSharedHandle` if needed otherwise it will be handled by a separate merge request. Unclear if `d3d11_device_CreateFence` is part of `D3D11_CREATE_DEVICE_VIDEO_SUPPORT` or specific to how Unity seems to implement as if `CreateFence` is dependent on `D3D11_CREATE_DEVICE_VIDEO_SUPPORT` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11398#note_147677
Okay, so I've given this a lot more thought. Thank you for the patience, and I apologize for not having a concrete answer earlier. Here are my current thoughts, and I do invite Henri to push back if he feels otherwise: * I originally thought that "video support" is something we already implement, specifically H.264 video decode. After rereading the documentation I'm less convinced; the lede is that it requires the "WDDM for Windows 8", which, considering that DXVA in a very similar form predates Windows 8, probably has more to do with resource sharing than with hardware video support. Given that I think it would actually be reasonable to just always fail creation with that flag... * ...except that I do have an application here that requires D3D11_CREATE_DEVICE_VIDEO_SUPPORT, and only uses hardware decode and no resource sharing. Making that change would break that application, so having a registry toggle would be warranted. * While I think that implementing proper resource sharing support wouldn't be too hard, it's only going to be able to work with the Vulkan backend, and while I'm working as hard as I can here, we're still a ways away from the Vulkan backend being at parity. So having a workaround until we're there makes sense. Granted, "use Damavand" itself could be the workaround... * As Stian pointed out, there is quite a long list of applications that this would fix. So even though it's not technically a regression (right?) the impact is large enough that I think it's worth having. * However, I would like it to be limited to D3D11_CREATE_DEVICE_VIDEO_SUPPORT. I want to be able to remove this workaround eventually, and that's easier when the scope is limited. With that in mind, some line-by-line review: ``` - dxgi_adapter->wined3d_adapter, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4, + dxgi_adapter->wined3d_adapter, WINED3D_DEVICE_TYPE_HAL, NULL, flags, 4, ``` These flags already have a meaning which conflicts with the d3d11 flags. See WINED3DCREATE_*. You will probably want to define your own WINED3DCREATE flags and explicitly translate to them. Simply handling D3D11_CREATE_DEVICE_VIDEO_SUPPORT is enough for now. ``` +unsigned int CDECL wined3d_device_create_flags_forced_unsupported(void) +{ + return wined3d_settings.no_create_flags; +} ``` You don't need this function; it can be inlined in its only user. ``` + /* Support forcing unsupported d3d device creation flags to allow + * UnityPlayer.dll to fallback to software video decoding until support for + * resource sharing needed otherwise for D3D11_CREATE_DEVICE_VIDEO_SUPPORT: + * https://bugs.winehq.org/buglist.cgi?quicksearch=%2211398%22 */ ``` This isn't quite grammatical, and we generally don't use Bugzilla links in code. If we want a comment I would write something like "Unity uses shared resources if D3D11_CREATE_DEVICE_VIDEO_SUPPORT succeeds, so allow failing for now." ``` + .no_create_flags = 0, ``` You don't need this; unspecified fields are zero-initialized. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11398#note_147775
participants (3)
-
Elizabeth Figura (@zfigura) -
Stian Low -
Stian Low (@stianlow)