Stammsignatur, Version 1.1
Der Zweck von Root Signature Version 1.1 besteht darin, Anwendungen das Angeben von Treibern zu ermöglichen, wenn sich Deskriptoren in einem Deskriptorheap nicht ändern oder sich die Datendeskriptoren auf nicht ändern. Dadurch können Treiber Optimierungen vornehmen, die möglicherweise möglich sind, wenn sie wissen, dass ein Deskriptor oder der Arbeitsspeicher, auf den er verweist, für einen bestimmten Zeitraum statisch ist.
- Übersicht
- Statische und flüchtige Flags
- API-Zusammenfassung der Version 1.1
- Folgen eines Verstoßs gegen Statische-Ness-Flags
- Versionsverwaltung
- Zugehörige Themen
Übersicht
Die Stammsignaturversion 1.0 ermöglicht es, dass der Inhalt von Deskriptorheaps und der Arbeitsspeicher, auf den sie zeigen, von Anwendungen jederzeit frei geändert werden können, wenn Befehlslisten/Bundles, die auf sie verweisen, möglicherweise auf der GPU im Einsatz sind. Sehr oft benötigen Anwendungen jedoch nicht die Flexibilität, Deskriptoren oder Arbeitsspeicher zu ändern, nachdem Befehle aufgezeichnet wurden, die auf sie verweisen.
Anwendungen sind häufig trivial in der Lage,
- Richten Sie Deskriptoren (und möglichen Arbeitsspeicher, auf den sie zeigen) ein, bevor Sie Deskriptortabellen oder Stammdeskriptoren in einer Befehlsliste oder einem Bündel binden.
- Stellen Sie sicher, dass sich diese Deskriptoren erst ändern, nachdem die Ausführung der Befehlsliste /bundles, die auf sie verweisen, zum letzten Mal abgeschlossen wurde.
- Stellen Sie sicher, dass sich die Daten, auf die die Deskriptoren zeigen, während derselben vollständigen Dauer nicht ändern.
Alternativ kann eine Anwendung nur in der Lage sein, diese Daten für einen kürzeren Zeitraum zu beachten. Insbesondere daten können während der Ausführung der Befehlsliste für das Zeitfenster statisch sein, das eine Stammparameterbindung (Deskriptortabelle oder Stammdeskriptor) derzeit auf die Daten verweist. Anders ausgedrückt: Eine Anwendung möchte möglicherweise die Ausführung auf der GPU-Zeitachse durchführen, die einige Daten zwischen Zeiträumen aktualisiert, in denen sie über einen Stammparameter festgelegt wird, wobei sie weiß, dass sie statisch ist, wenn sie festgelegt ist.
Wenn sich Deskriptoren oder die Datendeskriptoren, auf die verweisen, nicht ändern, sind die spezifischen Optimierungstreiber möglicherweise hardwareanbieterspezifisch, und wichtig ist, dass sie das Verhalten nur ändern, um die Leistung zu verbessern. Wenn Sie so viel Wissen über die Anwendungsabsicht wie möglich beibehalten, ist dies keine Belastung für Anwendungen.
Eine Optimierung besteht darin, dass viele Treiber effizientere Speicherzugriffe durch Shader erzeugen können, wenn sie die Zusagen kennen, die eine Anwendung hinsichtlich der statischen Freundlichkeit von Deskriptoren und Daten machen kann. Beispielsweise könnten Treiber eine Dekonstruktionsebene für den Zugriff auf einen Deskriptor in einem Heap entfernen, indem sie ihn in einen Stammdeskriptor konvertieren, wenn die jeweilige Hardware nicht hinsichtlich der Größe des Stammarguments vertraulich ist.
Die zusätzliche Aufgabe für Entwickler, die Version 1.1 verwenden, besteht darin, möglichst Zusagen hinsichtlich der Schwankungen und statischen Daten zu machen, damit Treiber die sinnvollen Optimierungen vornehmen können. Entwickler müssen keine Zusagen zur Statischen Ness machen.
Root Signature Version 1.0 funktioniert weiterhin unverändert, obwohl Anwendungen, die Stammsignaturen neu kompilieren, jetzt standardmäßig Stammsignatur 1.1 verwenden (mit einer Option zum Erzwingen von Version 1.0, falls gewünscht).
Statische und flüchtige Flags
Die folgenden Flags sind Teil der Stammsignatur, damit Treiber eine Strategie für den optimalen Umgang mit einzelnen Stammargumenten auswählen können, wenn sie festgelegt werden, und die gleichen Annahmen auch in Pipelinezustandsobjekte (Pipeline State Objects, PSOs) einbetten können, wenn sie ursprünglich kompiliert wurden – da die Stammsignatur Teil eines PSO ist.
Die folgenden Flags werden von der App festgelegt und gelten für Deskriptoren oder Daten.
typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS
{
D3D12_DESCRIPTOR_RANGE_FLAG_NONE = 0,
D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE = 0x1,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8
} D3D12_DESCRIPTOR_RANGE_FLAGS;
typedef enum D3D12_ROOT_DESCRIPTOR_FLAGS
{
D3D12_ROOT_DESCRIPTOR_FLAG_NONE = 0,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE = 0x2,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8
} D3D12_ROOT_DESCRIPTOR_FLAGS;
DESKRIPTOREN _ VOLATILE
Wenn dieses Flag festgelegt ist, können die Deskriptoren in einem Deskriptorheap, auf den von einer Stammdeskriptortabelle verwiesen wird, jederzeit von der Anwendung geändert werden, es sei denn, die Befehlsliste/-pakete, die die Deskriptortabelle binden, wurden übermittelt und nicht abgeschlossen. Die Aufzeichnung einer Befehlsliste und das anschließende Ändern von Deskriptoren in einem Deskriptorheap, auf den sie verweist, bevor die Befehlsliste zur Ausführung übermittelt wird, ist beispielsweise gültig. Dies ist das einzige unterstützte Verhalten von Root Signature Version 1.0.
Wenn das DESCRIPTORS _ VOLATILE-Flag nicht festgelegt ist, sind Deskriptoren statisch. Es gibt kein Flag für diesen Modus. Statische Deskriptoren bedeuten, dass die Deskriptoren in einem Deskriptorheap, auf den von einer Stammdeskriptortabelle verwiesen wird, zu dem Zeitpunkt initialisiert wurden, zu dem die Deskriptortabelle für eine Befehlsliste/ein Paket (während der Aufzeichnung) festgelegt wurde, und die Deskriptoren können erst geändert werden, nachdem die Ausführung der Befehlsliste/des Pakets zum letzten Mal abgeschlossen wurde. Bei Version 1.1 der Stammsignatur sind statische Deskriptoren die Standardannahme, und die Anwendung muss bei Bedarf das _ DESCRIPTORS VOLATILE-Flag angeben.
Bei Paketen, die Deskriptortabellen mit statischen Deskriptoren verwenden, müssen die Deskriptoren zum Zeitpunkt der Aufzeichnung des Bündels bereit sein (im Gegensatz zum Aufruf des Bündels) und sich erst ändern, wenn die Ausführung des Pakets zum letzten Mal abgeschlossen ist. Deskriptortabellen, die auf statische Deskriptoren verweisen, müssen während der Bündelaufzeichnung festgelegt und nicht in das Bündel geerbt werden. Es ist gültig, dass eine Befehlsliste eine Deskriptortabelle mit statischen Deskriptoren verwendet, die in einem Bündel festgelegt und an die Befehlsliste zurückgegeben wurde.
Wenn Deskriptoren statisch sind, gibt es eine weitere Verhaltensänderung, die erfordert, dass das DESCRIPTORS _ VOLATILE-Flag festgelegt wird. Zugriffe außerhalb der Grenzen auf Pufferansichten (im Gegensatz zu Texture1D/2D/3D/Cube-Ansichten) sind ungültig und führen zu nicht definierten Ergebnissen, einschließlich möglicher Gerätezurücksetzungen, anstatt Standardwerte für Lese- oder Schreibvorgänge zurückzugeben. Der Zweck, Anwendungen die Möglichkeit zu entziehen, von Hardware außerhalb der Grenzen abhängig zu sein, besteht darin, Treibern die Möglichkeit zu geben, statische Deskriptorzugriffe auf Stammdeskriptorzugriffe heraufzustufen, wenn sie dies für effizienter halten. Stammdeskriptoren unterstützen keine Überprüfung außerhalb der Grenzen.
Wenn Anwendungen beim Zugriff auf Deskriptoren von einem sicheren Speicherzugriffsverhalten außerhalb der Grenzen abhängen, müssen sie die Deskriptorbereiche, die auf diese Deskriptoren zugreifen, als DESCRIPTORS _ VOLATILE markieren.
DATA _ VOLATILE
Wenn dieses Flag festgelegt ist, können die Daten, auf die von Deskriptoren verwiesen wird, jederzeit von der CPU geändert werden, es sei denn, die Befehlsliste/-pakete, die die Deskriptortabelle binden, wurden übermittelt und haben die Ausführung nicht abgeschlossen. Dies ist das einzige unterstützte Verhalten von Root Signature Version 1.0.
Das Flag ist sowohl in Deskriptorbereichsflags als auch in Stammdeskriptorflags verfügbar.
DATA _ STATIC WÄHREND SET AT _ _ _ _ EXECUTE
Wenn dieses Flag festgelegt ist, können sich die Daten, auf die deskriptors zeigen, nicht ab ändern, wenn der zugrunde liegende Stammdeskriptor oder die Deskriptortabelle während der Ausführung auf der GPU-Zeitachse in einer Befehlsliste/einem Bündel festgelegt wird und das Ende endet, wenn nachfolgende Zeichnen/Dispatches nicht mehr auf die Daten verweisen.
Bevor eine Stammdeskriptor- oder Deskriptortabelle auf der GPU festgelegt wurde, können diese Daten auch durch dieselbe Befehlsliste/dasselbe Befehlspaket geändert werden. Die Daten können auch geändert werden, während eine Stammdeskriptor- oder Deskriptortabelle, die auf sie verweist, weiterhin in der Befehlsliste bzw. im Bündel festgelegt ist, solange draw/dispatches, die auf sie verweisen, abgeschlossen ist. Dies erfordert jedoch, dass die Deskriptortabelle erneut an die Befehlsliste gebunden wird, bevor der Stammdeskriptor oder die Deskriptortabelle das nächste Mal dereferenziert wird. Dadurch kann der Treiber erkennen, dass sich die Daten geändert haben, auf die von einem Stammdeskriptor oder einer Deskriptortabelle verwiesen wird.
Der wesentliche Unterschied zwischen DATA _ STATIC WHILE SET AT EXECUTE und DATA VOLATILE besteht _ _ _ _ _ darin, dass ein Treiber mit DATA VOLATILE _ nicht erkennen kann, ob Datenkopien in einer Befehlsliste die Daten geändert haben, auf die von einem Deskriptor verwiesen wird, ohne eine zusätzliche Zustandsnachverfolgung durchzuführen. Wenn ein Treiber z. B. beliebige Datenvorabrufbefehle in die Befehlsliste einfügen kann (um z. B. den Shaderzugriff auf bekannte Daten effizienter zu gestalten), informiert DATA _ STATIC WHILE SET AT EXECUTE den Treiber _ _ _ _ darüber, dass er nur datenvorabrufen muss, wenn er über SetGraphicsRootDescriptorTable, SetComputeRootDescriptorTable oder eine der Methoden zum Festlegen der konstanten Pufferansicht festgelegt wird. Shaderressourcenansicht oder ungeordnete Zugriffsansicht.
Bei Paketen gilt die Zusage, dass Daten statisch sind, während sie bei der Ausführung festgelegt sind, eindeutig für jede Ausführung des Pakets.
Das Flag ist sowohl in Deskriptorbereichsflags als auch in Stammdeskriptorflags verfügbar.
DATA _ STATIC
Wenn dieses Flag festgelegt ist, wurden die Daten, auf die von Deskriptoren verwiesen wird, initialisiert, wenn ein Stammdeskriptor oder eine Deskriptortabelle, die auf den Arbeitsspeicher verweist, während der Aufzeichnung für eine Befehlsliste/ein Paket festgelegt wurde, und die Daten können erst geändert werden, nachdem die Ausführung der Befehlsliste/des Pakets zum letzten Mal abgeschlossen wurde.
Bei Paketen beginnt die statische Dauer bei der Einstellung für Stammdeskriptor oder Deskriptortabelle während der Aufzeichnung des Bündels, anstatt eine aufrufende Befehlsliste aufzuzeichnen. Darüber hinaus muss eine Deskriptortabelle, die auf statische Daten verweist, im Bündel festgelegt und nicht geerbt werden. Es ist gültig, dass eine Befehlsliste eine Deskriptortabelle verwendet, die auf statische Daten verweist, die in einem Bündel festgelegt und an die Befehlsliste zurückgegeben wurden.
Das Flag ist sowohl in Deskriptorbereichsflags als auch in Stammdeskriptorflags verfügbar.
Kombinieren von Flags
Höchstens eines der DATA-Flags kann gleichzeitig angegeben werden, mit Ausnahme von Sampler-Deskriptorbereichen, die überhaupt keine DATA-Flags unterstützen, da Sampler nicht auf Daten verweisen.
Das Fehlen von DATA-Flags für SRV- und CBV-Deskriptorbereiche bedeutet, dass ein Standardverhalten von DATA _ STATIC WHILE SET AT EXECUTE angenommen _ _ _ _ wird. Der Grund, warum diese Standardeinstellung anstelle von DATA STATIC ausgewählt _ wird, ist, dass DATA _ STATIC WHILE SET AT EXECUTE in den meisten Fällen viel _ _ _ _ wahrscheinlicher als sicherer Standardwert gilt, während dennoch einige Optimierungsmöglichkeiten besser sind als die Standardeinstellung DATA _ VOLATILE.
Das Fehlen von DATA-Flags für UAV-Deskriptorbereiche bedeutet, dass ein Standardverhalten von DATA VOLATILE angenommen wird, da in der _ Regel UAVs geschrieben werden.
DESCRIPTORS _ VOLATILE kann nicht mit DATA _ STATIC, aber mit den anderen DATA-Flags kombiniert werden. Der Grund, warum DESCRIPTORS _ VOLATILE mit DATA STATIC kombiniert werden _ _ kann, WÄHREND SET AT EXECUTE _ _ festgelegt _ ist, ist, dass flüchtige Deskriptoren die Deskriptoren während der Ausführung der Befehlsliste/des Bündels noch bereit sein müssen, und DATA _ STATIC WHILE SET AT EXECUTE nur _ _ _ _ Zusagen zur statischen Ness innerhalb einer Teilmenge der Befehlsliste/Paketausführung macht.
Flagzusammenfassung
In den folgenden Tabellen werden die möglicherweise verwendeten Flagkombinationen zusammengefasst.
| Gültige D3D12 _ DESCRIPTOR _ RANGE _ FLAGS-Einstellungen | BESCHREIBUNG |
|---|---|
| Keine Flags festgelegt | Deskriptoren sind statisch (Standardeinstellung). Standardannahmen für Daten: für SRV/CBV: DATA _ STATIC WHILE SET AT EXECUTE und für _ _ _ _ UAV: DATA _ VOLATILE. Diese Standardwerte für SRV/CBV entsprechen sicher den Verwendungsmustern für die meisten Stammsignaturen. |
| DATA _ STATIC | Sowohl Deskriptoren als auch Daten sind statisch. Dadurch wird das Potenzial für die Treiberoptimierung maximiert. |
| DATA _ VOLATILE | Deskriptoren sind statisch, und die Daten sind flüchtig. |
| DATA _ STATIC WÄHREND SET AT _ _ _ _ EXECUTE | Deskriptoren sind statisch, und Daten sind statisch, während sie bei der Ausführung festgelegt werden. |
| DESKRIPTOREN _ VOLATILE | Deskriptoren sind flüchtig, und es werden Standardannahmen zu Daten getroffen: für SRV/CBV: DATA _ STATIC WHILE SET AT EXECUTE und für _ _ _ _ UAV: DATA _ VOLATILE. |
| DESKRIPTOREN _ VOLATILE | DATA _ VOLATILE | Sowohl Deskriptoren als auch Daten sind flüchtig, was der Stammsignatur 1.0 entspricht. |
| DESKRIPTOREN _ | FLÜCHTIGER DATEN _ STATISCH _ WÄHREND DER FESTLEGUNG BEI DER _ _ _ AUSFÜHRUNG | Deskriptoren sind flüchtig, aber beachten Sie, dass sie während der Ausführung der Befehlsliste nicht geändert werden können. Daher ist es gültig, die zusätzliche Deklaration zu kombinieren, dass Daten statisch sind, während sie während der Ausführung über die Stammdeskriptortabelle festgelegt werden. Die zugrunde liegenden Deskriptoren sind effektiv länger statisch, als die Daten als statisch zugesichert werden. |
| Gültige D3D12 _ ROOT _ DESCRIPTOR _ FLAGS-Einstellungen | BESCHREIBUNG |
|---|---|
| Keine Flags festgelegt | Standardannahmen für Daten: für SRV/CBV: DATA _ STATIC WHILE SET AT EXECUTE und für _ _ _ _ UAV: DATA _ VOLATILE. Diese Standardwerte für SRV/CBV entsprechen sicher den Verwendungsmustern für die meisten Stammsignaturen. |
| DATA _ STATIC | Daten sind statisch, das beste Potenzial für die Treiberoptimierung. |
| DATA _ STATIC WÄHREND SET AT _ _ _ _ EXECUTE | Daten sind statisch, während sie bei der Ausführung festgelegt werden. |
| DATA _ VOLATILE | Entspricht stammsignatur 1.0. |
API-Zusammenfassung der Version 1.1
Die folgenden API-Aufrufe ermöglichen Version 1.1.
Enumerationen
Diese Enumerationen enthalten die Schlüsselflags zum Angeben der Deskriptor- und Datenvolatilität.
- D3D _ ROOT _ SIGNATURE _ VERSION : Versions-IDs.
- D3D12 _ DESCRIPTOR _ RANGE _ FLAGS: Ein Bereich von Flags, der bestimmt, ob Deskriptoren oder Daten flüchtig oder statisch sind.
- D3D12 _ ROOT _ DESCRIPTOR _ FLAGS: Ein ähnlicher Bereich von Flags wie D3D12 _ DESCRIPTOR _ RANGE _ FLAGS,mit der Ausnahme, dass nur Datenflags für Stammdeskriptoren gelten.
Strukturen
Aktualisierte Strukturen (ab Version 1.0) enthalten Verweise auf die Flags "volatiley"/"static".
D3D12 _ FEATURE _ DATA _ ROOT _ SIGNATURE: Übergeben Sie diese Struktur an CheckFeatureSupport, um zu überprüfen, ob Root Signature Version 1.1 unterstützt wird.
D3D12 _ VERSIONED _ ROOT _ SIGNATURE _ DESC: kann eine beliebige Version einer Stammsignaturbeschreibung enthalten und ist für die Verwendung mit den unten aufgeführten Serialisierungs-/Deserialisierungsfunktionen konzipiert.
Diese Strukturen entsprechen denen, die in Version 1.0 verwendet werden, mit dem Hinzufügen neuer Flagfelder für Deskriptorbereiche und Stammdeskriptoren:
Functions
Die hier aufgeführten Methoden ersetzen die ursprünglichen Funktionen D3D12SerializeRootSignature und D3D12CreateRootSignatureDeserializer, da sie für die Arbeit mit einer beliebigen Version der Stammsignatur konzipiert sind. Das serialisierte Formular wird an die CreateRootSignature-API übergeben. Wenn ein Shader mit einer Stammsignatur erstellt wurde, enthält der kompilierte Shader bereits eine serialisierte Stammsignatur.
- D3D12SerializeVersionedRootSignature: Wenn eine Anwendung die D3D12 _ VERSIONED _ ROOT _ SIGNATURE-Datenstruktur prozedural generiert, muss sie das serialisierte Formular mit dieser Funktion erstellen.
- D3D12CreateVersionedRootSignatureDeserializer: generiert eine Schnittstelle, die die deserialisierte Datenstruktur über GetUnconvertedRootSignatureDesczurückgeben kann.
Methoden
Die ID3D12VersionedRootSignatureDeserializer-Schnittstelle wird erstellt, um die Stammsignaturdatenstruktur zu deserialisieren.
- GetRootSignatureDescAtVersion: Konvertiert Stammsignaturbeschreibungsstrukturen in eine angeforderte Version.
- GetUnconvertedRootSignatureDesc: Gibt einen Zeiger auf eine D3D12 _ VERSIONED _ ROOT SIGNATURE _ _ DESC-Struktur zurück.
Hilfsstrukturen
Hilfsstrukturen wurden hinzugefügt, um die Initialisierung einiger der Strukturen der Version 1.1 zu unterstützen.
- CD3DX12 _ DESCRIPTOR _ RANGE1
- CD3DX12 _ ROOT _ PARAMETER1
- CD3DX12 _ STATIC _ SAMPLER1
- CD3DX12 _ VERSIONED _ ROOT _ SIGNATURE _ DESC
Weitere Informationen finden Sie unter Hilfsstrukturen und -funktionen für D3D12.
Folgen eines Verstoßs gegen Statische-Ness-Flags
Die oben beschriebenen Deskriptor- und Datenflags (sowie die Standardeinstellungen, die durch das Fehlen bestimmter Flags impliziert werden) definieren eine Zusage der Anwendung an den Treiber in Bezug auf das Verhalten. Wenn eine Anwendung gegen die Zusage verstößt, ist dies ungültiges Verhalten: Ergebnisse sind nicht definiert und können sich über verschiedene Treiber und Hardware hinweg unterscheiden.
Die Debugebene verfügt über Optionen zum Überprüfen, dass Anwendungen ihre Zusagen einhalten, einschließlich der Standardzusicherungen, die mit der Verwendung von Root Signature Version 1.1 geliefert werden, ohne Flags festzulegen.
Versionsverwaltung
Beim Kompilieren von Stammsignaturen, die an Shader angefügt sind, kompilieren neuere HLSL-Compiler standardmäßig die Stammsignatur in Version 1.1, während alte HLSL-Compiler nur 1.0 unterstützen. Beachten Sie, dass 1.1-Stammsignaturen unter Betriebssystemen, die Stammsignatur 1.1 nicht unterstützen, nicht funktionieren.
Die mit einem Shader kompilierte Stammsignaturversion kann mithilfe von auf eine bestimmte Version erzwungen /force_rootsig_ver <version> werden. Das Erzwingen der Version ist erfolgreich, wenn der Compiler das Verhalten der Stammsignatur, die mit der erzwungenen Version kompiliert wird, beibehalten kann, z. B. durch Löschen nicht unterstützter Flags in der Stammsignatur, die nur zu Optimierungszwecken dienen, sich aber nicht auf das Verhalten auswirken.
Auf diese Weise kann eine Anwendung z. B. eine 1.1-Stammsignatur für 1.0 und 1.1 kompilieren, wenn sie die Anwendung erstellt und die entsprechende Version zur Laufzeit abhängig vom Grad der Betriebssystemunterstützung auswählt. Es wäre jedoch am effizientesten, wenn eine Anwendung Stammsignaturen einzeln (insbesondere, wenn mehrere Versionen benötigt werden) getrennt von Shadern kompilieren würde. Selbst wenn Shader anfänglich nicht mit einer angefügten Stammsignatur kompiliert werden, kann der Vorteil der Compilervalidierung der Stammsignaturkompatibilität mit einem Shader mithilfe der Compileroption beibehalten /verifyrootsignature werden. Später zur Laufzeit können PSOs mit Shadern erstellt werden, die keine Stammsignaturen enthalten, während die gewünschte Stammsignatur (möglicherweise die entsprechende Version, die vom Betriebssystem unterstützt wird) als separater Parameter übergeben wird.