Compartir a través de


Direct3D 11 en 12

D3D11On12 es un mecanismo por el que los desarrolladores pueden usar interfaces y objetos D3D11 para impulsar la API D3D12. D3D11on12 permite que los componentes escritos mediante D3D11 (por ejemplo, texto D2D y ui) funcionen junto con componentes escritos destinados a la API D3D12. D3D11on12 también permite la portabilidad incremental de una aplicación de D3D11 a D3D12, al habilitar partes de la aplicación para seguir apuntando D3D11 por motivos de simplicidad, mientras que otras tienen como destino D3D12 para el rendimiento, mientras que siempre tienen una representación completa y correcta. D3D11On12 facilita el uso de técnicas de interoperabilidad para compartir recursos y sincronizar el trabajo entre las dos API.

Inicializar D3D11On12

Para empezar a usar D3D11On12, el primer paso es crear un dispositivo D3D12 y una cola de comandos. Estos objetos se proporcionan como entrada para el método de inicialización D3D11On12CreateDevice. Puede pensar en este método como crear un dispositivo D3D11 con el tipo de controlador imaginario D3D_DRIVER_TYPE_11ON12, donde el controlador D3D11 es responsable de crear objetos y enviar listas de comandos a la API D3D12.

Después de tener un dispositivo D3D11 y un contexto inmediato, puede QueryInterface desactivar el dispositivo para la interfaz ID3D11On12Device. Esta es la interfaz principal que se usa para la interoperabilidad entre D3D11 y D3D12. Para que tanto el contexto del dispositivo D3D11 como las listas de comandos D3D12 funcionen en los mismos recursos, es necesario crear "recursos encapsulados" mediante la APIcreateWrappedResource de. Este método "promueve" un recurso D3D12 que se puede comprender en D3D11. Un recurso ajustado se inicia en el estado "adquirido", una propiedad manipulada por los métodos AcquireWrappedResources y ReleaseWrappedResources.

Uso de ejemplo

El uso típico de D3D11On12 sería usar D2D para representar texto o imágenes sobre un búfer de reserva D3D12. Consulte el ejemplo D3D11On12 para obtener código de ejemplo. Este es un esquema aproximado de los pasos que debe seguir para hacerlo:

  • Cree un dispositivo D3D12 (D3D12CreateDevice) y una cadena de intercambio D3D12 (CreateSwapChain con un ID3D12CommandQueue como entrada).
  • Cree un dispositivo D3D11On12 con el dispositivo D3D12 y la misma cola de comandos que la entrada.
  • Recupere los búferes de reserva de la cadena de intercambio y cree recursos encapsulados D3D11 para cada uno de ellos. El estado de entrada usado debe ser la última manera en que D3D12 lo usó (por ejemplo, RENDER_TARGET) y el estado de salida debe ser la forma en que D3D12 lo usará después de que D3D11 haya finalizado (por ejemplo, PRESENT).
  • Inicialice D2D y proporcione los recursos encapsulados D3D11 a D2D para prepararse para la representación.

A continuación, en cada fotograma, haga lo siguiente:

  • Represente en el búfer de retroceso de la cadena de intercambio actual mediante una lista de comandos D3D12 y ejecútelo.
  • Adquiera el recurso encapsulado del búfer de reserva actual (AcquireWrappedResources).
  • Emita comandos de representación D2D.
  • Libere el recurso ajustado (ReleaseWrappedResources).
  • Vaciar el contexto inmediato D3D11.
  • Presente (IDXGISwapChain1::P resent1).

Fondo

D3D11On12 funciona sistemáticamente. Cada llamada API D3D11 pasa por la validación típica en tiempo de ejecución y hace su camino al controlador. En la capa de controlador, el controlador especial 11on12 registra el estado y emite operaciones de representación en listas de comandos D3D12. Estas listas de comandos se envían según sea necesario (por ejemplo, una consulta GetData o recurso Map podría requerir que los comandos se vaciaran) o según lo solicite Flush. La creación de un objeto D3D11 normalmente da como resultado la creación del objeto D3D12 correspondiente. Algunas operaciones fijas de representación de funciones en D3D11, como GenerateMips o DrawAuto, no se admiten en D3D12 y, por tanto, D3D11On12 las emula mediante sombreadores y recursos adicionales.

Para la interoperabilidad, es importante comprender cómo interactúa D3D11On12 con los objetos D3D12 que la aplicación ha creado y proporcionado. Para asegurarse de que el trabajo se produce en el orden correcto, el contexto inmediato D3D11 debe vaciarse antes de que se pueda enviar un trabajo adicional de D3D12 a esa cola. También es importante asegurarse de que la cola dada a D3D11On12 debe ser purgable en todo momento. Esto significa que las esperas de la cola deben cumplirse finalmente, incluso si el subproceso D3D11 representa los bloques de subproceso indefinidamente. Tenga cuidado de no depender de cuándo D3D11On12 inserta vaciados o esperas, ya que esto puede cambiar con versiones futuras. Además, D3D11On12 realiza un seguimiento y manipula los estados de recursos por sí mismos. La única manera de garantizar la coherencia de las transiciones de estado es usar las API de adquisición o versión para manipular el seguimiento de estado para satisfacer las necesidades de la aplicación.

Limpieza

Para liberar un recurso encapsulado D3D11On12, deben producirse dos cosas en este orden:

  • Todas las referencias al recurso, incluidas las vistas del recurso, deben liberarse.
  • El procesamiento de destrucción diferida debe realizarse. La manera más sencilla de asegurarse de que esto sucede es invocar el contexto inmediato Flush API.

Una vez completados ambos pasos, las referencias realizadas por el recurso encapsulado deben liberarse y el recurso D3D12 se convierte exclusivamente en propiedad del componente D3D12. Tenga en cuenta que D3D12 todavía requiere esperar la finalización de la GPU antes de liberar completamente un recurso, por lo que asegúrese de contener una referencia en el recurso antes de realizar los dos pasos anteriores, a menos que ya haya confirmado que la GPU ya no usa el recurso.

Todos los demás recursos o objetos creados por D3D11On12 se limpiarán en el momento adecuado, cuando la GPU haya terminado de usarlas, mediante el mecanismo de destrucción diferido de D3D11. Sin embargo, si intenta liberar el propio dispositivo D3D11On12 mientras se está ejecutando la GPU, la destrucción puede bloquearse hasta que se complete la GPU.

Limitaciones

La capa D3D11On12 implementa un subconjunto muy grande de la API D3D11, pero hay algunas brechas conocidas (además de errores en la implementación que pueden provocar una representación incorrecta).

A partir de Windows 10, versión 1809 (10.0; Compilación 17763), siempre y cuando D3D11On12 se ejecute en un controlador que admita Shader Model 6.0 o posterior, puede ejecutar sombreadores que usen interfaces. En versiones anteriores de Windows, la característica de interfaces de sombreador no se implementa en D3D11On12 y al intentar usar la característica se producirán errores y mensajes de depuración.

A partir de Windows 10, versión 1803 (10.0; Compilación 17134), las cadenas de intercambio se admiten en dispositivos D3D11On12. En versiones anteriores de Windows, no lo son.

D3D11On12 no se ha optimizado para el rendimiento. Es probable que haya una sobrecarga moderada de CPU en comparación con un controlador D3D11 estándar, una sobrecarga mínima de GPU y se sabe que hay una sobrecarga significativa de memoria. Por lo tanto, no se recomienda usar D3D11On12 para escenas 3D complicadas y, en su lugar, se recomienda para escenas simples o representación 2D.

Apis

Las API que componen la capa 11on12 se describen en 11on12 Reference.

D2D mediante el tutorial D3D11on12

Understanding Direct3D 12

trabajar con Direct3D 11, Direct3D 10 y Direct2D