Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Direct3D 12 stellt einen erheblichen Abbruch vom Direct3D 11-Programmiermodell dar. Mit Direct3D 12 können Apps die Hardware näher als je zuvor erreichen. Durch die Näherung der Hardware ist Direct3D 12 schneller und effizienter. Der Kompromiss Ihrer App mit einer erhöhten Geschwindigkeit und Effizienz mit Direct3D 12 besteht jedoch darin, dass Sie für mehr Aufgaben als bei Direct3D 11 verantwortlich sind.
- explizite Synchronisierung
- Residency Management für physischen Speicher
- Pipelinestatusobjekte
- Befehlslisten und Bundles
- Heaps und Tabellen
- Portierung von Direct3D 11
- Verwandte Themen
Direct3D 12 ist eine Rückkehr zur Low-Level-Programmierung; Es bietet Ihnen mehr Kontrolle über die grafischen Elemente Ihrer Spiele und Apps, indem Sie diese neuen Features einführen: Objekte, die den Gesamtzustand der Pipeline darstellen, Befehlslisten und Bündel für die Arbeitsübermittlung sowie Deskriptor heaps und Tabellen für den Ressourcenzugriff.
Ihre App hat die Geschwindigkeit und Effizienz mit Direct3D 12 erhöht, aber Sie sind für mehr Aufgaben verantwortlich als bei Direct3D 11.
Explizite Synchronisierung
- In Direct3D 12 ist CPU-GPU Synchronisierung jetzt die explizite Verantwortung der App und wird nicht mehr implizit von der Laufzeit ausgeführt, wie es in Direct3D 11 ist. Dies bedeutet auch, dass keine automatische Überprüfung auf Pipelinegefahren durch Direct3D 12 durchgeführt wird, so dass dies wiederum die Verantwortung der Apps ist.
- In Direct3D 12 sind Apps für das Pipelining von Datenaktualisierungen verantwortlich. Das heißt, das Muster "Map/Lock-DISCARD" in Direct3D 11 muss in Direct3D 12 manuell ausgeführt werden. Wenn die GPU in Direct3D 11 den Puffer weiterhin verwendet, wenn Sie ID3D11DeviceContext::Map mit D3D11_MAP_WRITE_DISCARDaufrufen, gibt die Laufzeit einen Zeiger auf einen neuen Speicherbereich anstelle der alten Pufferdaten zurück. Dadurch kann die GPU die alten Daten weiterhin verwenden, während die App Daten im neuen Puffer platziert. In der App ist keine zusätzliche Speicherverwaltung erforderlich; Der alte Puffer wird automatisch wiederverwendet oder zerstört, wenn die GPU damit fertig ist.
- In Direct3D 12 werden alle dynamischen Updates (einschließlich Konstantenpuffer, dynamische Vertexpuffer, dynamische Texturen usw.) explizit von der App gesteuert. Diese dynamischen Updates umfassen alle erforderlichen GPU-Zäune oder Puffer. Die App ist dafür verantwortlich, den Speicher verfügbar zu halten, bis sie nicht mehr benötigt wird.
- Direct3D 12 verwendet nur für die Lebensdauer von Schnittstellen eine COM-Bezugszählung (mithilfe des schwachen Referenzmodells von Direct3D, das an die Lebensdauer des Geräts gebunden ist). Alle Ressourcen- und Beschreibungsspeicherlebensdauern sind die alleinige verantwortungsbewusste Verwaltung der App für die richtige Dauer und werden nicht gezählt. Direct3D 11 verwendet Referenzzählungen, um auch die Lebensdauer von Schnittstellenabhängigkeiten zu verwalten.
Residency Management für physischen Speicher
Eine Direct3D 12-Anwendung muss Racebedingungen zwischen mehreren Warteschlangen, mehreren Adaptern und den CPU-Threads verhindern. D3D12 synchronisiert die CPU und GPU nicht mehr und unterstützt keine praktischen Mechanismen für die Ressourcenumbenennung oder multipufferung. Zäune müssen verwendet werden, um zu vermeiden, dass mehrere Verarbeitungseinheiten überschreiben, bevor eine andere Verarbeitungseinheit sie verwendet.
Die Direct3D 12-Anwendung muss sicherstellen, dass Daten im Arbeitsspeicher gespeichert sind, während die GPU sie liest. Der von den einzelnen Objekten verwendete Speicher wird während der Erstellung des Objekts resident. Anwendungen, die diese Methoden aufrufen, müssen Zäune verwenden, um sicherzustellen, dass die GPU nicht auf Objekte zugreift, die entfernt wurden.
Ressourcenbarrieren sind eine weitere Art von Synchronisierung erforderlich, die zum Synchronisieren von Ressourcen- und Unterressourcenübergängen auf einer sehr granularen Ebene verwendet wird.
Weitere Informationen finden Sie unter Speicherverwaltung in Direct3D 12.
Pipelinestatusobjekte
Direct3D 11 ermöglicht die Manipulation des Pipelinezustands über einen großen Satz unabhängiger Objekte. Beispielsweise kann der Eingabeassemblerzustand, der Pixelshaderzustand, der Rasterizerzustand und der Ausgabezusammenführungszustand unabhängig geändert werden. Dieses Design bietet eine bequeme und relativ hohe Darstellung der Grafikpipeline, verwendet aber nicht die Funktionen moderner Hardware, hauptsächlich weil die verschiedenen Zustände häufig voneinander abhängig sind. Viele GPUs kombinieren beispielsweise den Pixelshader und den Ausgabezusammenführungszustand in einer einzigen Hardwaredarstellung. Da die Direct3D 11-API diese Pipelinephasen jedoch separat festlegen kann, kann der Anzeigetreiber erst dann Probleme mit dem Pipelinestatus beheben, wenn der Zustand abgeschlossen ist, was erst nach dem Zeichnen der Zeit liegt. Dieses Schema verzögert die Hardwarezustandseinrichtung, was zusätzlichen Aufwand und weniger maximale Draw-Aufrufe pro Frame bedeutet.
Direct3D 12 behebt dieses Schema, indem ein Großteil des Pipelinezustands in unveränderliche Pipelinezustandsobjekte (PSOs) vereinheitlicht wird, die bei der Erstellung abgeschlossen werden. Hardware und Treiber können dann sofort das PSO in alle systemeigenen Hardwareanweisungen und -zustand konvertieren, um GPU-Arbeit auszuführen. Sie können weiterhin dynamisch ändern, welche PSO verwendet wird, aber dazu muss die Hardware nur die minimale Menge des vorab berechneten Zustands direkt in die Hardwareregister kopieren, anstatt den Hardwarezustand dynamisch zu berechnen. Durch die Verwendung von PSOs wird der Draw Call Overhead erheblich reduziert, und viele weitere Draw-Aufrufe können pro Frame auftreten. Weitere Informationen zu PSOs finden Sie unter Verwalten des Grafikpipelinezustands in Direct3D 12.
Befehlslisten und Bündel
In Direct3D 11 erfolgt die gesamte Arbeitsübermittlung über den unmittelbaren Kontext, der einen einzelnen Datenstrom von Befehlen darstellt, die zur GPU wechseln. Um die Multithreadskalierung zu erreichen, verfügen Spiele auch über verzögerten Kontext, ihnen zur Verfügung stehen. Verzögerte Kontexte in Direct3D 11 entsprechen nicht perfekt der Hardware, sodass relativ wenig Arbeit in ihnen ausgeführt werden kann.
Direct3D 12 führt ein neues Modell für die Arbeitsübermittlung basierend auf Befehlslisten ein, die die gesamte Anzahl von Informationen enthalten, die zum Ausführen einer bestimmten Workload auf der GPU erforderlich sind. Jede neue Befehlsliste enthält Informationen, z. B. welche PSO verwendet werden soll, welche Textur- und Pufferressourcen benötigt werden, und die Argumente für alle Draw-Aufrufe. Da jede Befehlsliste eigenständig ist und keinen Zustand erbt, kann der Treiber alle erforderlichen GPU-Befehle vorab und freithreads berechnen. Der einzige serielle Prozess ist die endgültige Übermittlung von Befehlslisten an die GPU über die Befehlswarteschlange.
Zusätzlich zu Befehlslisten führt Direct3D 12 auch eine zweite Arbeitsvorberechnungsebene ein: Bundles. Im Gegensatz zu Befehlslisten, die vollständig eigenständig sind und in der Regel erstellt, einmal übermittelt und verworfen werden, stellen Bundles eine Form der Zustandsvererbung bereit, die die Wiederverwendung zulässt. Wenn ein Spiel beispielsweise zwei Zeichenmodelle mit unterschiedlichen Texturen zeichnen möchte, besteht ein Ansatz darin, eine Befehlsliste mit zwei Sätzen identischer Draw-Aufrufe aufzuzeichnen. Ein anderer Ansatz besteht jedoch darin, ein Bündel aufzuzeichnen, das ein einzelnes Zeichenmodell zeichnet und dann das Bundle zweimal in der Befehlsliste mit unterschiedlichen Ressourcen "wiedergeben". Im letzteren Fall muss der Anzeigetreiber nur einmal die entsprechenden Anweisungen berechnen, und das Erstellen der Befehlsliste beläuft sich im Wesentlichen auf zwei kostengünstige Funktionsaufrufe.
Weitere Informationen zu Befehlslisten und Bündeln finden Sie unter Arbeitsübermittlung in Direct3D 12.
Deskriptor-Heaps und -Tabellen
Die Ressourcenbindung in Direct3D 11 ist sehr abstrahiert und bequem, lässt aber viele moderne Hardwarefunktionen unterlastet. In Direct3D 11 erstellen Spiele Ansicht Objekte von Ressourcen und binden diese Ansichten dann an mehrere Slots in verschiedenen Shaderphasen in der Pipeline. Shader lesen wiederum Daten aus diesen expliziten Bindungsplätzen, die zur Zeichenzeit behoben sind. Dieses Modell bedeutet, dass jedes Mal, wenn ein Spiel mit unterschiedlichen Ressourcen gezeichnet wird, unterschiedliche Ansichten an verschiedene Slots neu binden und erneut zeichnen muss. Dieser Fall stellt auch den Aufwand dar, der durch die vollständige Nutzung moderner Hardwarefunktionen beseitigt werden kann.
Direct3D 12 ändert das Bindungsmodell so, dass es mit moderner Hardware übereinstimmt und die Leistung erheblich verbessert. Anstatt eigenständige Ressourcenansichten und explizite Zuordnung zu Slots zu erfordern, stellt Direct3D 12 einen Deskriptor-Heap bereit, in den Spiele ihre verschiedenen Ressourcenansichten erstellen. Dieses Schema bietet einen Mechanismus für die GPU, um die Hardware-native Ressourcenbeschreibung (Deskriptor) direkt in den Arbeitsspeicher im Vorfeld zu schreiben. Um zu deklarieren, welche Ressourcen von der Pipeline für einen bestimmten Draw-Aufruf verwendet werden sollen, geben Spiele eine oder mehrere Deskriptortabellen an, die Unterbereiche des vollständigen Deskriptors heap darstellen. Da der Deskriptor-Heap bereits mit den entsprechenden hardwarespezifischen Deskriptordaten aufgefüllt wurde, ist das Ändern von Deskriptortabellen ein äußerst kostengünstiger Vorgang.
Neben der verbesserten Leistung von Deskriptor-Heaps und -Tabellen ermöglicht Direct3D 12 auch die dynamische Indizierung von Ressourcen in Shadern, die beispiellose Flexibilität bietet und neue Renderingtechniken entsperrt. Als Beispiel codieren moderne verzögerte Renderingmodule in der Regel einen Material- oder Objektbezeichner einer Art für den Zwischenpuffer g-Puffer. In Direct3D 11 müssen diese Engines vorsichtig sein, um zu viele Materialien zu vermeiden, da die Aufnahme von zu vielen in einem G-Puffer den endgültigen Renderdurchlauf erheblich verlangsamen kann. Mit dynamisch indizierbaren Ressourcen kann eine Szene mit tausend Materialien genauso schnell wie eine mit nur zehn Fertig stellen.
Weitere Informationen zu Deskriptor heaps und Tabellen finden Sie unter Resource Bindingund Unterschiede im Bindungsmodell von Direct3D 11.
Portieren von Direct3D 11
Das Portieren von Direct3D 11 ist ein beteiligter Prozess, der in Portierung von Direct3D 11 zu Direct3D 12beschrieben wird. Weitere Informationen finden Sie in Arbeiten mit Direct3D 11, Direct3D 10 und Direct2D.
Verwandte Themen