Ön koşul sorguları
D3D12PredicationQueries örneği, DirectX 12 sorgu yığınlarını ve çoğaltmayı kullanarak tıkanıklık toplamayı gösterir. İzlenecek yol, HelloConstBuffer örneğini çoğaltma sorgularını işlemek için genişletmek için gereken ek kodu açıklar.
- Derinlik kalıbı tanımlayıcısı yığını ve bir okluzyon sorgu yığını oluşturma
- Alfa karıştırmayı etkinleştirme
- Renk ve derinlik yazma devre dışı bırakma
- Sorgu sonuçlarını depolamak için arabellek oluşturma
- Dörtlüleri çizin ve tıkanıklık sorgusunu gerçekleştirin ve çözün
- Örnek çalıştırma
- İlgili konular
Derinlik kalıbı tanımlayıcı yığını ve bir tıkanıklık sorgu yığını oluşturma
LoadPipeline yönteminde bir derinlik kalıbı tanımlayıcı yığını oluşturun.
// 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)));
Çağrı akışı | Parametre |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG](/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeap |
LoadAssets yönteminde, tıkanıklık sorguları için bir yığın oluşturun.
// 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)));
Çağrı akışı | Parametre |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeap |
Alfa karıştırmayı etkinleştirme
Bu örnek iki dörtlü çizer ve ikili bir okluzyon sorgusunu gösterir. Öndeki dörtlü ekran boyunca animasyon ekler ve arkadaki zaman zaman tıkanacaktır. LoadAssets yönteminde, D3D'nin arkadaki dörtlüye hangi noktada göz attığını görebilmek için bu örnek için alfa karıştırma etkinleştirilir.
// 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,
};
Çağrı akışı | Parametre |
---|---|
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) |
Renk ve derinlik yazmalarını devre dışı bırakma
Tıkanıklık sorgusu, görünürlüğünü test etmek istediğimiz dörtlüyle aynı alanı kapsayan bir dörtlü işlenerek gerçekleştirilir. Daha karmaşık sahnelerde, sorgu büyük olasılıkla basit dörtlü yerine sınırlayıcı bir birim olacaktır. Her iki durumda da, işleme hedefine ve z arabelleğine yazmayı devre dışı bırakabilen yeni bir işlem hattı durumu oluşturulur, böylece kapatma sorgusunun kendisi işleme geçişinin görünür çıkışını etkilemez.
LoadAssets yönteminde, kapatma sorgusunun durumu için renk yazma ve derinlik yazmalarını devre dışı bırakın.
// 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)));
Çağrı akışı | Parametre |
---|---|
D3D12_GRAPHICS_PIPELINE_STATE_DESC | D3D12_DEPTH_WRITE_MASK |
CreateGraphicsPipelineState |
Sorgunun sonuçlarını depolamak için arabellek oluşturma
LoadAssets yönteminde sorgunun sonuçlarını depolamak için bir arabellek oluşturulması gerekir. Her sorgu gpu belleğinde 8 bayt alan gerektirir. Bu örnek yalnızca bir sorgu gerçekleştirir ve kolaylık ve okunabilirlik için tam olarak bu boyutta bir arabellek oluşturur (bu işlev çağrısı bir 64K GPU belleği sayfası ayıracak olsa da, çoğu gerçek uygulama büyük olasılıkla daha büyük bir arabellek oluşturur).
// 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)
));
Çağrı akışı | Parametre |
---|---|
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) |
Dörtlüleri çizin ve okluzyon sorgusunu gerçekleştirin ve çözün
Kurulumu tamamladıktan sonra ana döngü PopulateCommandLists yönteminde güncelleştirilir.
- 1. Saydamlık efektinin düzgün çalışmasını sağlamak için dörtlüleri arkadan öne doğru çekin. Dörtlünün arkaya doğru çizilmiş olması, önceki çerçevenin sorgusunun sonucuna göre belirlenir ve bunun için oldukça yaygın bir tekniktir.
2. İşleme hedefi ve derinlik kalıbı yazmalarını devre dışı bırakmak için PSO'yu değiştirin.
3. Gizli sorguyu gerçekleştirin.
4. Gizli sorguyu çözün.
// 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));
}
Çağrı akışı | Parametre |
---|---|
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) |
Örneği çalıştırma
Gizli değil:
Gizli:
Bir kutu tamamen dolu
Kısmen dolu:
Kısmen dolu bir kutu
İlgili konular