Übersicht über Deskriptorheaps

Deskriptor-Heaps enthalten viele Objekttypen, die nicht Teil eines Pipeline State Object (PSO) sind, z. B. Shader-Ressourcenansichten (SRVs), Unordered Access Views (UAVs), Konstantenpufferansichten (CBVs) und Sampler.

Zweck der Deskriptor-Heaps

Der Hauptzweck eines Deskriptor-Heaps besteht darin, den Großteil der Speicherzuweisung zu umfassen, die für das Speichern der Deskriptorspezifikationen von Objekttypen erforderlich sind, auf die Shader auf so große Fenster des Renderings wie möglich verweisen (idealerweise ein vollständiger Frame des Renderings oder mehr). Wenn eine Anwendung wechselt, welche Texturen die Pipeline schnell aus der API sieht, muss im Deskriptor-Heap Platz vorhanden sein, um Deskriptortabellen für jeden erforderlichen Zustandssatz zu definieren. Die Anwendung kann sich entscheiden, Definitionen wiederzuverwenden, wenn die Ressourcen z. B. erneut in einem anderen Objekt verwendet werden oder einfach den Heapraum sequenziell zuweisen, da es verschiedene Objekttypen wechselt.

Deskriptor-Heaps ermöglichen auch einzelnen Softwarekomponenten, deskriptorspeicher getrennt voneinander zu verwalten.

Alle Heaps sind für die CPU sichtbar. Die Anwendung kann auch anfordern, über welche CPU-Zugriffseigenschaften ein Deskriptor-Heap verfügen soll (sofern vorhanden) – kombiniert, zurückschreiben, zurückschreiben usw. Apps können beliebig viele Deskriptor-Heaps mit den gewünschten Eigenschaften erstellen. Apps haben immer die Möglichkeit, Deskriptor-Heaps zu erstellen, die ausschließlich für Stagingzwecke gelten, die nicht in der Größe enthalten sind, und kopieren Sie nach Bedarf in Deskriptor-Heaps, die für das Rendern verwendet werden.

Es gibt einige Einschränkungen in dem, was in demselben Deskriptor-Heap gehen kann. CBV-, UAV- und SRV-Einträge können sich in demselben Deskriptor-Heap befinden. Samplers-Einträge können jedoch keinen Heap für CBV-, UAV- oder SRV-Einträge freigeben. In der Regel gibt es zwei Gruppen von Deskriptor-Heaps, eine für die allgemeinen Ressourcen und die zweite für Sampler.

Die Verwendung von Deskriptor-Heaps von Direct3D 12 spiegelt die meisten GPU-Hardware wider, was entweder erforderlich ist, deskriptoren nur in Deskriptor-Heaps oder einfach, dass weniger Adressierungsbits benötigt werden, wenn diese Heaps verwendet werden. Direct3D 12 erfordert die Verwendung von Deskriptor-Heaps, es gibt keine Möglichkeit, Deskriptoren überall im Arbeitsspeicher zu platzieren.

Deskriptor-Heaps können nur sofort von der CPU bearbeitet werden, es gibt keine Möglichkeit, einen Deskriptor-Heap von der GPU zu bearbeiten.

Synchronization

Deskriptor-Heapinhalte können vor, während und nach der Aufzeichnung von Befehlslisten geändert werden, die darauf verweisen. Deskriptoren können jedoch nicht geändert werden, während eine für die Ausführung übermittelte Befehlsliste auf diesen Speicherort verweist, da dies eine Racebedingung aufrufen kann.

Bindung

Höchstens ein CBV/SRV/UAV kombinierter Heap und ein Sampler-Heap kann jederzeit gebunden werden. Diese Heaps werden sowohl zwischen den Grafik- als auch rechenpipelinen geteilt (beschrieben in ihren PSOs).

Wechseln von Heaps

Es ist akzeptabel, dass eine Anwendung Heaps in derselben Befehlsliste oder in unterschiedlichen anwendungen mit den SetDescriptorHeaps und Reset-APIs wechselt. Bei einigen Hardware kann dies ein teurer Vorgang sein, der eine GPU-Stände erfordert, um alle Arbeiten zu leeren, die von der derzeit gebundenen Deskriptor-Heap abhängen. Wenn Deskriptor-Heaps geändert werden müssen, sollten Anwendungen versuchen, dies zu tun, wenn die GPU-Workload relativ leicht ist, vielleicht die Änderungen am Anfang einer Befehlsliste einschränken.

Bundles

Bei Bündeln kann es nur einen Aufruf der SetDescriptorHeaps-Methode geben, und der Deskriptor-Heapssatz muss genau mit denen der Befehlsliste übereinstimmen, die das Bundle aufruft. Wenn das Bundle keine Deskriptortabellen ändert, muss die Deskriptor-Heaps nicht festgelegt werden.

Eine Liste der API-Aufrufe, die nicht mit Bündeln verwendet werden können, finden Sie unter Erstellen und Aufzeichnen von Befehlslisten und Bündeln.

Verwaltung

Um alle Objekte in einer Szene zu rendern, werden viele Deskriptoren benötigt, und es gibt einige verschiedene Verwaltungsstrategien, die befolgt werden können.

Die einfachste Strategie wäre es, einen neuen Bereich des Deskriptor-Heaps mit allen Anforderungen für den nächsten Draw-Aufruf auszufüllen. Vor dem Ausstellen des Draw-Aufrufs in der Befehlsliste würde also ein Deskriptortabellenzeiger auf den Anfang der frisch ausgefüllten Tabelle festgelegt. Die Upside besteht darin, dass keine Aufzeichnung erforderlich ist, wo sich ein bestimmter Deskriptor im Heap befindet.

Der Nachteil dieser Strategie besteht darin, dass es viele Wiederholungen von Deskriptoren im Deskriptor-Heap geben könnte, insbesondere wenn eine sehr ähnliche Szene gerendert wird, und dass der Deskriptor-Heapraum schnell verwendet wird. Separate Deskriptor-Heaps für diejenigen, die auf der GPU gerendert werden, und für diejenigen, die von der CPU aufgezeichnet werden, wären wahrscheinlich erforderlich, um Konflikte zu vermeiden. Alternativ kann ein Unterzuweisungssystem verwendet werden.

Außerdem könnte das Grundlegende System durch sorgfältige Verwendung überlappender Deskriptortabellen von einem Draw-Aufruf zum nächsten optimiert werden, sodass nur die neuen Deskriptoren hinzugefügt werden, die erforderlich sind.

Eine effizientere Strategie als die grundlegende Strategie wäre das Vorfüllen von Deskriptor-Heaps mit Deskriptoren, die für die Objekte (oder Materialien) erforderlich sind, die als Teil der Szene bekannt sind. Die Idee ist hier, dass es nur erforderlich ist, die Deskriptortabelle zum Zeichnen festzulegen, da der Deskriptor-Heap vor der Zeit aufgefüllt wird.

Eine Variante der Vorfüllstrategie besteht darin, den Deskriptor-Heap als ein riesiges Array zu behandeln, das alle erforderlichen Deskriptoren an festen bekannten Orten enthält. Anschließend muss der Draw-Aufruf nur eine Reihe von Konstanten empfangen, die die Indizes in das Array enthalten, in dem die Deskriptoren verwendet werden müssen.

Eine weitere Optimierung besteht darin, sicherzustellen, dass Stammkonstanten und Stammbeschreibungen diejenigen enthalten, die am häufigsten geändert werden, anstatt Konstanten im Deskriptor-Heap zu platzieren. Für die meisten Hardware ist dies eine effiziente Methode zur Behandlung von Konstanten.

In der Praxis kann ein Grafikmodul eine andere Strategie in verschiedenen Situationen verwenden und Elemente jeder Strategie kombinieren, um den jeweiligen Zeichnungsanforderungen gerecht zu werden.

Deskriptorheaps