Verwenden einer Stammsignatur
Die Stammsignatur ist die Definition einer willkürlich angeordneten Auflistung von Deskriptortabellen (einschließlich ihres Layouts), Stammkonstanten und Stammdeskriptoren. Jeder Eintrag hat Kosten in Richtung eines Höchstlimits, sodass die Anwendung den Ausgleich zwischen der Anzahl der einzelnen Arten von Einträgen in der Stammsignatur ausgleichen kann.
Die Stammsignatur ist ein Objekt, das durch manuelle Spezifikation an der API erstellt werden kann. Alle Shader in einem PSO müssen mit dem mit dem PSO angegebenen Stammlayout kompatibel sein, andernfalls müssen die einzelnen Shader eingebettete Stammlayouts enthalten, die zueinander passen. Andernfalls schlägt die PSO-Erstellung fehl. Eine Eigenschaft der Stammsignatur ist, dass Shader beim Erstellen nichts davon wissen müssen, obwohl Stammsignaturen bei Bedarf auch direkt in Shadern erstellt werden können. Vorhandene Shaderressourcen erfordern keine Änderungen, um mit Stammsignaturen kompatibel zu sein. Shadermodell 5.1 wird eingeführt, um zusätzliche Flexibilität zu bieten (dynamische Indizierung von Deskriptoren innerhalb von Shadern) und kann nach Wunsch inkrementell von vorhandenen Shaderressourcen übernommen werden.
Befehlslistensemantik
Am Anfang einer Befehlsliste ist die Stammsignatur nicht definiert. Grafik-Shader verfügen über eine separate Stammsignatur vom Compute-Shader, die jeweils unabhängig in einer Befehlsliste zugewiesen werden. Der Stammsignatursatz für eine Befehlsliste oder ein Bundle muss auch mit dem aktuell festgelegten PSO unter Draw/Dispatch übereinstimmen. andernfalls ist das Verhalten nicht definiert. Vorübergehende Stammsignaturkonflikte vor Draw/Dispatch sind in Ordnung, z. B. das Festlegen eines inkompatiblen PSO vor dem Wechsel zu einer kompatiblen Stammsignatur (sofern diese zum Zeitpunkt des Aufrufs von Draw/Dispatch kompatibel sind). Das Festlegen eines PSO ändert die Stammsignatur nicht. Die Anwendung muss eine dedizierte API zum Festlegen der Stammsignatur aufrufen.
Sobald eine Stammsignatur für eine Befehlsliste festgelegt wurde, definiert das Layout den Satz von Bindungen, die die Anwendung bereitstellen soll, und welche PsOs für die nächsten Draw/Dispatch-Aufrufe verwendet werden können (die mit demselben Layout kompiliert wurden). Beispielsweise kann eine Stammsignatur von der Anwendung definiert werden, um die folgenden Einträge zu enthalten. Jeder Eintrag wird als "Slot" bezeichnet.
- [0] Eine CBV-Deskriptor-Inline (Stammdeskriptoren)
- [1] Eine Deskriptortabelle mit 2 SRVs, 1 CBVs und 1 UAV
- [2] Eine Deskriptortabelle mit 1 Sampler
- [3] Eine 4x32-Bit-Auflistung von Stammkonstanten
- [4] Eine Deskriptortabelle, die eine nicht angegebene Anzahl von SRVs enthält.
In diesem Fall wird erwartet, dass die Anwendung, bevor sie eine Draw/Dispatch-Instanz ausstellen kann, die entsprechende Bindung für jeden der Slots [0..4] festgelegt wird, die die Anwendung mit ihrer aktuellen Stammsignatur definiert hat. Für instance muss im Slot [1] eine Deskriptortabelle gebunden sein, die ein zusammenhängender Bereich in einem Deskriptorheap ist, der 2 SRVs, 1 CBVs und 1 UAV enthält (oder bei der Ausführung enthalten wird). Auf ähnliche Weise müssen Deskriptortabellen an den Slots [2] und [4] festgelegt werden.
Die Anwendung kann einen Teil der Stammsignaturbindungen gleichzeitig ändern (der Rest bleibt unverändert). Wenn beispielsweise zwischen Ziehungen nur eine der Konstanten am Slot [2] geändert werden muss, muss dies nur die Anwendung neu binden. Wie bereits erläutert, gibt der Treiber/die Hardware den gesamten Stammsignaturbindungsstatus an, da er automatisch geändert wird. Wenn eine Stammsignatur in einer Befehlsliste geändert wird, werden alle vorherigen Stammsignaturbindungen veraltet, und alle neu erwarteten Bindungen müssen vor Draw/Dispatch festgelegt werden. andernfalls ist das Verhalten nicht definiert. Wenn die Stammsignatur redundant auf die gleiche festgelegte festgelegt ist, werden vorhandene Stammsignaturbindungen nicht veraltet.
Bündelsemantik
Bundles erben die Stammsignaturbindungen der Befehlsliste (die Bindungen an die verschiedenen Slots im obigen Beispiel befehlsliste). Wenn ein Bundle einige der geerbten Stammsignaturbindungen ändern muss, muss es zuerst festlegen, dass die Stammsignatur mit der aufrufenden Befehlsliste identisch ist (die geerbten Bindungen werden nicht veraltet). Wenn das Bundle die Stammsignatur von der aufrufenden Befehlsliste unterscheidet, hat dies die gleiche Auswirkung wie das Ändern der Stammsignatur in der oben beschriebenen Befehlsliste: Alle vorherigen Stammsignaturbindungen sind veraltet, und neu erwartete Bindungen müssen vor Draw/Dispatch festgelegt werden; andernfalls ist das Verhalten nicht definiert. Wenn ein Bundle keine Stammsignaturbindungen ändern muss, muss es die Stammsignatur nicht festlegen.
Der folgende Code zeigt einen Beispielaufrufflow in ein Bundle.
// Command List
...
pCmdList->SetGraphicsRootSignature(pRootSig); // new parameter space
MyEngine_SetTextures(); // bundle inherits descriptor table setting
MyEngine_SetAnimationFactor(fTime); // bundle inherits root constant
pCmdList->ExecuteBundle(...);
...
// Bundle
pBundle->SetGraphicsRootSignature(pRootSig); // same as caller, in order to inherits bindings
pBundle->SetPipelineState(pPS);
pBundle->SetGraphicsRoot32BitConstant(drawConstantsSlot,0,drawIDOffset);
pBundle->Draw(...); // using inherited textures / animation factor
pBundle->SetGraphicsRoot32BitConstant(drawConstantsSlot,1,drawIDOffset);
pBundle->Draw(...);
...
Alle Stammlayoutänderungen und/oder Bindungsänderungen, die ein Bündel vornimmt, werden an die aufrufende Befehlsliste zurückvererbt, wenn die Ausführung eines Bundles abgeschlossen ist.
Weitere Informationen zur Vererbung finden Sie im Abschnitt Vererbung des Grafikpipelinezustandsunter Verwalten des Zustands der Grafikpipeline in Direct3D 12.
Zugehörige Themen