Se necesita mucho trabajo en la CPU para configurar un marco para la GPU, y una buena parte de ese trabajo está dentro del controlador de gráficos. Antes de DX12 / Vulkan, el diseño de la API obligaba esencialmente a que el trabajo del controlador de gráficos tuviera un solo subproceso.
La esperanza es que DX12 / Vulkan levante esa restricción, permitiendo que el trabajo del controlador se realice en paralelo en múltiples hilos de CPU dentro de un marco. Esto permitirá un uso más eficiente de las CPU multinúcleo, lo que permitirá a los motores de los juegos impulsar escenas más complejas sin comprometerse con la CPU. Esa es la esperanza: si se realizará en la práctica es algo que tendremos que esperar para ver en los próximos años.
Para elaborar un poco: la salida de un procesador de juego es una secuencia de llamadas API DX / GL que describen la secuencia de operaciones para representar un marco. Sin embargo, hay una gran distancia entre el flujo de llamadas API y los búferes de comandos binarios reales que consume el hardware de la GPU. El controlador tiene que "compilar" las llamadas API en el lenguaje de máquina de la GPU, por así decirlo. Ese no es un proceso trivial: implica una gran cantidad de traducción de conceptos de API a realidades de hardware de bajo nivel, validación para asegurarse de que la GPU nunca se establece en un estado no válido, disputas de asignaciones de memoria y datos, seguimiento de cambios de estado para emitir el comandos correctos de bajo nivel, y así sucesivamente. El controlador de gráficos es responsable de todo esto.
En DX11 / GL4 y API anteriores, este trabajo generalmente lo realiza un solo subproceso de controlador. Incluso si llama a la API desde varios subprocesos (lo que puede hacer usando las listas de comandos diferidos DX11, por ejemplo), simplemente agrega algo de trabajo a una cola para que el subproceso del controlador lo mastique más tarde. Una gran razón para esto es el seguimiento del estado que mencioné antes. Muchos de los detalles de configuración de GPU a nivel de hardware requieren conocer el estado actual de la canalización de gráficos, por lo que no hay una buena manera de dividir la lista de comandos en fragmentos que puedan procesarse en paralelo: cada fragmento tendría que saber exactamente en qué estado debe comenzar con, a pesar de que el fragmento anterior aún no se ha procesado.
Esa es una de las grandes cosas que cambió en DX12 / Vulkan. Por un lado, incorporan casi todos los estados de canalización de gráficos en un objeto, y para otro (al menos en DX12) cuando comienza a crear una lista de comandos, debe proporcionar un estado de canalización inicial; el estado no se hereda de una lista de comandos a la siguiente. En principio, esto permite que el controlador no tenga que saber nada sobre las listas de comandos anteriores antes de que pueda comenzar a compilar, y eso a su vez permite que la aplicación divida su representación en fragmentos paralelizables, produciendo listas de comandos completamente compiladas, que luego pueden ser compiladas. concatenados juntos y enviados a la GPU con un mínimo de alboroto.
Por supuesto, hay muchos otros cambios en las nuevas API, pero en lo que respecta al subprocesamiento múltiple, esa es la parte más importante.