Bagikan melalui


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

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_TYPE
[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
CD3DX12_DEFAULT
[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
CD3DX12_HEAP_PROPERTIES
[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
CD3DX12_RESOURCE_BARRIER
[D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states)
ResolveQueryData D3D12_QUERY_TYPE
ResourceBarrier
CD3DX12_RESOURCE_BARRIER
[D3D12_RESOURCE_STATES] (/windows/desktop/api/d3d12/ne-d3d12-d3d12_resource_states)

 

Menjalankan sampel

Tidak terakludasi:

dua kotak tidak terpaku

Terakludasi:

satu kotak sepenuhnya terpaku

Sebagian okludasi:

satu kotak terpaku sebagian

Panduan Kode D3D12

Predikasi

Kueri