Ausführen und Synchronisieren von Befehlslisten

In Microsoft Direct3D 12 ist der sofortige Modus früherer Versionen nicht mehr vorhanden. Stattdessen erstellen Apps Befehlslisten und -bundles und zeichnen dann Sätze von GPU-Befehlen auf. Befehlswarteschlangen werden verwendet, um auszuführende Befehlslisten zu übermitteln. Mit diesem Modell haben Entwickler mehr Kontrolle über die effiziente Nutzung der Grafikverarbeitungseinheit (GRAPHICS Processing Unit, GPU) und der CPU.

Übersicht über Befehlswarteschlangen

Direct3D 12-Befehlswarteschlangen ersetzen die Laufzeit- und Treibersynchronisierung der Arbeitsübermittlung im unmittelbaren Modus, die zuvor nicht für den Entwickler verfügbar gemacht wurde, durch APIs zum expliziten Verwalten von Parallelität, Parallelität und Synchronisierung. Befehlswarteschlangen bieten die folgenden Verbesserungen für Entwickler:

  • Ermöglicht Es Entwicklern, versehentliche Ineffizienzen zu vermeiden, die durch unerwartete Synchronisierung verursacht werden.
  • Ermöglicht Es Entwicklern, die Synchronisierung auf einer höheren Ebene einzuführen, auf der die erforderliche Synchronisierung effizienter und genauer bestimmt werden kann. Dies bedeutet, dass die Laufzeit und der Grafiktreiber weniger Zeit damit verbringen, parallele Parallelität reaktiv zu entwickeln.
  • Macht teure Vorgänge expliziter.

Diese Verbesserungen ermöglichen oder verbessern die folgenden Szenarien:

  • Erhöhte Parallelität: Anwendungen können tiefere Warteschlangen für Hintergrundworkloads wie die Videodecodierung verwenden, wenn sie über separate Warteschlangen für Vordergrundarbeit verfügen.
  • Asynchrone und GPU-Arbeit mit niedriger Priorität: Das Befehlswarteschlangenmodell ermöglicht die gleichzeitige Ausführung von GPU-Arbeits- und Atomvorgängen mit niedriger Priorität, die es einem GPU-Thread ermöglichen, die Ergebnisse eines anderen nicht synchronisierten Threads ohne Blockierung zu nutzen.
  • Computearbeit mit hoher Priorität: Dieser Entwurf ermöglicht Szenarien, die eine Unterbrechung des 3D-Renderings erfordern, eine kleine Menge an Computearbeit mit hoher Priorität, sodass das Ergebnis frühzeitig für eine zusätzliche Verarbeitung der CPU abgerufen werden kann.

Initialisieren einer Befehlswarteschlange

Befehlswarteschlangen können durch Aufrufen von ID3D12Device::CreateCommandQueue erstellt werden. Diese Methode nimmt eine D3D12_COMMAND_LIST_TYPE an, die angibt, welche Art von Warteschlange erstellt werden soll und daher welche Art von Befehlen an diese Warteschlange übermittelt werden kann. Denken Sie daran, dass Bundles nur aus direkten Befehlslisten aufgerufen und nicht direkt an eine Warteschlange übermittelt werden können. Die folgenden Warteschlangentypen werden unterstützt:

Im Allgemeinen akzeptieren DIRECT-Warteschlangen und Befehlslisten alle Befehle, COMPUTE-Warteschlangen und Befehlslisten akzeptieren Compute- und Kopierbefehle, und COPY-Warteschlangen und Befehlslisten akzeptieren nur Kopierbefehle.

Ausführen von Befehlslisten

Nachdem Sie eine Befehlsliste aufgezeichnet und entweder die Standardbefehlswarteschlange abgerufen oder eine neue erstellt haben, führen Sie Befehlslisten aus, indem Sie ID3D12CommandQueue::ExecuteCommandLists aufrufen.

Anwendungen können Befehlslisten aus mehreren Threads an eine beliebige Befehlswarteschlange übermitteln. Die Runtime führt die Serialisierung dieser Anforderungen in der Reihenfolge der Übermittlung durch.

Die Runtime überprüft die Liste der übermittelten Befehle und legt den Aufruf von ExecuteCommandLists ab, wenn eine der Einschränkungen verletzt wird. Anrufe werden aus folgenden Gründen gelöscht:

Zugreifen auf Ressourcen über mehrere Befehlswarteschlangen

Es gibt eine Reihe von Regeln, die von der Runtime auferlegt werden, die den Zugriff auf Ressourcen aus mehreren Befehlswarteschlangen einschränken. Nachfolgend sind diese Regeln aufgeführt:

  1. Eine Ressource kann nicht aus mehreren Befehlswarteschlangen gleichzeitig in eine Ressource geschrieben werden. Wenn eine Ressource in eine Warteschlange in einen schreibbaren Zustand übergeht, wird sie als ausschließlich im Besitz dieser Warteschlange betrachtet und muss in einen Lese- oder COMMON-Zustand (siehe D3D12_RESOURCE_STATES) wechseln, bevor eine andere Warteschlange darauf zugreifen kann.

  2. Im Lesezustand kann eine Ressource basierend auf ihrem Lesezustand gleichzeitig aus mehreren Befehlswarteschlangen gelesen werden, auch prozessübergreifend.

Weitere Informationen zu Ressourcenzugriffseinschränkungen und zur Verwendung von Ressourcenbarrieren zum Synchronisieren des Zugriffs auf Ressourcen finden Sie unter Verwenden von Ressourcenbarrieren zum Synchronisieren von Ressourcenzuständen.

Synchronisieren der Befehlslistenausführung mithilfe von Befehlswarteschlangenzaunen

Die Unterstützung mehrerer paralleler Befehlswarteschlangen in Direct3D 12 bietet Ihnen mehr Flexibilität und Kontrolle über die Priorisierung asynchroner Arbeit auf der GPU. Dieser Entwurf bedeutet auch, dass Apps die Synchronisierung der Arbeit explizit verwalten müssen, insbesondere wenn die Befehlslisten in einer Warteschlange von Ressourcen abhängen, die von einer anderen Befehlswarteschlange betrieben werden. Einige Beispiele hierfür sind das Warten auf den Abschluss eines Vorgangs in einer Computewarteschlange, sodass das Ergebnis für einen Renderingvorgang in der 3D-Warteschlange verwendet werden kann, und das Warten auf den Abschluss eines 3D-Vorgangs, damit ein Vorgang in der Computewarteschlange auf eine Ressource zum Schreiben zugreifen kann. Um die Synchronisierung von Arbeit zwischen Warteschlangen zu ermöglichen, verwendet Direct3D 12 das Konzept der Zäune, die in der API durch die ID3D12Fence-Schnittstelle dargestellt werden.

Ein Zaun ist eine ganze Zahl, die die aktuelle Arbeitseinheit darstellt, die verarbeitet wird. Wenn die App den Zaun vorantreibt, wird die ganze Zahl durch Aufrufen von ID3D12CommandQueue::Signal aktualisiert. Apps können den Wert eines Zauns überprüfen und ermitteln, ob eine Arbeitseinheit abgeschlossen wurde, um zu entscheiden, ob ein nachfolgender Vorgang gestartet werden kann.

Synchronisieren von Ressourcen, auf die von Befehlswarteschlangen zugegriffen wird

In Direct3D 12 wird die Synchronisierung des Zustands einiger Ressourcen mit Ressourcenbarrieren implementiert. An jeder Ressourcenbarriere deklariert eine App den Vorher- und Nachher-Status einer Ressource. Ein gängiges Beispiel ist der Übergang einer Ressource zwischen einer Shaderressourcenansicht und einer Renderzielansicht. In den meisten Fällen werden diese Ressourcenbarrieren in Befehlslisten verwaltet. Wenn die Debugebenen aktiviert sind, erzwingt das System, dass die Vorher- und Nachher-Zustände aller Ressourcen übereinstimmen, wodurch sichergestellt wird, dass sich die Ressource bei einem Barrierenübergang im richtigen Zustand für einen bestimmten Vorgang befindet.

Weitere Informationen zum Synchronisieren des Ressourcenstatus finden Sie unter Verwenden von Ressourcenbarrieren zum Synchronisieren von Ressourcenzuständen.

Unterstützung von Befehlswarteschlangen für gruppierte Ressourcen

Methoden zum Verwalten von kachelfähigen Ressourcen, die über die ID3D11DeviceContext2-Schnittstelle in Direct3D 11 verfügbar gemacht wurden, werden von der ID3D12CommandQueue-Schnittstelle in Direct3D 12 bereitgestellt. Diese Methoden umfassen:

Methode BESCHREIBUNG
CopyTileMappings Kopiert Zuordnungen aus einer gekachelten Quellressource in eine zielkachelte Ressource.
UpdateTileMappings Updates Zuordnungen von Kachelspeicherorten in kachelten Ressourcen zu Speicherspeicherorten in einem Ressourcenheap.

Weitere Informationen zur Verwendung von gekachelten Ressourcen in Direct3D 12-Apps finden Sie unter Direct3D11 Tiled Resources.

Arbeitsübermittlung in Direct3D 12