Partilhar via


Direct3D 11 em 12

D3D11On12 é um mecanismo pelo qual os desenvolvedores podem usar interfaces e objetos D3D11 para conduzir a API D3D12. O D3D11on12 permite que componentes escritos usando D3D11 (por exemplo, texto D2D e interface do usuário) trabalhem em conjunto com componentes escritos visando a API D3D12. O D3D11on12 também permite a portabilidade incremental de um aplicativo de D3D11 para D3D12, permitindo que partes do aplicativo continuem direcionando D3D11 para simplicidade, enquanto outros visam D3D12 para desempenho, sempre com renderização completa e correta. O D3D11On12 torna mais simples do que usar técnicas de interoperabilidade para compartilhar recursos e sincronizar o trabalho entre as duas APIs.

Inicializando o D3D11On12

Para começar a usar D3D11On12, a primeira etapa é criar um dispositivo D3D12 e uma fila de comandos. Esses objetos são fornecidos como entrada para o método de inicialização D3D11On12CreateDevice. Você pode pensar neste método como a criação de um dispositivo D3D11 com o tipo de driver imaginário D3D_DRIVER_TYPE_11ON12, onde o driver D3D11 é responsável por criar objetos e enviar listas de comandos para a API D3D12.

Depois de ter um dispositivo D3D11 e contexto imediato, você pode QueryInterface fora do dispositivo para o ID3D11On12Device interface. Esta é a interface primária usada para interoperabilidade entre D3D11 e D3D12. Para que o contexto do dispositivo D3D11 e as listas de comandos D3D12 operem nos mesmos recursos, é necessário criar "recursos encapsulados" usando a APICreateWrappedResource. Este método "promove" um recurso D3D12 para ser compreensível em D3D11. Um recurso encapsulado começa no estado "adquirido", uma propriedade que é manipulada pelosAcquireWrappedResources e métodos de ReleaseWrappedResources.

Exemplo de Utilização

O uso típico de D3D11On12 seria usar D2D para renderizar texto ou imagens em cima de um buffer traseiro D3D12. Consulte o exemplo D3D11On12 para obter um código de exemplo. Aqui está um esboço dos passos a seguir para fazê-lo:

  • Crie um dispositivo D3D12 (D3D12CreateDevice) e uma cadeia de permuta D3D12 (CreateSwapChain com um ID3D12CommandQueue como entrada).
  • Crie um dispositivo D3D11On12 usando o dispositivo D3D12 e a mesma fila de comandos como entrada.
  • Recupere os buffers de retorno da cadeia de permuta e crie recursos encapsulados D3D11 para cada um deles. O estado de entrada usado deve ser a última maneira que D3D12 o usou (por exemplo, RENDER_TARGET) e o estado de saída deve ser a maneira que D3D12 irá usá-lo após D3D11 ter terminado (por exemplo, PRESENT).
  • Inicialize o D2D e forneça os recursos encapsulados do D3D11 ao D2D para preparar a renderização.

Em seguida, em cada quadro, faça o seguinte:

Contexto geral

O D3D11On12 funciona sistematicamente. Cada chamada de API D3D11 passa pela validação de tempo de execução típica e chega ao driver. Na camada de driver, o driver especial 11on12 registra o estado e emite operações de renderização para listas de comandos D3D12. Essas listas de comandos são enviadas conforme necessário (por exemplo, um GetData de consulta ou Map de recursos pode exigir que os comandos sejam liberados) ou conforme solicitado pelo Flush. A criação de um objeto D3D11 normalmente resulta na criação do objeto D3D12 correspondente. Algumas operações de renderização de função fixa em D3D11, como GenerateMips ou DrawAuto, não são suportadas em D3D12 e, portanto, D3D11On12 as emula usando sombreadores e recursos adicionais.

Para interoperabilidade, é importante entender como o D3D11On12 interage com os objetos D3D12 que o aplicativo criou e forneceu. Para garantir que o trabalho aconteça na ordem correta, o contexto imediato D3D11 deve ser liberado antes que o trabalho D3D12 adicional possa ser enviado para essa fila. Também é importante garantir que a fila dada ao D3D11On12 deve ser drenável em todos os momentos. Isso significa que qualquer espera na fila deve eventualmente ser satisfeita, mesmo que o D3D11 renderize blocos de thread indefinidamente. Desconfie para não depender de quando o D3D11On12 insere flushes ou espera, pois isso pode mudar com versões futuras. Além disso, o D3D11On12 rastreia e manipula estados de recursos por conta própria. A única maneira de garantir a coerência das transições de estado é usar as APIs de aquisição/liberação para manipular o rastreamento de estado para atender às necessidades do aplicativo.

Limpeza

Para liberar um recurso encapsulado D3D11On12, duas coisas precisam acontecer nesta ordem:

  • Todas as referências ao recurso, incluindo quaisquer visualizações do recurso, precisam ser liberadas.
  • Deve ser efetuado um tratamento diferido da destruição. A maneira mais simples de garantir que isso aconteça é invocar o contexto imediato Flush API.

Depois que ambas as etapas forem concluídas, todas as referências feitas pelo recurso encapsulado deverão ser liberadas e o recurso D3D12 se tornará de propriedade exclusiva do componente D3D12. Lembre-se de que o D3D12 ainda requer aguardar a conclusão da GPU antes de liberar completamente um recurso, portanto, certifique-se de manter uma referência sobre o recurso antes de executar as duas etapas acima, a menos que você já tenha confirmado que a GPU não está mais usando o recurso.

Todos os outros recursos ou objetos criados pelo D3D11On12 serão limpos no momento apropriado, quando a GPU terminar de usá-los, usando o mecanismo de destruição diferida do D3D11. No entanto, se você tentar liberar o próprio dispositivo D3D11On12 enquanto a GPU ainda está em execução, a destruição pode bloquear até que a GPU seja concluída.

Limitações

A camada D3D11On12 implementa um subconjunto muito grande da API D3D11, mas existem algumas lacunas conhecidas (além de bugs na implementação que podem causar renderização incorreta).

A partir do Windows 10, versão 1809 (10.0; Build 17763), desde que o D3D11On12 esteja sendo executado em um driver que suporte Shader Model 6.0 ou posterior, ele pode executar sombreadores que usam interfaces. Em versões anteriores do Windows, o recurso de interfaces de sombreador não é implementado no D3D11On12, e tentar usar o recurso causará erros e mensagens de depuração.

A partir do Windows 10, versão 1803 (10.0; Build 17134), as cadeias de permuta são suportadas em dispositivos D3D11On12. Em versões anteriores do Windows, eles não são.

O D3D11On12 não foi otimizado para desempenho. Provavelmente haverá sobrecarga moderada da CPU em comparação com um driver D3D11 padrão, sobrecarga mínima da GPU e sabe-se que há uma sobrecarga de memória significativa. Portanto, não é recomendado usar D3D11On12 para cenas 3D complicadas e, em vez disso, é recomendado para cenas simples ou renderização 2D.

APIs

As APIs que compõem a camada 11on12 são descritas em de referência 11on12.

D2D usando o passo a passo D3D11on12

Noções básicas sobre o Direct3D 12

Trabalhando com Direct3D 11, Direct3D 10 e Direct2D