Verwalten des Grafikpipelinestatus in Direct3D 12
In diesem Thema wird beschrieben, wie der Grafikpipelinezustand in Direct3D 12 festgelegt wird.
Übersicht über den Pipelinestatus
Wenn geometrie an die grafikverarbeitende Einheit (GPU) übermittelt wird, die gezeichnet werden soll, gibt es eine Vielzahl von Hardwareeinstellungen, die bestimmen, wie die Eingabedaten interpretiert und gerendert werden. Zusammen werden diese Einstellungen als Grafikpipelinezustand bezeichnet und enthalten allgemeine Einstellungen wie rasterizer state, blend state und depth stencil state sowie den primitiven Topologietyp der übermittelten Geometrie und die Shader, die zum Rendern verwendet werden. In Microsoft Direct3D 12 wird der Großteil des Grafikpipelinezustands mithilfe von Pipelinezustandsobjekten (PSO) festgelegt. Eine App kann eine unbegrenzte Anzahl dieser Objekte erstellen, die durch die ID3D12PipelineState-Schnittstelle dargestellt wird, in der Regel zur Initialisierungszeit. Dann können Befehlslisten zur Renderzeit schnell mehrere Einstellungen des Pipelinezustands wechseln, indem sie ID3D12GraphicsCommandList::SetPipelineState in einer direkten Befehlsliste oder einem Bundle aufrufen, um den aktiven PSO festzulegen.
In Direct3D 11 wurde der Grafikpipelinezustand in große, grobe Zustandsobjekte wie ID3D11BlendState gebündelt, die zur Renderzeit im unmittelbaren Kontext mit Methoden wie ID3D11DeviceContext::OMSetBlendStateerstellt und festgelegt werden konnten. Die Idee dahinter war, dass die GPU die Effizienz steigern konnte, indem verwandte Einstellungen, z. B. die Einstellungen für den Blendzustand, auf einmal festgelegt werden. Bei der heutigen Grafikhardware bestehen jedoch Abhängigkeiten zwischen den verschiedenen Hardwareeinheiten. Beispielsweise kann der Hardwaremischungszustand Abhängigkeiten vom Rasterzustand sowie vom Blendzustand aufweisen. PSOs in Direct3D 12 wurden so konzipiert, dass die GPU alle abhängigen Einstellungen in jedem Pipelinezustand vorab verarbeiten kann , in der Regel während der Initialisierung, um das Wechseln zwischen Zuständen zur Renderzeit so effizient wie möglich zu gestalten.
Beachten Sie, dass zwar die meisten Pipelinezustandseinstellungen mithilfe von PSOs festgelegt werden, es jedoch einige Zustandseinstellungen gibt, die separat mithilfe von APIs festgelegt werden, die von ID3D12GraphicsCommandListbereitgestellt werden. Diese Einstellungen und die zugehörigen APIs werden unten ausführlich erläutert. Darüber hinaus gibt es Unterschiede in der Art und Weise, wie der Grafikpipelinezustand von direkten Befehlslisten und Paketen geerbt und von diesen beibehalten wird. Dieses Thema enthält Details zu beiden unten aufgeführten Themen.
Mit Pipelinezustandsobjekten festgelegte Grafikpipelinezustände
Die einfachste Möglichkeit, alle verschiedenen Pipelinezustände anzuzeigen, die mithilfe eines Pipelinezustandsobjekts festgelegt werden können, ist das Referenzthema für D3D12 _ GRAPHICS PIPELINE STATE _ _ _ DESC, das Sie beim Initialisieren des Objekts an ID3D12Device::CreateGraphicsPipelineState übergeben. Eine kurze Zusammenfassung der Zustände, die festgelegt werden können, umfasst Folgendes:
- Der Bytecode für alle Shader, einschließlich Vertex-, Pixel-, Domänen-, Hüllen- und Geometrie-Shadern.
- Das Eingabevertexformat.
- Der primitive Topologietyp. Beachten Sie, dass der primitive Topologietyp des Eingabeassemblierers (Punkt, Linie, Dreieck, Patch) innerhalb des PSO mithilfe der Enumeration D3D12 _ PRIMITIVE _ TOPOLOGY _ TYPE festgelegt wird. Die primitive Adjazenz und Reihenfolge (Zeilenliste, Zeilenstreifen, Zeilenstreifen mit Adjazenzdaten usw.) wird mithilfe der ID3D12GraphicsCommandList::IASetPrimitiveTopology-Methode in einer Befehlsliste festgelegt.
- Der Blendzustand, Rasterizerzustand, Tiefenschablonenzustand.
- Die Tiefenschablone und das Renderzielformat sowie die Anzahl der Renderziele.
- Parameter mit mehreren Stichproben.
- Ein Streamingausgabepuffer.
- Die Stammsignatur. Weitere Informationen finden Sie unter Stammsignaturen.
Außerhalb des Pipelinezustandsobjekts festgelegte Grafikpipelinezustände
Die meisten Grafikpipelinezustände werden mithilfe von PSOs festgelegt. Es gibt jedoch eine Reihe von Pipelinezustandsparametern, die durch Aufrufen von Methoden der ID3D12GraphicsCommandList-Schnittstelle aus einer Befehlsliste festgelegt werden. Die folgende Tabelle zeigt die Zustände, die auf diese Weise festgelegt werden, und die entsprechenden Methoden.
| State | Methode |
|---|---|
| Ressourcenbindungen | IASetIndexBuffer IASetVertexBuffers SOSetTargets OMSetRenderTargets SetDescriptorHeaps Alle SetGraphicsRoot...-Methoden Alle SetComputeRoot...-Methoden |
| Ansichtsfenster | RSSetViewports |
| Scissor rects | RSSetScissorRects |
| Blend-Faktor | OMSetBlendFactor |
| Der Tiefenschablonen-Verweiswert | OMSetStencilRef |
| Die primitive Topologiereihenfolge und der Adjazenztyp des Eingabeassemblierers | IASetPrimitiveTopology |
Vererbung des Grafikpipelinezustands
Da direkte Befehlslisten in der Regel für jeweils eine Verwendung vorgesehen sind und Pakete mehrmals gleichzeitig verwendet werden sollen, gibt es unterschiedliche Regeln darüber, wie sie den Grafikpipelinezustand erben, der von vorherigen Befehlslisten oder Paketen festgelegt wurde.
Für die Grafikpipelinezustände, die mithilfe von PSOs festgelegt werden, wird keiner dieser Zustände von direkten Befehlslisten oder Paketen geerbt. Der anfängliche Grafikpipelinezustand für direkte Befehlslisten und Pakete wird zur Erstellungszeit mit dem Parameter ID3D12PipelineState auf ID3D12Device::CreateCommandListfestgelegt. Wenn im Aufruf kein PSO angegeben wird, wird ein Standard-Anfangszustand verwendet. Sie können den aktuellen PSO in einer Befehlsliste ändern, indem Sie ID3D12GraphicsCommandList::SetPipelineStateaufrufen.
Direkte Befehlslisten erben auch keinen Zustand, der mit Befehlslistenmethoden wie RSSetViewportsfestgelegt wird. Ausführliche Informationen zu den Standardwerten für Nicht-PSO-Zustände finden Sie unter ID3D12GraphicsCommandList::ClearState.
Bundles erben den gesamten Grafikpipelinezustand, der nicht mit PSOs festgelegt ist, mit Ausnahme des primitiven Topologietyps. Die primitive Topologie wird immer auf D3D12 _ PRIMITIVE _ TOPOLOGY _ TYPE _ UNDEFINED festgelegt, wenn ein Bündel mit der Ausführung beginnt. Jeder Zustand, der innerhalb eines Bündels festgelegt ist (der PSO selbst, der nicht PSO-basierte Zustand und Ressourcenbindungen), wirkt sich auf den Zustand der übergeordneten Direktbefehlsliste aus. Wenn ein RSSetViewports beispielsweise innerhalb eines Pakets aufgerufen wird, werden die angegebenen Viewports weiterhin in der übergeordneten Direktbefehlsliste für Aufrufe festgelegt, die auf den ExecuteBundle-Aufruf folgen, der die Viewports festgelegt hat.
Ressourcenbindungen, die in einer Befehlsliste oder einem Bündel festgelegt sind, bleiben erhalten. Daher werden Ressourcenbindungen, die in einer Direkten Befehlsliste geändert werden, weiterhin in der nachfolgenden Ausführung des untergeordneten Pakets festgelegt. Ressourcenbindungen, die innerhalb eines Pakets geändert werden, werden weiterhin für nachfolgende Aufrufe in der übergeordneten Direktbefehlsliste festgelegt.
Weitere Informationen zu Bindungen finden Sie im Abschnitt Bündelsemantik unter Verwenden einer Stammsignatur.