Query di predicazione
L'esempio D3D12PredicationQueries illustra il culling dell'occlusione usando heap e predicazione di query DirectX 12. La procedura dettagliata descrive il codice aggiuntivo necessario per estendere l'esempio HelloConstBuffer per gestire le query di predicazione.
- Creare un heap del descrittore depth stencil e un heap di query di occlusione
- Abilitare la fusione alfa
- Disabilitare le scritture di colore e profondità
- Creare un buffer per archiviare i risultati della query
- Disegnare i quad ed eseguire e risolvere la query di occlusione
- Eseguire l'esempio
- Argomenti correlati
Creare un heap del descrittore depth stencil e un heap di query di occlusione
Nel metodo LoadPipeline creare un heap del descrittore depth stencil.
// 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)));
Flusso di chiamata | Parametri |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeap |
Nel metodo LoadAssets creare un heap per le query di occlusione.
// 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)));
Flusso di chiamata | Parametri |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeap |
Abilitare la fusione alfa
Questo esempio disegna due quad e illustra una query di occlusione binaria. Il quad davanti si anima sullo schermo e quello indietro occasionalmente verrà occluso. Nel metodo LoadAssets , la fusione alfa è abilitata per questo esempio in modo da poter vedere in quale punto D3D considera il quad in back occluded.
// 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,
};
Flusso di chiamata | Parametri |
---|---|
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) |
Disabilitare le scritture di colore e profondità
La query di occlusione viene eseguita eseguendo il rendering di un quad che copre la stessa area del quad di cui si vuole testare la visibilità. In scene più complesse, è probabile che la query sia un volume di delimitazione anziché un semplice quad. In entrambi i casi, viene creato un nuovo stato della pipeline che disabilita la scrittura nella destinazione di rendering e nel buffer z in modo che la query di occlusione stessa non influisca sull'output visibile del passaggio di rendering.
Nel metodo LoadAssets disabilitare le scritture a colori e le scritture di profondità per lo stato della query di occlusione.
// 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)));
Flusso di chiamata | Parametri |
---|---|
D3D12_GRAPHICS_PIPELINE_STATE_DESC | D3D12_DEPTH_WRITE_MASK |
CreateGraphicsPipelineState |
Creare un buffer per archiviare i risultati della query
Nel metodo LoadAssets è necessario creare un buffer per archiviare i risultati della query. Ogni query richiede 8 byte di spazio nella memoria GPU. Questo esempio esegue una sola query e, per semplicità e leggibilità, crea un buffer esattamente di tale dimensione (anche se questa chiamata di funzione alloca una pagina di memoria GPU di 64 KB, la maggior parte delle app reali creerebbe probabilmente un buffer più grande).
// 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)
));
Flusso di chiamata | Parametri |
---|---|
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) |
Disegnare i quad ed eseguire e risolvere la query di occlusione
Dopo aver eseguito l'installazione, il ciclo main viene aggiornato nel metodo PopulateCommandLists .
- 1. Disegnare i quad da indietro verso l'inizio per rendere l'effetto di trasparenza funziona correttamente. Il disegno del quad in fronte è predicato sul risultato della query del frame precedente ed è una tecnica abbastanza comune per questo.
2. Modificare l'oggetto PSO per disabilitare le scritture di stencil di destinazione e profondità di rendering.
3. Eseguire la query di occlusione.
4. Risolvere la query di occlusione.
// 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));
}
Flusso di chiamata | Parametri |
---|---|
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) |
Eseguire l'esempio
Non isolato:
Occlusa:
Parzialmente occluso:
Argomenti correlati