Prädikationsabfragen
Das D3D12PredicationQueries-Beispiel veranschaulicht die Okklusionskulling mithilfe von DirectX 12-Abfrageheaps und Prädication. In der exemplarischen Vorgehensweise wird der zusätzliche Code beschrieben, der zum Erweitern des HelloConstBuffer-Beispiels zur Behandlung von Prädicationabfragen erforderlich ist.
- Erstellen eines Tiefenschablonendeskriptors heap und eines Abfrageheaps mit Okklusion
- Aktivieren der Alphamischung
- Deaktivieren von Farb- und Tiefenschreibvorgängen
- Erstellen eines Puffers zum Speichern der Ergebnisse der Abfrage
- Zeichnen Sie die Quads, und führen Sie die Okklusionsabfrage aus, und lösen Sie sie auf.
- Ausführen des Beispiels
- Zugehörige Themen
Erstellen eines Tiefenschablonendeskriptors heap und eines Abfrageheaps mit Okklusion
Erstellen Sie in der LoadPipeline-Methode einen Tiefenschablonendeskriptor heap.
// Describe and create a depth stencil view (DSV) descriptor heap.
D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
dsvHeapDesc.NumDescriptors = 1;
dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));
Anrufverlauf | Parameter |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeap |
Erstellen Sie in der LoadAssets-Methode einen Heap für Okklusionsabfragen.
// Describe and create a heap for occlusion queries.
D3D12_QUERY_HEAP_DESC queryHeapDesc = {};
queryHeapDesc.Count = 1;
queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
ThrowIfFailed(m_device->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&m_queryHeap)));
Anrufverlauf | Parameter |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeap |
Aktivieren der Alphamischung
Dieses Beispiel zeichnet zwei Quads und veranschaulicht eine Abfrage mit binärer Okklusion. Das Viereck vorne animiert über den Bildschirm, und das quad hinten wird gelegentlich verworren. In der LoadAssets-Methode ist die Alphamischung für dieses Beispiel aktiviert, sodass wir sehen können, an welchem Punkt D3D das Quad in back als verworren betrachtet.
// Enable alpha blending so we can visualize the occlusion query results.
CD3DX12_BLEND_DESC blendDesc(CD3DX12_DEFAULT);
blendDesc.RenderTarget[0] =
{
TRUE, FALSE,
D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
D3D12_LOGIC_OP_NOOP,
D3D12_COLOR_WRITE_ENABLE_ALL,
};
Anrufverlauf | Parameter |
---|---|
CD3DX12_BLEND_DESC |
[D3D12_BLEND] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_blend) [D3D12_BLEND_OP] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_blend_op) [D3D12_LOGIC_OP] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_logic_op) [D3D12_COLOR_WRITE_ENABLE] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_color_write_enable) |
Deaktivieren von Farb- und Tiefenschreibvorgängen
Die Okklusionsabfrage wird durch Rendern eines Quads ausgeführt, das denselben Bereich wie das Quad abdeckt, dessen Sichtbarkeit wir testen möchten. In komplexeren Szenen würde es sich bei der Abfrage wahrscheinlich um ein begrenzungsierendes Volume und nicht um ein einfaches Quad handeln. In beiden Fällen wird ein neuer Pipelinezustand erstellt, der das Schreiben in das Renderziel und den z-Puffer deaktiviert, sodass die Okklusionsabfrage selbst keine Auswirkungen auf die sichtbare Ausgabe des Renderingdurchlaufs hat.
Deaktivieren Sie in der LoadAssets-Methode Farb- und Tiefenschreibvorgänge für den Zustand der Okklusionsabfrage.
// Disable color writes and depth writes for the occlusion query's state.
psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = 0;
psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_queryState)));
Anrufverlauf | Parameter |
---|---|
D3D12_GRAPHICS_PIPELINE_STATE_DESC | D3D12_DEPTH_WRITE_MASK |
CreateGraphicsPipelineState |
Erstellen eines Puffers zum Speichern der Ergebnisse der Abfrage
In der LoadAssets-Methode muss ein Puffer erstellt werden, um die Ergebnisse der Abfrage zu speichern. Jede Abfrage benötigt 8 Bytes Speicherplatz im GPU-Arbeitsspeicher. In diesem Beispiel wird nur eine Abfrage ausgeführt, und aus Gründen der Einfachheit und Lesbarkeit wird ein Puffer genau in dieser Größe erstellt (auch wenn dieser Funktionsaufruf eine 64K-Seite GPU-Speicher zuordnet – die meisten echten Apps würden wahrscheinlich einen größeren Puffer erstellen).
// Create the query result buffer.
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_DEFAULT);
auto queryBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(8);
ThrowIfFailed(m_device->CreateCommittedResource(
&heapProps,
D3D12_HEAP_FLAG_NONE,
&queryBufferDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&m_queryResult)
));
Anrufverlauf | Parameter |
---|---|
CreateCommittedResource |
[D3D12_HEAP_TYPE] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_heap_type) [D3D12_HEAP_FLAG] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_heap_flags) [CD3DX12_RESOURCE_DESC] (cd3dx12-resource-desc.md) [D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states) |
Zeichnen Sie die Quads, und führen Sie die Okklusionsabfrage aus, und lösen Sie sie auf.
Nach dem Setup wird die Standard-Schleife in der PopulateCommandLists-Methode aktualisiert.
- 1. Zeichnen Sie die Quads von hinten nach vorne, damit der Transparenzeffekt ordnungsgemäß funktioniert. Das Zeichnen des Quads von hinten nach vorne basiert auf dem Ergebnis der Abfrage des vorherigen Frames und ist eine ziemlich gängige Technik dafür.
2. Ändern Sie den PSO, um Renderziel- und Tiefenschablonenschreibvorgänge zu deaktivieren.
3. Führen Sie die Okklusionsabfrage aus.
4. Lösen Sie die Okklusionsabfrage auf.
// Draw the quads and perform the occlusion query.
{
CD3DX12_GPU_DESCRIPTOR_HANDLE cbvFarQuad(m_cbvHeap->GetGPUDescriptorHandleForHeapStart(), m_frameIndex * CbvCountPerFrame, m_cbvSrvDescriptorSize);
CD3DX12_GPU_DESCRIPTOR_HANDLE cbvNearQuad(cbvFarQuad, m_cbvSrvDescriptorSize);
m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
// Draw the far quad conditionally based on the result of the occlusion query
// from the previous frame.
m_commandList->SetGraphicsRootDescriptorTable(0, cbvFarQuad);
m_commandList->SetPredication(m_queryResult.Get(), 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
m_commandList->DrawInstanced(4, 1, 0, 0);
// Disable predication and always draw the near quad.
m_commandList->SetPredication(nullptr, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
m_commandList->SetGraphicsRootDescriptorTable(0, cbvNearQuad);
m_commandList->DrawInstanced(4, 1, 4, 0);
// Run the occlusion query with the bounding box quad.
m_commandList->SetGraphicsRootDescriptorTable(0, cbvFarQuad);
m_commandList->SetPipelineState(m_queryState.Get());
m_commandList->BeginQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0);
m_commandList->DrawInstanced(4, 1, 8, 0);
m_commandList->EndQuery(m_queryHeap.Get(), D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0);
// Resolve the occlusion query and store the results in the query result buffer
// to be used on the subsequent frame.
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_queryResult.Get(), D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_COPY_DEST));
m_commandList->ResolveQueryData(m_queryHeap.Get(), D3D12_QUERY_TYPE_BINARY_OCCLUSION, 0, 1, m_queryResult.Get(), 0);
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_queryResult.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ));
}
Anrufverlauf | Parameter |
---|---|
CD3DX12_GPU_DESCRIPTOR_HANDLE | GetGPUDescriptorHandleForHeapStart |
IASetPrimitiveTopology | D3D_PRIMITIVE_TOPOLOGY |
IASetVertexBuffers | |
SetGraphicsRootDescriptorTable | |
SetPredication | D3D12_PREDICATION_OP |
DrawInstanced | |
SetPredication | D3D12_PREDICATION_OP |
SetGraphicsRootDescriptorTable | |
DrawInstanced | |
SetGraphicsRootDescriptorTable | |
SetPipelineState | |
BeginQuery | D3D12_QUERY_TYPE |
DrawInstanced | |
EndQuery | D3D12_QUERY_TYPE |
ResourceBarrier |
[D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states) |
ResolveQueryData | D3D12_QUERY_TYPE |
ResourceBarrier |
[D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states) |
Ausführen des Beispiels
Nicht verdeckt:
Verdeckt:
Teilweise verworren:
Zugehörige Themen