조건자 쿼리
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 |
알파 혼합 사용
이 샘플에서는 두 개의 쿼드를 그리고 이진 폐색 쿼리를 보여 줍니다. 앞의 쿼드는 화면에 애니메이션 효과를 주며, 뒤쪽에 있는 쿼드는 때때로 폐색됩니다. 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바이트의 공간이 필요합니다. 이 샘플은 하나의 쿼리만 수행하고 단순성과 가독성을 위해 정확히 해당 크기의 버퍼를 만듭니다(이 함수 호출은 GPU 메모리의 64K 페이지를 할당하더라도 대부분의 실제 앱은 더 큰 버퍼를 만들 수 있습니다).
// 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) |
샘플 실행
폐색되지 않음:
폐색:
한 상자가 완전히 폐색된
부분적으로 폐색:
한 상자가 부분적으로 폐색된
관련 항목