Aracılığıyla paylaş


Ö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ı 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_TYPE
[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
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)

 

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
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)

 

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
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)

 

Örneği çalıştırma

Gizli değil:

iki kutu

Gizli:

Bir kutu tamamen dolu

Kısmen dolu:

Kısmen dolu bir kutu

D3D12 Kod kılavuzu

Sorguları