Compartilhar via


Direct3D 11 em 12

D3D11On12 é um mecanismo pelo qual os desenvolvedores podem usar interfaces E objetos D3D11 para conduzir a API D3D12. D3D11on12 permite que os componentes gravados usando D3D11 (por exemplo, texto D2D e interface do usuário) trabalhem em conjunto com componentes gravados 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 simplificar, enquanto outras visam D3D12 para desempenho, ao mesmo tempo em que sempre têm renderização completa e correta. D3D11On12 torna mais simples do que usar técnicas de interoperabilidade para compartilhar recursos e sincronizar o trabalho entre as duas APIs.

Inicializando 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 nesse método como criar um dispositivo D3D11 com o tipo de driver imaginário D3D_DRIVER_TYPE_11ON12, em que o driver D3D11 é responsável por criar objetos e enviar listas de comandos para a API D3D12.

Depois de ter um dispositivo D3D11 e um contexto imediato, você pode QueryInterface fora do dispositivo para a interfaceID3D11On12Device do. Essa é 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 API CreateWrappedResource. Esse método "promove" um recurso D3D12 para ser compreensível na D3D11. Um recurso encapsulado começa no estado "adquirido", uma propriedade manipulada pelos métodos AcquireWrappedResources e ReleaseWrappedResources.

Uso de exemplo

O uso típico de D3D11On12 seria usar D2D para renderizar texto ou imagens em cima de um buffer de back D3D12. Consulte o exemplo D3D11On12 para obter o código de exemplo. Aqui está uma estrutura de tópicos aproximada das etapas a serem tomadas para fazer isso:

  • Crie um dispositivo D3D12 (D3D12CreateDevice) e uma cadeia de troca D3D12 (CreateSwapChain com um ID3D12CommandQueue como entrada).
  • Crie um dispositivo D3D11On12 usando o dispositivo D3D12 e a mesma fila de comandos que a entrada.
  • Recupere os buffers de back da cadeia de troca e crie recursos encapsulados em D3D11 para cada um deles. O estado de entrada usado deve ser a última maneira que d3D12 usou (por exemplo, RENDER_TARGET) e o estado de saída deve ser a maneira como D3D12 o usará após a conclusão do D3D11 (por exemplo, PRESENT).
  • Inicialize d2D e forneça os recursos encapsulados D3D11 para D2D para se preparar para renderização.

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

Fundo

D3D11On12 funciona sistematicamente. Cada chamada à API D3D11 passa pela validação típica de runtime e chega ao driver. Na camada de driver, o driver 11on12 especial 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, uma consulta GetData 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 têm suporte na D3D12 e, portanto, D3D11On12 as emula usando sombreadores e recursos adicionais.

Para interoperabilidade, é importante entender como D3D11On12 interage com os objetos D3D12 que o aplicativo criou e forneceu. Para garantir que o trabalho ocorra 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 fornecida a D3D11On12 seja drenável o tempo todo. Isso significa que todas as esperas na fila devem eventualmente ser atendidas, mesmo que o thread de renderização D3D11 seja bloqueado indefinidamente. Tenha cuidado para não depender de quando D3D11On12 insere liberações ou esperas, pois isso pode mudar com versões futuras. Além disso, 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/versão para manipular o acompanhamento 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 exibições do recurso, precisam ser liberadas.
  • O processamento de destruição adiada deve ocorrer. 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á exclusivamente de propriedade do componente D3D12. Lembre-se de que o D3D12 ainda requer aguardar a conclusão da GPU antes de liberar completamente um recurso, portanto, mantenha uma referência no 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 por D3D11On12 serão limpos no momento apropriado, quando a GPU terminar de usá-los, usando o mecanismo de destruição adiada da D3D11. No entanto, se você tentar liberar o próprio dispositivo D3D11On12 enquanto a GPU ainda estiver em execução, a destruição poderá ser bloqueada até que a GPU seja concluída.

Limitações

A camada D3D11On12 implementa um subconjunto muito grande da API D3D11, mas há 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 D3D11On12 esteja em execução em um driver que dê suporte ao Sombreador Modelo 6.0 ou posterior, ele poderá executar sombreadores que usam interfaces. Nas versões anteriores do Windows, o recurso de interfaces de sombreador não é implementado em 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 troca têm suporte em dispositivos D3D11On12. Em versões anteriores do Windows, elas não são.

D3D11On12 não foi otimizado para desempenho. Provavelmente haverá uma sobrecarga de CPU moderada em comparação com um driver D3D11 padrão, sobrecarga mínima de GPU, e sabe-se que há uma sobrecarga significativa de memória. Portanto, não é recomendável 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 no 11on12 Reference.

D2D usando passo a passo D3D11on12

noções básicas sobre o Direct3D 12

trabalhando com Direct3D 11, Direct3D 10 e Direct2D