Opening a game, closing it, and opening another crashed or device-lost on
the Vulkan backend with VR enabled. D3D11 and D3D12 both restart cleanly,
so this was Vulkan-specific rather than an OpenXR runtime limitation.
Root cause, proven with VK_EXT_device_fault plus
VK_EXT_device_address_binding_report: the fault is a write-invalid at a
page-aligned address that the binding tracer reports as not owned by the
second game device. The OpenXR compositor still references resources that
lived on the first game VkDevice; destroying that device frees the memory
and the compositor later writes into the freed page. The D3D backends are
immune because their shared compositor resources are COM ref-counted,
while vkDestroyDevice frees unconditionally.
Fix: persist and reuse the VulkanContext (VkInstance and VkDevice) across
VR games, so vkCreateDevice/vkDestroyDevice run once per process and those
pages are never unmapped. Per-game objects are still fully recreated,
including the surface, swapchain, object cache, command buffers, and the
OpenXR session and XrInstance. A device-lost context is never persisted. A
non-VR launch, or a runtime requiring a device extension the persisted
device lacks, discards it and initializes fresh.
Two problems that persisting exposed:
- InitBackendInfo() creates and destroys a temporary VkInstance on every
game boot and then calls UnloadVulkanLibrary(), which nulls every global
Vulkan function pointer. Reuse now re-resolves the instance and device
dispatch for the persisted handles.
- That same UnloadVulkanLibrary() unmaps vulkan-1.dll on runtimes that do
not otherwise pin it, invalidating the persisted handles. This is why
VDXR still failed after SteamVR worked. Added KeepVulkanLibraryLoaded()
so unloading is suppressed while a device is persisted.
Also removes the XR_KHR_vulkan_enable2 path. Creating a second device
against a retained XrInstance crashes inside the runtime in a way SEH
cannot catch. The backend now always uses legacy XR_KHR_vulkan_enable,
where Dolphin owns instance and device creation and the runtime binds at
xrCreateSession.
Supporting changes: ordered OpenXR session teardown (ShutdownSession and
DestroySession), a device-lost guard in CommandBufferManager that stops
emulation instead of resubmitting to a dead device, synchronous release of
Dolphin views and framebuffers before xrDestroySwapchain, and the two GPU
fault diagnostics. Note that vkGetDeviceFaultInfoEXT must be called with
vendorBinarySize zeroed on the second call, or the driver writes the
vendor blob to a null pointer.
Verified on SteamVR/PSVR2, VDXR/Quest 3, and Meta Link over repeated
open/close cycles.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
In WiimoteReal.cpp, JitRegCache.cpp, lambda predicates were replaced by pointers to member functions because ranges algorithms are able invoke those.
In ConvertDialog.cpp, the `std::mem_fn` helper was removed because ranges algorithms are able to handle pointers to member functions as predicates.
To further increase the accuracy of the post process phase, I've added (scRGB) HDR support, which is necessary
to fully display the PAL and NTSC-J color spaces, and also to improve the quality of post process texture samplings and
do them in linear space instead of gamma space (which is very important when playing at low resolutions).
For SDR, the quality is also slightly increased, at least if any post process runs, as the buffer is now
R10G10B10A2 (on Vulkan, DX11 and DX12) if supported; previously it was R8G8B8A8 but the alpha bits were wasted.
Gamma correction is arguably the most important thing as Dolphin on Windows outputted in "sRGB" (implicitly)
as that's what Windows expects by default, though sRGB gamma is very different from the gamma commonly used
by video standards dating to the pre HDR era (roughly gamma 2.35).
Additionally, the addition of HDR support (which is pretty straight forward and minimal), added support for
our own custom AutoHDR shaders, which would allow us to achieve decent looking HDR in Dolphin games without
having to use SpecialK or Windows 11 AutoHDR. Both of which don't necessarily play nice with older games
with strongly different and simpler lighting. HDR should also be supported in Linux.
Development of my own AutoHDR shader is almost complete and will come next.
This has been carefully tested and there should be no regression in any of the different features that Dolphin
offers, like multisampling, stereo rendering, other post processes, etc etc.
Fixes: https://bugs.dolphin-emu.org/issues/8941
Co-authored-by: EndlesslyFlowering <EndlesslyFlowering@protonmail.com>
Co-authored-by: Dogway <lin_ares@hotmail.com>
The former is deprecated and pretty much all modern drivers
support VK_EXT_debug_utils.
Android drivers dont support it. On those drivers,
we use the implementation provided by the validation layers.
Adds a pass to process driver deficiencies between UID caching and use, allowing a full view of the whole pipeline, since some bugs/workarounds involve interactions between blend modes and the pixel shader
I think this is a relic of D3D9. D3D11 and D3D12 seem to work fine without it. Plus, ViewportCorrectionMatrix just didn't work correctly (at least with the viewports being generated by the new scissor code).