Share via


Cambios importantes en Direct3D 12 respecto de Direct3D 11

Direct3D 12 representa una salida significativa del modelo de programación de Direct3D 11. Direct3D 12 permite que las aplicaciones se acerquen al hardware que nunca. Al estar más cerca del hardware, Direct3D 12 es más rápido y eficaz. Pero el equilibrio de la aplicación con una mayor velocidad y eficiencia con Direct3D 12 es que eres responsable de más tareas de las que estabas con Direct3D 11.

Direct3D 12 es un retorno a la programación de bajo nivel; proporciona más control sobre los elementos gráficos de los juegos y las aplicaciones mediante la introducción de estas nuevas características: objetos para representar el estado general de la canalización, listas de comandos y agrupaciones para el envío de trabajo, y montones de descriptores y tablas para el acceso a recursos.

Tu aplicación ha aumentado la velocidad y eficiencia con Direct3D 12, pero eres responsable de más tareas de las que estabas con Direct3D 11.

Sincronización explícita

  • En Direct3D 12, la sincronización de CPU-GPU es ahora la responsabilidad explícita de la aplicación y ya no la realiza implícitamente el tiempo de ejecución, ya que está en Direct3D 11. Este hecho también significa que Direct3D 12 no realiza ninguna comprobación automática de los peligros de la canalización, por lo que esta es la responsabilidad de las aplicaciones.
  • En Direct3D 12, las aplicaciones son responsables de las actualizaciones de datos de canalización. Es decir, el patrón "Map/Lock-DISCARD" de Direct3D 11 debe realizarse manualmente en Direct3D 12. En Direct3D 11, si la GPU sigue usando el búfer al llamar a ID3D11DeviceContext::Map con D3D11_MAP_WRITE_DISCARD, el tiempo de ejecución devuelve un puntero a una nueva región de memoria en lugar de los datos antiguos del búfer. Esto permite que la GPU siga usando los datos antiguos mientras la aplicación coloca los datos en el nuevo búfer. No se requiere ninguna administración de memoria adicional en la aplicación; el búfer antiguo se reutiliza o se destruye automáticamente cuando la GPU finaliza con él.
  • En Direct3D 12, todas las actualizaciones dinámicas (incluidos los búferes de constantes, los búferes de vértices dinámicos, las texturas dinámicas, etc.) se controlan explícitamente mediante la aplicación. Estas actualizaciones dinámicas incluyen las barreras de GPU o el almacenamiento en búfer necesarios. La aplicación es responsable de mantener la memoria disponible hasta que ya no sea necesaria.
  • Direct3D 12 usa el recuento de referencias de estilo COM solo para la duración de las interfaces (mediante el modelo de referencia débil de Direct3D vinculado a la duración del dispositivo). Todas las duraciones de memoria de recursos y de descripción son la única responsable de la aplicación que se mantiene durante el tiempo adecuado y no se cuentan las referencias. Direct3D 11 usa el recuento de referencias para administrar también las duraciones de las dependencias de interfaz.

Administración de residencia de memoria física

Una aplicación de Direct3D 12 debe evitar condiciones de carrera entre varias colas, varios adaptadores y los subprocesos de CPU. D3D12 ya no sincroniza la CPU y la GPU, ni admite mecanismos cómodos para cambiar el nombre de recursos o el almacenamiento en búfer múltiple. Se deben usar barreras para evitar que varias unidades de procesamiento sobreescriba la memoria antes de que otra unidad de procesamiento termine de usarla.

La aplicación Direct3D 12 debe asegurarse de que los datos residen en la memoria mientras la GPU la lee. La memoria utilizada por cada objeto se convierte en residente durante la creación del objeto . Las aplicaciones que llaman a estos métodos deben usar barreras para asegurarse de que la GPU no tiene acceso a los objetos que se han expulsado.

Las barreras de recursos son otro tipo de sincronización necesaria, que se usa para sincronizar las transiciones de recursos y subrecursos en un nivel muy granular.

Consulte Administración de memoria en Direct3D 12.

Objetos de estado de canalización

Direct3D 11 permite la manipulación del estado de la canalización a través de un gran conjunto de objetos independientes. Por ejemplo, el estado del ensamblador de entrada, el estado del sombreador de píxeles, el estado de rasterizador y el estado de fusión de salida se pueden modificar de forma independiente. Este diseño proporciona una representación cómoda y relativamente alta de la canalización de gráficos, pero no utiliza las funcionalidades del hardware moderno, principalmente porque los distintos estados suelen ser interdependientes. Por ejemplo, muchas GPU combinan el sombreador de píxeles y el estado de fusión de salida en una sola representación de hardware. Sin embargo, dado que la API de Direct3D 11 permite establecer estas fases de canalización por separado, el controlador de pantalla no puede resolver los problemas del estado de la canalización hasta que se finalice el estado, lo que no es hasta el tiempo de dibujo. Este esquema retrasa la configuración del estado de hardware, lo que significa sobrecarga adicional y menos llamadas de dibujo máximas por fotograma.

Direct3D 12 aborda este esquema mediante la unificación de gran parte del estado de la canalización en objetos de estado de canalización inmutables (PSO), que se finalizan al crearse. A continuación, el hardware y los controladores pueden convertir inmediatamente el ARCHIVO EN cualquier instrucción nativa de hardware y estado necesarios para ejecutar el trabajo de GPU. Todavía se puede cambiar dinámicamente el ARCHIVO que está en uso, pero para ello, el hardware solo necesita copiar la cantidad mínima de estado preprocesado directamente en los registros de hardware, en lugar de calcular el estado de hardware sobre la marcha. Mediante el uso de PSO, la sobrecarga de llamadas de dibujo se reduce significativamente y muchas más llamadas de dibujo se pueden producir por fotograma. Para obtener más información sobre las SPO, consulta Administración del estado de canalización de gráficos en Direct3D 12.

Listas de comandos y agrupaciones

En Direct3D 11, todo el envío de trabajo se realiza a través del contexto inmediato, que representa una única secuencia de comandos que van a la GPU. Para lograr el escalado multiproceso, los juegos también tienen contextos diferidos disponibles para ellos. Los contextos diferidos en Direct3D 11 no se asignan perfectamente al hardware, por lo que se puede realizar relativamente poco trabajo en ellos.

Direct3D 12 presenta un nuevo modelo para el envío de trabajo basado en listas de comandos que contienen toda la información necesaria para ejecutar una carga de trabajo determinada en la GPU. Cada nueva lista de comandos contiene información como la que SE va a usar, qué recursos de textura y búfer son necesarios, y los argumentos para todas las llamadas a draw. Dado que cada lista de comandos es independiente y no hereda ningún estado, el controlador puede calcular previamente todos los comandos de GPU necesarios por adelantado y de forma sin subprocesos. El único proceso en serie necesario es el envío final de listas de comandos a la GPU a través de la cola de comandos.

Además de las listas de comandos, Direct3D 12 también presenta un segundo nivel de cálculo previo del trabajo: agrupaciones. A diferencia de las listas de comandos, que son completamente independientes y normalmente se construyen, envían una vez y descartan, los conjuntos proporcionan una forma de herencia de estado que permite la reutilización. Por ejemplo, si un juego quiere dibujar dos modelos de personajes con texturas diferentes, un enfoque consiste en grabar una lista de comandos con dos conjuntos de llamadas de dibujo idénticas. Pero otro enfoque consiste en "grabar" una agrupación que dibuja un modelo de un solo carácter y, a continuación, "reproducir" la agrupación dos veces en la lista de comandos con recursos diferentes. En este último caso, el controlador de pantalla solo tiene que calcular las instrucciones adecuadas una vez y crear la lista de comandos básicamente equivale a dos llamadas de función de bajo costo.

Para obtener más información sobre las listas de comandos y las agrupaciones, consulta Envío de trabajo en Direct3D 12.

Montones de descriptores y tablas

El enlace de recursos en Direct3D 11 es muy abstracto y conveniente, pero deja muchas funcionalidades de hardware modernas infrautilizadas. En Direct3D 11, los juegos crean objetos de vista de recursos y luego enlazan esas vistas a varias ranuras en varias fases del sombreador de la canalización. Los sombreadores, a su vez, leen datos de esas ranuras de enlace explícitas, que se fijan en tiempo de dibujo. Este modelo significa que cada vez que un juego dibujará con diferentes recursos, debe volver a enlazar vistas diferentes a diferentes ranuras y llamar a draw de nuevo. Este caso también representa la sobrecarga que se puede eliminar mediante el uso completo de las funcionalidades de hardware modernas.

Direct3D 12 cambia el modelo de enlace para que coincida con el hardware moderno y mejora significativamente el rendimiento. En lugar de requerir vistas de recursos independientes y asignación explícita a ranuras, Direct3D 12 proporciona un montón de descriptores en el que los juegos crean sus distintas vistas de recursos. Este esquema proporciona un mecanismo para que la GPU escriba directamente la descripción de recursos nativos de hardware (descriptor) en la memoria por adelantado. Para declarar qué recursos va a usar la canalización para una llamada de dibujo determinada, los juegos especifican una o varias tablas descriptores que representan sub rangos del montón de descriptores completo. Dado que el montón de descriptores ya se ha rellenado con los datos de descriptor específicos del hardware adecuados, el cambio de las tablas de descriptores es una operación extremadamente de bajo costo.

Además del rendimiento mejorado que ofrecen los montones de descriptores y las tablas, Direct3D 12 también permite que los recursos se indexan dinámicamente en sombreadores, lo que proporciona flexibilidad sin precedentes y desbloquea nuevas técnicas de representación. Por ejemplo, los motores de representación aplazados modernos suelen codificar un identificador de material o objeto de algún tipo en el búfer g intermedio. En Direct3D 11, estos motores deben tener cuidado de evitar el uso de demasiados materiales, ya que incluir demasiados en un búfer g puede ralentizar significativamente el paso de representación final. Con recursos indexables dinámicamente, una escena con mil materiales se puede finalizar tan rápidamente como una con solo diez.

Para obtener más información sobre los montones de descriptores y las tablas, vea Enlace de recursos y Diferencias en el modelo de enlace de Direct3D 11.

Migración desde Direct3D 11

La migración desde Direct3D 11 es un proceso implicado, descrito en Migración de Direct3D 11 a Direct3D 12. Consulte también la gama de opciones de Trabajar con Direct3D 11, Direct3D 10 y Direct2D.

Descripción de Direct3D 12