Share via


Indirektes Zeichnen

Indirektes Zeichnen ermöglicht es, einige Szenendurchläufe und Cullings von der CPU auf die GPU zu verschieben, was die Leistung verbessern kann. Der Befehlspuffer kann von der CPU oder GPU generiert werden.

Befehlssignaturen

Mit dem Befehlssignaturobjekt (ID3D12CommandSignature) können Apps indirekte Zeichnung angeben, insbesondere Folgendes festlegen:

Beim Start erstellt eine App einen kleinen Satz von Befehlssignaturen. Zur Laufzeit füllt die Anwendung einen Puffer mit Befehlen (über die vom App-Entwickler gewählten Mittel). Die Befehle enthalten optional den Zustand, der für Vertexpuffersichten, Indexpuffersichten, Stammkonstanten und Stammdeskriptoren (rohe oder strukturierte SRV/UAV/CBVs) festgelegt werden soll. Diese Argumentlayouts sind nicht hardwarespezifisch, sodass Apps die Puffer direkt generieren können. Die Befehlssignatur erbt den verbleibenden Zustand aus der Befehlsliste. Anschließend ruft die App ExecuteIndirect auf, um die GPU anzuweisen, den Inhalt des indirekten Argumentpuffers entsprechend dem format zu interpretieren, das durch eine bestimmte Befehlssignatur definiert wird.

Wenn die Befehlssignatur Stammargumente ändert, wird dies in der Befehlssignatur als Teilmenge einer Stammsignatur gespeichert.

Beachten Sie, dass kein Befehlssignaturstatus in die Befehlsliste zurückfällt, wenn die Ausführung abgeschlossen ist.

Angenommen, ein App-Entwickler möchte eine eindeutige Stammkonstante pro Zeichnungsaufruf im indirekten Argumentpuffer angeben. Die App erstellt eine Befehlssignatur, die es dem indirekten Argumentpuffer ermöglicht, die folgenden Parameter pro Draw-Aufruf anzugeben:

  • Der Wert einer Stammkonstante.
  • Die Zeichenargumente (Vertexanzahl, instance Anzahl usw.).

Der von der Anwendung generierte indirekte Argumentpuffer würde ein Array von Datensätzen mit fester Größe enthalten. Jede Struktur entspricht einem Zeichnungsaufruf. Jede Struktur enthält die Zeichenargumente und den Wert der Stammkonstante. Die Anzahl der Zeichnungsaufrufe wird in einem separaten GPU-sichtbaren Puffer angegeben.

Es folgt ein Beispielbefehlspuffer, der von der App generiert wurde:

Befehlspufferformat

Indirekte Argumentpufferstrukturen

Die folgenden Strukturen definieren, wie bestimmte Argumente in einem indirekten Argumentpuffer angezeigt werden. Diese Strukturen werden in keiner D3D12-API angezeigt. Anwendungen verwenden diese Definitionen beim Schreiben in einen indirekten Argumentpuffer (mit der CPU oder GPU):

Erstellen von Befehlssignaturen

Verwenden Sie zum Erstellen einer Befehlssignatur die folgenden API-Elemente:

Die Reihenfolge von Argumenten innerhalb eines indirekten Argumentpuffers wird so definiert, dass sie genau der Reihenfolge der Argumente entspricht, die im pArguments-Parameter von D3D12_COMMAND_SIGNATURE_DESC angegeben sind. Alle Argumente für einen Draw(Grafik)/Dispatch-Aufruf (Compute) in einem indirekten Argumentpuffer sind eng gepackt. Anwendungen können jedoch einen beliebigen Byteschritt zwischen Draw-/Dispatch-Befehlen in einem indirekten Argumentpuffer angeben.

Die Stammsignatur muss nur angegeben werden, wenn die Befehlssignatur eines der Stammargumente ändert.

Für den SRV/UAV/CBV-Stamm ist die angegebene Anwendungsgröße in Bytes. Die Debugebene überprüft die folgenden Einschränkungen für die Adresse:

  • CBV: Die Adresse muss ein Vielfaches von 256 Bytes sein.
  • Unformatierte SRV/UAV: Die Adresse muss ein Vielfaches von 4 Bytes sein.
  • Strukturierte SRV/UAV: Adresse muss ein Vielfaches des Strukturbytes stride sein (im Shader deklariert).

Eine bestimmte Befehlssignatur ist entweder eine Zeichen- oder eine Computebefehlssignatur. Wenn eine Befehlssignatur einen Zeichnungsvorgang enthält, handelt es sich um eine Grafikbefehlssignatur. Andernfalls muss die Befehlssignatur einen Verteilungsvorgang enthalten, und es handelt sich um eine Computebefehlssignatur.

Die folgenden Abschnitte zeigen einige Beispielbefehlssignaturen.

Keine Argumentänderungen

In diesem Beispiel enthält der von der Anwendung generierte indirekte Argumentpuffer ein Array von 36-Byte-Strukturen. Jede Struktur enthält nur die fünf Parameter, die an DrawIndexedInstanced (plus Padding) übergeben werden.

Der Code zum Erstellen der Befehlssignaturbeschreibung folgt:

D3D12_INDIRECT_ARGUMENT_DESC Args[1];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;

D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 36;
ProgramDesc.NumArgumentDescs = 1;
ProgramDesc.pArguments = Args;

Das Layout einer einzelnen Struktur in einem indirekten Argumentpuffer lautet:

Byte BESCHREIBUNG
0:3 IndexCountPerInstance
4:7 InstanceCount
8:11 StartIndexLocation
12:15 BaseVertexLocation
16:19 StartInstanceLocation
20:35 Auffüllen

 

Stammkonstanten und Vertexpuffer

In diesem Beispiel ändert jede Struktur in einem indirekten Argumentpuffer zwei Stammkonstanten, ändert eine Vertexpufferbindung und führt einen nicht indizierten Zeichnungsvorgang aus. Zwischen Strukturen gibt es keine Auffüllung.

Der Code zum Erstellen der Befehlssignaturbeschreibung lautet:

D3D12_INDIRECT_ARGUMENT_DESC Args[4];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[0].Constant.RootParameterIndex = 2;
Args[0].Constant.DestOffsetIn32BitValues = 0;
Args[0].Constant.Num32BitValuesToSet = 1;

Args[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[1].Constant.RootParameterIndex = 6;
Args[1].Constant.DestOffsetIn32BitValues = 0;
Args[1].Constant.Num32BitValuesToSet = 1;

Args[2].Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW;
Args[2].VertexBuffer.Slot = 3;

Args[3].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;

D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 40;
ProgramDesc.NumArgumentDescs = 4;
ProgramDesc.pArguments = Args;

Das Layout einer einzelnen Struktur innerhalb des indirekten Argumentpuffers ist wie folgt:

Byte BESCHREIBUNG
0:3 Daten für den Stammparameterindex 2
4:7 Daten für den Stammparameterindex 6
8:15 Virtuelle Adresse von VB am Slot 3 (64-Bit)
16:19 VB-Größe
20:23 VB-Schritt
24:27 VertexCountPerInstance
28:31 InstanceCount
32:35 StartVertexLocation
36:39 StartInstanceLocation

 

DirectX-Videotutorials für erweitertes Lernen: Ausführen indirekter und asynchroner GPU-Culling

Indirektes Zeichnen und GPU-Culling: Exemplarische Codeanleitung

Darstellung