Direct3D 11 on 12
D3D11On12 ist ein Mechanismus, mit dem Entwickler D3D11-Schnittstellen und -Objekte verwenden können, um die D3D12-API zu nutzen. D3D11on12 ermöglicht es Komponenten, die mit D3D11 geschrieben wurden (z. B. D2D-Text und Benutzeroberfläche), mit Komponenten zu arbeiten, die für die D3D12-API geschrieben wurden. D3D11on12 ermöglicht auch das inkrementelle Portieren einer Anwendung von D3D11 auf D3D12, indem Teile der App der Einfachheit halber weiterhin D3D11 als Ziel verwenden können, während andere auf D3D12 abzielen, während sie immer ein vollständiges und korrektes Rendering haben. D3D11On12 vereinfacht die Verwendung von Interop-Techniken zum Freigeben von Ressourcen und Synchronisieren der Arbeit zwischen den beiden APIs.
- Initialisieren von D3D11On12
- Verwendungsbeispiel
- Hintergrund
- Bereinigen
- Einschränkungen
- APIs
- Zugehörige Themen
Initialisieren von D3D11On12
Um mit der Verwendung von D3D11On12 zu beginnen, müssen Sie zunächst ein D3D12-Gerät und eine Befehlswarteschlange erstellen. Diese Objekte werden als Eingabe für die Initialisierungsmethode D3D11On12CreateDevice bereitgestellt. Sie können sich diese Methode wie das Erstellen eines D3D11-Geräts mit dem imaginären Treibertyp D3D DRIVER TYPE 11ON12 vorkennen, bei dem der D3D11-Treiber für das Erstellen von Objekten und das Übermitteln von Befehlslisten an die _ _ _ D3D12-API zuständig ist.
Nachdem Sie über ein D3D11-Gerät und einen unmittelbaren Kontext verfügen, können Sie das Gerät für die QueryInterface ID3D11On12Device-Schnittstelle deaktivieren. Dies ist die primäre Schnittstelle, die für die Interop zwischen D3D11 und D3D12 verwendet wird. Damit sowohl der D3D11-Gerätekontext als auch die D3D12-Befehlslisten auf denselben Ressourcen ausgeführt werden, müssen "umschlossene Ressourcen" mithilfe der CreateWrappedResource-API erstellt werden. Diese Methode "fördert" eine D3D12-Ressource, damit sie in D3D11 verständlich ist. Eine umschlossene Ressource beginnt im Zustand "Acquired", einer Eigenschaft, die von den Methoden AcquireWrappedResources und ReleaseWrappedResources bearbeitet wird.
Beispielverwendung
Die typische Verwendung von D3D11On12 wäre die Verwendung von D2D zum Rendern von Text oder Bildern auf einem D3D12-Hintergrundpuffer. Beispielcode finden Sie im Beispiel D3D11On12. Im Folgenden finden Sie eine grobe Übersicht über die schritte, die Sie dazu ausführen müssen:
- Erstellen Sie ein D3D12-Gerät (D3D12CreateDevice) und eine D3D12-Swapkette (CreateSwapChain mit id3D12CommandQueue als Eingabe).
- Erstellen Sie ein D3D11On12-Gerät mit dem D3D12-Gerät und derselben Befehlswarteschlange wie die Eingabe.
- Rufen Sie die Puffer für die Auslagerungskette ab, und erstellen Sie für jede von ihnen umschlossene D3D11-Ressourcen. Der verwendete Eingabezustand sollte die letzte Methode sein, die D3D12 verwendet hat (z. B. RENDER TARGET), und der Ausgabezustand sollte die Art und Weise sein, wie D3D12 ihn nach Abschluss von _ D3D11 verwendet (z. B. PRESENT).
- Initialisieren Sie D2D, und stellen Sie die umschlossenen D3D11-Ressourcen für D2D bereit, um das Rendering vorzubereiten.
Führen Sie dann in jedem Frame die folgenden Schritte aus:
- Rendern Sie mithilfe einer D3D12-Befehlsliste in den aktuellen Puffer der Auslagerungskette, und führen Sie ihn aus.
- Erwerben der umschlossenen Ressource des aktuellen Zurückpuffers (AcquireWrappedResources).
- Geben Sie D2D-Renderingbefehle aus.
- Geben Sie die umschlossene Ressource frei (ReleaseWrappedResources).
- Leeren Sie den unmittelbaren Kontext D3D11.
- Present (IDXGISwapChain1::P resent1).
Hintergrund
D3D11On12 funktioniert systematisch. Jeder D3D11-API-Aufruf durchläuft die typische Laufzeitvalidierung und geht zum Treiber. Auf der Treiberebene zeichnet der spezielle 11on12-Treiber status- und issues-Rendervorgänge in D3D12-Befehlslisten auf. Diese Befehlslisten werden nach Bedarf übermittelt (z. B. wenn für eine Abfrage oder Ressource befehle geleert werden müssen) oder wie von GetData Map Flush angefordert. Das Erstellen eines D3D11-Objekts führt in der Regel dazu, dass das entsprechende D3D12-Objekt erstellt wird. Einige feste Funktionsrenderingvorgänge in D3D11 wie oder werden GenerateMips DrawAuto in D3D12 nicht unterstützt. Daher emuliert D3D11On12 sie mitHilfe von Shadern und zusätzlichen Ressourcen.
Für interop ist es wichtig zu verstehen, wie D3D11On12 mit den D3D12-Objekten interagiert, die die App erstellt und bereitgestellt hat. Um sicherzustellen, dass die Arbeit in der richtigen Reihenfolge erfolgt, muss der direkte D3D11-Kontext geleert werden, bevor zusätzliche D3D12-Arbeit an diese Warteschlange übermittelt werden kann. Es ist auch wichtig sicherzustellen, dass die an D3D11On12 gegebene Warteschlange jederzeit entleerbar sein muss. Das bedeutet, dass alle Warteschleifen in der Warteschlange letztendlich erfüllt werden müssen, auch wenn der D3D11-Renderthread unbegrenzt blockiert wird. Vermeiden Sie es, eine Abhängigkeit von zu übernehmen, wenn D3D11On12 Leerungen einfüge oder wartet, da sich dies bei zukünftigen Releases ändern kann. Darüber hinaus verfolgt und bearbeitet D3D11On12 ressourcenzustände selbst. Die einzige Möglichkeit, die Parallelität von Zustandsübergängen sicherzustellen, besteht in der Verwendung der Acquire/Release-APIs, um die Zustandsnachverfolgung an die Anforderungen der App anzupassen.
Bereinigen
Um eine umschlossene D3D11On12-Ressource frei zu geben, müssen zwei Dinge in dieser Reihenfolge geschehen:
- Alle Verweise auf die Ressource, einschließlich aller Ansichten der Ressource, müssen freigegeben werden.
- Die verzögerte Zerstörungsverarbeitung muss stattfinden. Die einfachste Möglichkeit, dies sicherzustellen, ist das Aufrufen der API für den unmittelbaren
FlushKontext.
Nachdem beide Schritte abgeschlossen sind, sollten alle Von der umschlossenen Ressource übernommenen Verweise freigegeben werden, und die D3D12-Ressource wird ausschließlich im Besitz der D3D12-Komponente. Beachten Sie, dass D3D12 vor der vollständigen Freigabe einer Ressource weiterhin auf die GPU-Vervollständigung warten muss. Achten Sie daher darauf, dass Sie vor den beiden oben genannten Schritten einen Verweis auf die Ressource halten, es sei denn, Sie haben bereits bestätigt, dass die GPU die Ressource nicht mehr verwendet.
Alle anderen Ressourcen oder Objekte, die von D3D11On12 erstellt wurden, werden zum richtigen Zeitpunkt bereinigt, wenn die GPU sie nicht mehr verwendet. Dazu wird der Mechanismus für die verzögerte Zerstörung von D3D11 verwendet. Wenn Sie jedoch versuchen, das Gerät D3D11On12 selbst frei zu geben, während die GPU noch ausgeführt wird, kann die Zerstörung blockiert werden, bis die GPU abgeschlossen ist.
Einschränkungen
Die D3D11On12-Ebene implementiert eine sehr große Teilmenge der D3D11-API, aber es gibt einige bekannte Lücken (zusätzlich zu Fehlern in der Implementierung, die zu falschem Rendering führen können).
Ab Windows 10, Version 1809 (10.0; Build 17763), solange D3D11On12 auf einem Treiber ausgeführt wird, der Shadermodell 6.0 oder höher unterstützt, können Shader ausgeführt werden, die Schnittstellen verwenden. In früheren Versionen von Windows ist das Shaderschnittstellenfeature in D3D11On12 nicht implementiert, und der Versuch, das Feature zu verwenden, verursacht Fehler und Debugmeldungen.
Ab Windows 10 Version 1803 (10.0; Build 17134), werden Austauschketten auf D3D11On12-Geräten unterstützt. In früheren Versionen von Windows nicht.
D3D11On12 wurde nicht für die Leistung optimiert. Im Vergleich zu einem D3D11-Standardtreiber wird wahrscheinlich ein mittlerer CPU-Mehraufwand, ein minimaler GPU-Mehraufwand und ein hoher Arbeitsspeicheraufwand bekannt sein. Daher wird nicht empfohlen, D3D11On12 für komplizierte 3D-Szenen zu verwenden, sondern stattdessen für einfache Szenen oder 2D-Rendering.
APIs
APIs, aus denen die Ebene 11on12 besteht, werden in 11on12 Reference (Referenz zu 11on12) beschrieben.