Verwalten des Grafikpipelinestatus in Direct3D 12

In diesem Thema wird beschrieben, wie der Zustand der Grafikpipeline in Direct3D 12 festgelegt wird.

Übersicht über den Pipelinestatus

Wenn geometrie an die Grafikverarbeitungseinheit (GPU) übermittelt wird, um gezeichnet zu werden, gibt es eine Vielzahl von Hardwareeinstellungen, die bestimmen, wie die Eingabedaten interpretiert und gerendert werden. Zusammen werden diese Einstellungen als Grafikpipelinezustand bezeichnet und umfassen allgemeine Einstellungen wie den Rasterisierungszustand, den Mischzustand und den Tiefenschablonenzustand sowie den primitiven Topologietyp der übermittelten Geometrie und die Shader, die zum Rendern verwendet werden. In Microsoft Direct3D 12 wird der meiste Grafikpipelinestatus mithilfe von Pipelinezustandsobjekten (Pipeline State Objects, PSO) festgelegt. Eine App kann eine unbegrenzte Anzahl dieser Objekte erstellen, die durch die ID3D12PipelineState-Schnittstelle dargestellt werden, in der Regel zur Initialisierungszeit. Dann können Befehlslisten zur Renderzeit schnell mehrere Einstellungen des Pipelinestatus ändern, indem SIE ID3D12GraphicsCommandList::SetPipelineState in einer direkten Befehlsliste oder einem Bündel aufrufen, um den aktiven PSO festzulegen.

In Direct3D 11 wurde der Zustand der Grafikpipeline in große, grobkörnige Zustandsobjekte wie ID3D11BlendState gebündelt, die zur Renderzeit im unmittelbaren Kontext mit Methoden wie ID3D11DeviceContext::OMSetBlendState erstellt und festgelegt werden konnten. Die Idee dahinter war, dass die GPU effizienzgewinnen konnte, indem sie verwandte Einstellungen wie die Einstellungen für den Mischzustand auf einmal festlegt. Bei der heutigen Grafikhardware gibt es 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 vorverarbeiten kann, in der Regel während der Initialisierung, um den Wechsel zwischen den Zuständen zur Renderzeit so effizient wie möglich zu gestalten.

Beachten Sie, dass die meisten Pipelinestatuseinstellungen zwar über PsOs festgelegt werden, es jedoch einige Zustandseinstellungen gibt, die separat mithilfe von APIs festgelegt werden, die von ID3D12GraphicsCommandList bereitgestellt werden. Diese Einstellungen und die zugehörigen APIs werden unten ausführlich erläutert. Außerdem gibt es Unterschiede in der Art und Weise, wie der Grafikpipelinestatus von vererbt und aus direkten Befehlslisten und Bündeln beibehalten wird. In diesem Thema finden Sie Details zu den beiden unten aufgeführten Informationen.

Grafikpipelinezustände mit Pipelinestatusobjekten festgelegt

Die einfachste Möglichkeit, alle verschiedenen Pipelinezustände anzuzeigen, die mithilfe eines Pipelinezustandsobjekts festgelegt werden können, besteht darin, sich das Referenzthema für die D3D12_GRAPHICS_PIPELINE_STATE_DESC anzusehen, die Sie beim Initialisieren des Objekts an ID3D12Device::CreateGraphicsPipelineState übergeben. Eine kurze Zusammenfassung der Zustände, die festgelegt werden können, enthält Folgendes:

  • Der Bytecode für alle Shader, einschließlich Vertex-, Pixel-, Domänen-, Hull- und Geometry-Shadern.
  • Das Eingabevertexformat.
  • Der primitive Topologietyp. Beachten Sie, dass der primitive Topologietyp der Eingabeassember (Punkt, Linie, Dreieck, Patch) innerhalb des PSO mithilfe der D3D12_PRIMITIVE_TOPOLOGY_TYPE-Enumeration festgelegt wird. Die primitive Adjazenz und Reihenfolge (Zeilenliste, Zeilenstreifen, Zeilenstreifen mit Adjacency-Daten usw.) wird in einer Befehlsliste mithilfe der ID3D12GraphicsCommandList::IASetPrimitiveTopology-Methode festgelegt.
  • Der Mischzustand, Rasterungszustand, Tiefenschablonenzustand.
  • Die Tiefenschablonen- und Renderzielformate sowie die Anzahl der Renderziele.
  • Parameter mit mehreren Stichprobenentnahmen.
  • 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 Pipelinestatusparametern, die durch Aufrufen von Methoden der ID3D12GraphicsCommandList-Schnittstelle innerhalb einer Befehlsliste festgelegt werden. Die folgende Tabelle zeigt die auf diese Weise festgelegten Zustände und die entsprechenden Methoden.

State Methode
Ressourcenbindungen IASetIndexBuffer
IASetVertexBuffers
SOSetTargets
OMSetRenderTargets
SetDescriptorHeaps
Alle SetGraphicsRoot...- Methoden
Alle SetComputeRoot...- Methoden
Ansichtsfenster RSSetViewports
Scherenrekts RSSetScissorRects
Mischfaktor OMSetBlendFactor
Der Referenzwert der Tiefenschablone OMSetStencilRef
Die primitive Topologiereihenfolge und der Adjazenztyp der Eingabe-Assembler IASetPrimitiveTopology

Vererbung des Grafikpipelinezustands

Da direkte Befehlslisten in der Regel jeweils für eine Verwendung vorgesehen sind und Bundles mehrere Male gleichzeitig verwendet werden sollen, gibt es unterschiedliche Regeln darüber, wie sie den Zustand der Grafikpipeline erben, der von vorherigen Befehlslisten oder Bundles festgelegt wurde.

Für die Grafikpipelinezustände, die mithilfe von PsOs festgelegt werden, wird keiner dieser Zustände von direkten Befehlslisten oder Bündeln geerbt. Der anfängliche Grafikpipelinezustand für direkte Befehlslisten und Bundles wird zur Erstellungszeit mit dem PARAMETER ID3D12PipelineState auf ID3D12Device::CreateCommandList festgelegt. Wenn im Aufruf kein PSO angegeben ist, wird ein Standard-Anfangszustand verwendet. Sie können den aktuellen PSO in einer Befehlsliste ändern, indem Sie ID3D12GraphicsCommandList::SetPipelineState aufrufen.

Direkte Befehlslisten erben auch nicht den Zustand, der mit Befehlslistenmethoden wie RSSetViewports festgelegt ist. 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 ist immer auf D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED festgelegt, wenn ein Bundle mit der Ausführung beginnt. Jeder Zustand, der innerhalb eines Bundles festgelegt wird (der PSO selbst, der nicht PSO-basierte Zustand und ressourcenbasierte Bindungen), wirkt sich auf den Zustand der übergeordneten direkten Befehlsliste aus. Wenn beispielsweise ein RSSetViewports innerhalb eines Bundles aufgerufen wird, werden die angegebenen Viewports weiterhin in der Liste der übergeordneten direkten Befehle für Aufrufe nach dem ExecuteBundle-Aufruf festgelegt, mit dem die Viewports festgelegt werden.

Ressourcenbindungen, die innerhalb einer Befehlsliste oder eines Bundles festgelegt werden, bleiben erhalten. Ressourcenbindungen, die in einer direkten Befehlsliste geändert wurden, werden also weiterhin innerhalb der nachfolgenden untergeordneten Bündelausführung festgelegt. Ressourcenbindungen, die innerhalb eines Bundles geändert werden, werden weiterhin für nachfolgende Aufrufe in der übergeordneten direkten Befehlsliste festgelegt.

Weitere Informationen zu Bindungen finden Sie im Abschnitt Bündelsemantik unter Verwenden einer Stammsignatur.