Consultas de predicación
El ejemplo D3D12PredicationQueries muestra la selección de oclusión mediante montones y predicación de consultas de DirectX 12. En el tutorial se describe el código adicional necesario para ampliar el ejemplo de HelloConstBuffer para controlar las consultas de predicación.
- Crear un montón de descriptores de galería de símbolos de profundidad y un montón de consultas de oclusión
- Habilitar de combinación alfa
- Deshabilitar escrituras de color y profundidad
- Crear un búfer para almacenar los resultados de la consulta
- Dibujar los quads y realizar y resolver la consulta de oclusión
- Ejecutar el de ejemplo
- temas relacionados
Creación de un montón de descriptores de galería de símbolos de profundidad y un montón de consultas de oclusión
En el método LoadPipeline, cree un montón de descriptores de galería de símbolos de profundidad.
// 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)));
Flujo de llamadas | Parámetros |
---|---|
D3D12_DESCRIPTOR_HEAP_DESC |
[D3D12_DESCRIPTOR_HEAP_FLAG](/windows/desktop/api/d3d12/ne-d3d12-d3d12_descriptor_heap_flags) |
CreateDescriptorHeap |
En el método LoadAssets, cree un montón para las consultas de oclusión.
// 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)));
Flujo de llamadas | Parámetros |
---|---|
D3D12_QUERY_HEAP_DESC | D3D12_QUERY_HEAP_TYPE |
CreateQueryHeap |
Habilitación de la combinación alfa
En este ejemplo se dibujan dos cuadrantes y se muestra una consulta de oclusión binaria. El quad en el frente anima a través de la pantalla, y el de atrás se ocluye ocasionalmente. En el método de LoadAssets, la combinación alfa está habilitada para este ejemplo para que podamos ver en qué punto D3D considera el cuádular en la parte posterior ocluida.
// 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,
};
Flujo de llamadas | Parámetros |
---|---|
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) |
Deshabilitar escrituras de color y profundidad
La consulta de oclusión se realiza mediante la representación de un quad que cubre el mismo área que el quad cuya visibilidad queremos probar. En escenas más complejas, es probable que la consulta sea un volumen delimitador, en lugar de un quad simple. En cualquier caso, se crea un nuevo estado de canalización que deshabilita la escritura en el destino de representación y el búfer z para que la propia consulta de oclusión no afecte a la salida visible del paso de representación.
En el método LoadAssets, deshabilite las escrituras de color y las escrituras de profundidad para el estado de la consulta de oclusió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)));
Flujo de llamadas | Parámetros |
---|---|
D3D12_GRAPHICS_PIPELINE_STATE_DESC | D3D12_DEPTH_WRITE_MASK |
CreateGraphicsPipelineState |
Creación de un búfer para almacenar los resultados de la consulta
En el método LoadAssets se debe crear un búfer para almacenar los resultados de la consulta. Cada consulta requiere 8 bytes de espacio en la memoria de GPU. Este ejemplo solo realiza una consulta y, por motivos de simplicidad y legibilidad, crea un búfer exactamente ese tamaño (aunque esta llamada de función asignará una página de 64 0000 de memoria gpu; la mayoría de las aplicaciones reales probablemente crearían un búfer mayor).
// 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)
));
Flujo de llamadas | Parámetros |
---|---|
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) |
Dibujar los quads y realizar y resolver la consulta de oclusión
Después de realizar la instalación, el bucle principal se actualiza en el método PopulateCommandLists.
- 1. Dibuje los quads de atrás a delante para que el efecto de transparencia funcione correctamente. Dibujar el quad de vuelta hacia delante se basa en el resultado de la consulta del marco anterior y es una técnica bastante común para esto.
2. Cambie el ARCHIVO PARA deshabilitar las escrituras de la galería de símbolos de profundidad y destino de representación.
3. Realice la consulta de oclusión.
4. Resuelva la consulta de oclusió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));
}
Flujo de llamadas | Parámetros |
---|---|
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 de | 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) |
Ejecución del ejemplo
No se ocluyó:
Ocluida:
Parcialmente ocluida:
Temas relacionados