Compartir a través de


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

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

 

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

 

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

 

Ejecución del ejemplo

No se ocluyó:

dos cuadros no ocluidos

Ocluida:

un cuadro totalmente ocluido

Parcialmente ocluido:

un cuadro parcialmente ocluido

Tutoriales de código D3D12

Predicación

Consultas