Predication クエリ
D3D12PredicationQueries サンプルでは、DirectX 12 クエリ ヒープとプリディケーションを使用したオクルージョン カリングを示します。 このチュートリアルでは、プレディケーション クエリを処理するために HelloConstBuffer サンプルを拡張するために必要な追加のコードについて説明します。
- 深度ステンシル記述子ヒープとオクルージョン クエリ ヒープを作成
- アルファ ブレンド を有効にする
- 色と深度の書き込みを無効にする
- クエリ の結果を格納するバッファーを作成する
- クワッドを描画し、オクルージョン クエリを実行して解決
- サンプル を実行する
- 関連トピック
深度ステンシル記述子ヒープとオクルージョン クエリ ヒープを作成する
LoadPipeline メソッドで深度ステンシル記述子ヒープを作成します。
// 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)));
通話フロー | パラメーター |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG](/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeapの |
LoadAssets メソッドで、オクルージョン クエリ用のヒープを作成します。
// 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)));
通話フロー | パラメーター |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeapの |
アルファ ブレンドを有効にする
このサンプルでは、2 つのクワッドを描画し、バイナリ オクルージョン クエリを示します。 前面のクワッドは画面全体でアニメーション化され、後ろのクワッドが隠されることがあります。 LoadAssets メソッドでは、このサンプルに対してアルファ ブレンドが有効になっているため、D3D がバック オクルードでクワッドと見なすポイントを確認できます。
// 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,
};
通話フロー | パラメーター |
---|---|
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) |
色と深度の書き込みを無効にする
オクルージョン クエリは、可視性をテストするクワッドと同じ領域をカバーするクワッドをレンダリングすることによって実行されます。 より複雑なシーンでは、クエリは単純なクワッドではなく境界ボリュームである可能性があります。 どちらの場合も、オクルージョン クエリ自体がレンダリング パスの表示出力に影響を与えないように、レンダー ターゲットと z バッファーへの書き込みを無効にする新しいパイプライン状態が作成されます。
LoadAssets メソッドで、オクルージョン クエリの状態に対するカラー書き込みと深度書き込みを無効にします。
// 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)));
通話フロー | パラメーター |
---|---|
D3D12_GRAPHICS_PIPELINE_STATE_DESC | D3D12_DEPTH_WRITE_MASK |
CreateGraphicsPipelineStateの |
クエリの結果を格納するバッファーを作成する
LoadAssets メソッドでは、クエリの結果を格納するためにバッファーを作成する必要があります。 各クエリには、GPU メモリに 8 バイトの領域が必要です。 このサンプルでは、1 つのクエリのみを実行し、わかりやすく、読みやすくするために、正確にそのサイズのバッファーが作成されます (この関数呼び出しでは 64K ページの GPU メモリが割り当てられますが、ほとんどの実際のアプリではより大きなバッファーが作成される可能性があります)。
// 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)
));
通話フロー | パラメーター |
---|---|
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) |
クワッドを描画し、オクルージョン クエリを実行して解決する
セットアップが完了すると、メイン ループが PopulateCommandLists メソッドで更新されます。
- 1. クワッドを背面から前面に描画して、透明度効果を適切に動作させます。 四角形を前面に描画することは、前のフレームのクエリの結果に基づいて行われ、これは非常に一般的な手法です。
2. PSO を変更して、レンダー ターゲットと深度ステンシルの書き込みを無効にします。
3. オクルージョン クエリを実行します。
4. オクルージョン クエリを解決します。
// 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));
}
通話フロー | パラメーター |
---|---|
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) |
サンプルを実行する
隠されていない:
する
閉塞:
1 つのボックス
部分的に隠されている:
部分的に隠されたボックスを 1 つ
関連トピック