Vulkan-HDR auf virtuellen Displays reparieren: ein Vulkan-Layer, der macht, was der GPU-Treiber verweigert
NVIDIA-/AMD-Vulkan-Treiber verstecken HDR auf indirekten (virtuellen) Displays, also verweigern Vulkan-Spiele beim Streaming HDR. Wir haben bewiesen, dass der Treiber eine erzwungene HDR-Swapchain trotzdem darstellt — und einen winzigen Vulkan-Layer gebaut, der die fehlenden Formate einschleust. Die ganze Technikgeschichte.
Doom: The Dark Ages, Indiana Jones and the Great Circle und andere Vulkan-Spiele verweigern HDR, wenn du sie über ein virtuelles Display streamst — die Art von Display, die jeder Streaming-Host erzeugt. Die Streaming-Community (Sunshine, Apollo, das Virtual-Display-Driver-Projekt) hatte das als unlösbar abgehakt, „irgendwas im Windows-Kernel.“ Ist es nicht. So haben wir es gelöst.
Zwei verschiedene HDR-Fragen
Ob Windows ein Display für HDR-fähig hält und ob ein Vulkan-Spiel das tut, beantworten zwei verschiedene Teile des Stacks. Der Windows-Schalter „HDR verwenden“ und der Desktop-Compositor lesen HDR aus den Display-Metadaten und dem OS — und ein indirektes (IddCx-)virtuelles Display meldet das korrekt. Deshalb funktioniert der Schalter, ist der Desktop 10 Bit und sind DirectX-12-Spiele meist in Ordnung. Vulkan-Spiele fragen stattdessen den Vulkan-Treiber der GPU, indem sie die Swapchain-Formate aufzählen und nach VK_COLOR_SPACE_HDR10_ST2084_EXT suchen. Auf einem virtuellen Display gibt der NVIDIA-/AMD-Vulkan-Treiber diesen Farbraum nicht zurück — also sieht das Spiel „kein HDR.“
Das entscheidende Experiment
Bevor wir eine Zeile Code schrieben, prüften wir die naheliegende Frage: Ist die HDR-Pipeline auf einem virtuellen Display wirklich kaputt — oder nur die Anzeige der Fähigkeit? Mit einem kleinen Vulkan-Probe erzwangen wir eine HDR-Swapchain (HDR10_ST2084, 10 Bit) auf dem virtuellen Display — ein Format, das der Treiber nie auflistete —, setzten HDR-Metadaten und stellten Frames dar. Alles funktionierte. Der Treiber stellt dort HDR einwandfrei dar; er weigert sich nur, das Format in die Liste zu schreiben, die ein Spiel ausliest. Der ganze Fix besteht also darin, den fehlenden Eintrag wieder hinzuzufügen.
Eine winzige Idee, verpackt in einen Vulkan-Layer
Vulkan hat genau dafür einen sauberen Erweiterungspunkt: einen impliziten Layer zwischen Spiel und Treiber. Unser Layer fängt die beiden Surface-Format-Abfragen ab (vkGetPhysicalDeviceSurfaceFormatsKHR und die 2KHR-Variante), ruft den Treiber auf und hängt die HDR-Formate — HDR10/ST2084 und scRGB — an die Liste an. Das Spiel fordert dann eine HDR-Swapchain an, und (wie das Experiment zeigte) der Treiber gewährt sie. Keine Spiel-Patches, keine Anpassung pro Titel.
Zwei Details machen es produktionssicher:
- Selbst-Gating. Der Layer schleust nur ein, wenn das Zieldisplay gerade *tatsächlich* HDR aktiviert hat — er prüft den Windows-Advanced-Color-Zustand des Monitors der Surface. In einer SDR-Sitzung oder auf einem echten Monitor, der HDR ohnehin bewirbt, tut er nichts und kann ein SDR-Spiel nicht ausblassen.
- Immer aktiv, aber inert. Er ist global registriert, damit er funktioniert, egal wie ein Spiel gestartet wird (env-basiertes Scoping scheitert stillschweigend bei Spielen, die ein bereits laufendes Steam startet). Wegen des Selbst-Gatings ist er überall ein No-op außer in einer HDR-Sitzung am virtuellen Display — mit Aus-Schalter und einer Anti-Cheat-Ausschlussliste.
Eine Stolperfalle für Nachbauer
Falls du es selbst baust: Die privaten Create-Info-Structs des Vulkan-Loaders (VK_STRUCTURE_TYPE_LOADER_INSTANCE/DEVICE_CREATE_INFO) nutzen die Enum-Werte 47 und 48, nicht den dokumentierten 1000211xxx-Bereich — machst du das falsch, scheitert vkCreateInstance in deinem Layer. Der Rest ist normales Layer-Dispatch-Chaining.
Das Ergebnis
Doom: The Dark Ages aktiviert jetzt HDR über das virtuelle Display, durchgängig, ganz ohne Arbeit pro Spiel — und punktfunk liefert den Layer in seinem Windows-Host mit. Wenn du nur willst, dass es funktioniert, siehe die Kurzfassung; zum Diagnostizieren deines Setups siehe DirectX vs. Vulkan-HDR auf einem virtuellen Display.