Vorababfragen
Das D3D12PredicationQueries Beispiel veranschaulicht die Okklusions-Culling mithilfe von DirectX 12-Abfrage heaps und -prädication. In der exemplarischen Vorgehensweise wird der zusätzliche Code beschrieben, der zum Erweitern des HelloConstBuffer- Beispiels zur Behandlung von Vorababfragen erforderlich ist.
- Erstellen eines Tiefenschablonendeskriptor-Heaps und eines Okklusionsabfrage-Heaps
- Aktivieren der Alphamischung
- Farb- und Tiefenschreibvorgänge deaktivieren
- Erstellen eines Puffers zum Speichern der Ergebnisse der Abfrage
- Zeichnen der Quads und Ausführen und Auflösen der Okklusionsabfrage
- Ausführen des Beispiel-
- Verwandte Themen
Erstellen eines Tiefenschablonendeskriptor-Heaps und eines Heaps für okklusionsabfragen
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)));
Anruffluss | Parameter |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG](/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeap- |
Erstellen Sie im 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)));
Anruffluss | Parameter |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeap- |
Aktivieren der Alphamischung
In diesem Beispiel werden zwei Quads gezeichnet und eine binäre Okklusionsabfrage veranschaulicht. Das Quad vorn wird über den Bildschirm animiert, und die in der Rückseite wird gelegentlich verdeckt. In der LoadAssets-Methode ist die Alphamischung für dieses Beispiel aktiviert, sodass wir sehen können, an welchem Punkt D3D das Quad im Hintergrund 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,
};
Anruffluss | 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 ausgeführt, indem ein Quad gerendert wird, das denselben Bereich wie das Quad abdeckt, dessen Sichtbarkeit wir testen möchten. In komplexeren Szenen wäre die Abfrage wahrscheinlich ein Begrenzungsvolumen anstelle eines einfachen Quads. In beiden Fällen wird ein neuer Pipelinestatus erstellt, der das Schreiben in das Renderziel und den Z-Puffer deaktiviert, sodass sich die Okklusionsabfrage selbst nicht auf die sichtbare Ausgabe des Renderingdurchlaufs auswirkt.
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)));
Anruffluss | 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 Byte Speicherplatz im GPU-Speicher. In diesem Beispiel wird nur eine Abfrage ausgeführt, und aus Gründen der Einfachheit und Lesbarkeit wird ein Puffer genau dieser Größe erstellt (auch wenn dieser Funktionsaufruf eine 64K-Seite des GPU-Speichers zuweist – 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)
));
Anruffluss | 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 Der Quads und Ausführen und Auflösen der Okklusionsabfrage
Nach Abschluss des Setups wird die Hauptschleife in der PopulateCommandLists-Methode aktualisiert.
- 1. Zeichnen Sie die Quads von hinten nach vorne, damit der Transparenzeffekt ordnungsgemäß funktioniert. Das Zeichnen des Quads in den Vordergrund wird auf das Ergebnis der Abfrage des vorherigen Frames prädiziert und ist dafür eine ziemlich häufige Technik.
2. Ändern Sie die PSO, um Renderziel- und Tiefenschablonenschreibvorgänge zu deaktivieren.
3. Ausführen der Okklusionsabfrage.
4. Auflösen der Okklusionsabfrage.
// 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));
}
Anruffluss | 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 verdeckt:
Verwandte Themen