Kueri predikasi
Sampel D3D12PredicationQueries menunjukkan oklusi pemisahan menggunakan tumpukan dan predikasi kueri DirectX 12. Panduan ini menjelaskan kode tambahan yang diperlukan untuk memperluas sampel HelloConstBuffer untuk menangani kueri predikasi.
- Membuat tumpukan deskriptor stensil kedalaman dan tumpukan kueri oklusi
- Aktifkan penpaduan alfa
- Menonaktifkan penulisan warna dan kedalaman
- Membuat buffer untuk menyimpan hasil kueri
- Gambar quad dan lakukan dan atasi kueri oklusi
- Menjalankan sampel
- Topik terkait
Membuat tumpukan deskriptor stensil kedalaman dan tumpukan kueri oklusi
Dalam metode LoadPipeline , buat tumpukan deskriptor stensil kedalaman.
// 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)));
Alur panggilan | Parameter |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeap |
Dalam metode LoadAssets , buat tumpukan untuk kueri oklusi.
// 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)));
Alur panggilan | Parameter |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeap |
Aktifkan penpaduan alfa
Sampel ini menggambar dua quad dan mengilustrasikan kueri oklusi biner. Quad di depan menghidupkan di seluruh layar, dan yang ada di belakang kadang-kadang akan dihilangkan. Dalam metode LoadAssets , penpaduan alfa diaktifkan untuk sampel ini sehingga kita dapat melihat pada titik mana D3D menganggap quad di back okluded.
// 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,
};
Alur panggilan | 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) |
Menonaktifkan penulisan warna dan kedalaman
Kueri oklusi dilakukan dengan merender quad yang mencakup area yang sama dengan quad yang visibilitasnya ingin kita uji. Dalam adegan yang lebih kompleks, kueri kemungkinan akan menjadi volume pembatas, bukan quad sederhana. Dalam kedua kasus, status alur baru dibuat yang menonaktifkan penulisan ke target render dan buffer z sehingga kueri oklusi itu sendiri tidak memengaruhi output yang terlihat dari kode penyajian.
Dalam metode LoadAssets , nonaktifkan penulisan warna dan penulisan kedalaman untuk status kueri oklusi.
// 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)));
Alur panggilan | Parameter |
---|---|
D3D12_GRAPHICS_PIPELINE_STATE_DESC | D3D12_DEPTH_WRITE_MASK |
CreateGraphicsPipelineState |
Membuat buffer untuk menyimpan hasil kueri
Dalam metode LoadAssets , buffer perlu dibuat untuk menyimpan hasil kueri. Setiap kueri memerlukan ruang 8 byte dalam memori GPU. Sampel ini hanya melakukan satu kueri dan untuk kesederhanaan dan keterbacaan menciptakan buffer persis ukuran tersebut (meskipun panggilan fungsi ini akan mengalokasikan halaman memori GPU 64K - sebagian besar aplikasi nyata kemungkinan akan membuat buffer yang lebih besar).
// 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)
));
Alur panggilan | 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) |
Gambar quad dan lakukan dan atasi kueri oklusi
Setelah melakukan penyiapan, perulangan utama diperbarui dalam metode PopulateCommandLists .
- 1. Gambar quad dari belakang ke depan untuk membuat efek transparansi berfungsi dengan baik. Menggambar quad di belakang ke depan diprediksikan pada hasil kueri bingkai sebelumnya dan merupakan teknik yang cukup umum untuk ini.
2. Ubah PSO untuk menonaktifkan penulisan target render dan stensil kedalaman.
3. Lakukan kueri oklusi.
4. Atasi kueri oklusi.
// 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));
}
Alur panggilan | 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) |
Menjalankan sampel
Tidak terakludasi:
Terakludasi:
Sebagian okludasi:
Topik terkait