Consultas de predicación
En el ejemplo D3D12PredicationQueries se muestra la selección de oclusión mediante montones de consulta y predicación de DirectX 12. En el tutorial se describe el código adicional necesario para ampliar el ejemplo HelloConstBuffer para controlar las consultas de predicación.
- 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
- Habilitación de la combinación alfa
- Deshabilitar escrituras de color y profundidad
- Creación de un búfer para almacenar los resultados de la consulta
- Dibujar los cuadrantes y realizar y resolver la consulta de oclusión
- Ejecución del 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 frente anima a través de la pantalla, y el de atrás se oscribirá ocasionalmente. En el método LoadAssets , la combinación alfa está habilitada para este ejemplo para que podamos ver en qué punto D3D considera que el quad en la parte posterior está 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 cuadrante que cubre el mismo área que el cuadrángulo cuya visibilidad queremos probar. En escenas más complejas, es probable que la consulta sea un volumen delimitador, en lugar de un cuadrángulo 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 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 a 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 más grande).
// 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 cuadrantes 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 cuadrantes de atrás hacia delante para que el efecto de transparencia funcione correctamente. Dibujar el cuadrángulo hacia atrás hacia delante se basa en el resultado de la consulta del fotograma anterior y es una técnica bastante común para esto.
2. Cambie el ARCHIVO PARA deshabilitar las escrituras de 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 | |
BeginEvent | 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) |
Ejecución del ejemplo
No se ocluyó:
Ocluida:
Parcialmente ocluido:
Temas relacionados