Direct3D 11 auf 12
D3D11On12 ist ein Mechanismus, mit dem Entwickler D3D11-Schnittstellen und -Objekte verwenden können, um die D3D12-API zu steuern. D3D11on12 ermöglicht komponenten, die mit D3D11 (z. B. D2D-Text und UI) geschrieben wurden, mit Komponenten zu arbeiten, die für die D3D12-API geschrieben wurden. D3D11on12 ermöglicht auch die inkrementelle Portierung einer Anwendung von D3D11 zu D3D12, indem Teile der App die Zielbestimmung von D3D11 weiterhin zur Vereinfachung ermöglichen, während andere auf D3D12 für die Leistung abzielen, während immer vollständiges und korrektes Rendering ausgeführt wird. D3D11On12 macht es einfacher als die Verwendung von Interop-Techniken zum Freigeben von Ressourcen und zum Synchronisieren der Arbeit zwischen den beiden APIs.
- Initialisierung von D3D11On12
- Beispielverwendung
- Hintergrund-
- Bereinigen von
- Einschränkungen
- -APIs
- Verwandte Themen
Initialisieren von D3D11On12
Um mit der Verwendung von D3D11On12 zu beginnen, besteht der erste Schritt darin, ein D3D12-Gerät und eine Befehlswarteschlange zu erstellen. Diese Objekte werden als Eingabe für die Initialisierungsmethode D3D11On12CreateDevicebereitgestellt. Sie können sich diese Methode als Erstellung eines D3D11-Geräts mit dem imaginären Treibertyp D3D_DRIVER_TYPE_11ON12 vorstellen, bei dem der D3D11-Treiber für das Erstellen von Objekten und das Übermitteln von Befehlslisten an die D3D12-API verantwortlich ist.
Nachdem Sie über ein D3D11-Gerät und sofortigen Kontext verfügen, können Sie das Gerät für die ID3D11On12Device--Schnittstelle QueryInterface
. Dies ist die primäre Schnittstelle, die für die Interoperabilität zwischen D3D11 und D3D12 verwendet wird. Damit sowohl der D3D11-Gerätekontext als auch die D3D12-Befehlslisten auf die gleichen Ressourcen angewendet werden, ist es erforderlich, mithilfe der CreateWrappedResource-API "umschlossene Ressourcen" zu erstellen. Diese Methode fördert eine D3D12-Ressource, die in D3D11 verständlich ist. Eine umschlossene Ressource beginnt im Zustand "erworben", einer Eigenschaft, die von den AcquireWrappedResources und ReleaseWrappedResources Methoden bearbeitet wird.
Beispielverwendung
Die typische Verwendung von D3D11On12 wäre die Verwendung von D2D zum Rendern von Text oder Bildern über einem D3D12-Hintergrundpuffer. Beispielcode finden Sie im D3D11On12-Beispiel. Hier ist eine grobe Übersicht über die Schritte, die sie ausführen müssen:
- Erstellen Sie ein D3D12-Gerät (D3D12CreateDevice) und eine D3D12-Swapchain (CreateSwapChain- mit einer ID3D12CommandQueue als Eingabe).
- Erstellen Sie ein D3D11On12-Gerät mit dem D3D12-Gerät und derselben Befehlswarteschlange wie Eingaben.
- Rufen Sie die Swapchain-Hintergrundpuffer ab, und erstellen Sie umschlossene D3D11-Ressourcen für jede dieser Puffer. Der verwendete Eingabezustand sollte der letzte Weg sein, wie D3D12 es verwendet (z. B. RENDER_TARGET), und der Ausgabezustand sollte die Art und Weise sein, wie D3D12 es verwendet, nachdem D3D11 abgeschlossen ist (z. B. PRESENT).
- Initialisieren Sie D2D, und stellen Sie die umschlossenen D3D11-Ressourcen für die Vorbereitung auf das Rendering bereit.
Führen Sie dann für jeden Frame die folgenden Schritte aus:
- Rendern Sie mithilfe einer D3D12-Befehlsliste in den aktuellen Swapchain-Hintergrundpuffer, und führen Sie ihn aus.
- Abrufen der umschlossenen Ressource des aktuellen Hintergrundpuffers (AcquireWrappedResources).
- Ausgeben von D2D-Renderingbefehlen.
- Release the wrapped resource (ReleaseWrappedResources).
- Leeren Sie den direkten D3D11-Kontext.
- Present (IDXGISwapChain1::P resent1).
Hintergrund
D3D11On12 funktioniert systematisch. Jeder D3D11-API-Aufruf durchläuft die typische Laufzeitüberprüfung und macht den Weg zum Treiber. Auf der Treiberebene zeichnet der spezielle 11on12-Treiber Zustand auf und gibt Rendervorgänge in D3D12-Befehlslisten aus. Diese Befehlslisten werden nach Bedarf übermittelt (z. B. eine Abfrage GetData
oder RessourcenMap
möglicherweise Befehle geleert werden müssen) oder wie von Flush angefordert. Das Erstellen eines D3D11-Objekts führt in der Regel dazu, dass das entsprechende D3D12-Objekt erstellt wird. Einige feste Funktionsrenderungsvorgänge in D3D11, z. B. GenerateMips
oder DrawAuto
, werden in D3D12 nicht unterstützt, sodass D3D11On12 sie mithilfe von Shadern und zusätzlichen Ressourcen emuliert.
Für die Interoperabilität 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 Warteschlange, die an D3D11On12 übergeben wird, jederzeit entwässerbar sein muss. Dies bedeutet, dass alle Wartezeiten in der Warteschlange letztendlich erfüllt sein müssen, auch wenn der D3D11-Renderthread auf unbestimmte Zeit blockiert wird. Seien Sie vorsichtig, keine Abhängigkeit davon zu nehmen, wann D3D11On12 Spülungen einfügt oder wartet, da sich dies bei zukünftigen Versionen ändern kann. Darüber hinaus verfolgt und bearbeitet D3D11On12 ressourcenzustände eigenständig. Die einzige Möglichkeit, die Kohärenz von Zustandsübergängen sicherzustellen, besteht darin, die Abruf-/Freigabe-APIs zu verwenden, um die Statusverfolgung so zu bearbeiten, dass sie den Anforderungen der App entspricht.
Aufputzend
Um eine umschlossene D3D11On12-Ressource freizugeben, müssen in dieser Reihenfolge zwei Dinge geschehen:
- Alle Verweise auf die Ressource, einschließlich aller Ansichten der Ressource, müssen freigegeben werden.
- Die verzögerte Vernichtungsverarbeitung muss erfolgen. Die einfachste Möglichkeit, um sicherzustellen, dass dies geschieht, besteht darin, den unmittelbaren Kontext
Flush
-API aufzurufen.
Nachdem beide Schritte abgeschlossen wurden, sollten alle Verweise, die von der umschlossenen Ressource ausgeführt werden, freigegeben werden, und die D3D12-Ressource gehört ausschließlich der D3D12-Komponente. Beachten Sie, dass D3D12 noch vor dem vollständigen Freigeben einer Ressource auf den GPU-Abschluss wartet. Achten Sie daher darauf, einen Verweis auf die Ressource zu halten, bevor Sie die beiden vorstehenden Schritte ausführen, 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 zu dem entsprechenden Zeitpunkt bereinigt, wenn die GPU sie mit dem verzögerten Zerstörungsmechanismus von D3D11 abgeschlossen hat. Wenn Sie jedoch versuchen, das D3D11On12-Gerät selbst freizugeben, während die GPU noch ausgeführt wird, kann die Zerstörung bis zum Abschluss der GPU blockiert werden.
Begrenzungen
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 falsches Rendering verursachen 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, kann es Shader ausführen, die Schnittstellen verwenden. In früheren Versionen von Windows wird das Feature "Shaderschnittstellen" nicht in D3D11On12 implementiert, und der Versuch, das Feature zu verwenden, verursacht Fehler und Debugmeldungen.
Ab Windows 10, Version 1803 (10.0; Build 17134), Swapchains werden auf D3D11On12-Geräten unterstützt. In früheren Versionen von Windows sind sie nicht.
D3D11On12 wurde nicht für die Leistung optimiert. Es wird wahrscheinlich einen moderaten CPU-Overhead im Vergleich zu einem standardmäßigen D3D11-Treiber, minimalem GPU-Overhead geben, und es ist bekannt, dass ein erheblicher Arbeitsspeicheraufwand besteht. Daher wird nicht empfohlen, D3D11On12 für komplizierte 3D-Szenen zu verwenden, und es wird stattdessen für einfache Szenen oder 2D-Rendering empfohlen.
Apis
APIs, aus denen die Ebene 11on12 besteht, werden in 11on12 Referencebeschrieben.
Verwandte Themen