Junto a la esperanzadora llegada de Windows 10, que añadirá un sinfín de posibilidades a Xbox One gracias a la ampliación de los horizontes en otras plataformas, uno de los elementos más llamativos de esta alianza es la que aportará la API DirectX 12. Considerando una época en la que, por raro que parezca, los rendimientos globales han copado portadas y noticias, generando polémicas que han tapado la esencia de este hobby, ya sea por resolución o framerrate, la construcción de Xbox One parecía abocada a tener que esperar al desarrollo de este conjunto de librerías para poder acceder a todo el potencial que este hardware puede dar por si solo.
Los primeros indicios del desarrollo de esta nueva API se remontan a la alianza que forjaron entre Microsoft y ATI en la construcción de una base de librerías que diese un mejor rendimiento de los productos del fabricante de hardware. A partir de ahí, surgieron las primeras evidencias de un trabajo intenso para trabajar con estas piezas, que fue bautizado como Mantle. Los datos revelados por esta API propia de ATI suponían un incremento interesante de rendimiento en los juegos lanzados, aplicándose un incremento de hasta el 30% en algunos casos, sosteniendo un mínimo del 12% en algunos títulos probados.
Ahora bien, el anuncio de DirectX 12 suponía un paso alentador para la comunidad de Xbox, que veía como la batalla por los datos, al menos en los que afectan de forma directa (resolución y framerrate), sucumbían ante la mayor potencia en bruto de su rival directo. DirectX 12 es uno de los baluartes de la llegada de Windows 10 y con ello, muchos desarrolladores han declarado lo positivo de su llegada, principalmente, por ofrecer un mayor acceso a determinados aspectos de Xbox One, como la esRAM, la cual, fue una apuesta que no parece estar dando tan buenos resultados como se esperaba. Ahora, la llegada de DirectX 12 sugeriría un incremento del potencial global de los hardwares, en torno a un 20%, afectando de diferente manera en los PC, según piezas, y alcanzando de pleno a Xbox One, aunque también podría haber diferencias en base al motor gráfico empleado y la pericia de los desarrolladores.
DirectX nace de la unión con los desarrolladores
Un aspecto importante es la vinculación de Microsoft con los fabricantes de hardware y los desarrolladores de motores gráficos, quienes parten como principal factor responsable del nacimiento y la futura evolución de DirectX 12. Cuando la llegada de DirectX 12 parece cercana, se presume de que la última versión de DirectX 11, la cual estaría implementada en Xbox One, sería una versión predecesora de lo que DirectX 12 puede llegar a ofrecer, intentando minimizar el impacto que podría tener en Xbox One. Ahora bien, lejos de que esta API sea definitiva cuando llegue, el feedback de los desarrolladores se mantendrá constante para una continua evolución que permitirá sacar más y más rendimiento a todos y cada uno de los hardwares. En principio, DirectX 12 rige su funcionamiento en el máximo aprovechamiento de los recursos, reduciendo requisitos y optimizando la compenetración de rendimientos entre diferentes elementos del hardware.
En términos de acceso temprano, más de 400 desarrolladores de más de 100 estudios ya tienen acceso a ella, y en algunas casos, ya se han mostrado datos sobre la implicación que tendrá en algunos títulos, como es el caso de The Witcher 3: Wild Hunt o Project CARS. No se puede esperar que los juegos que vean la luz este año estén implicados en el uso de esta API, no obstante, son varios los que han asegurado trabajar en una actualización que permita sacar algo de provecho de la misma. Los efectos directos sobre la llegada de DirectX 12 se harán esperar, si bien, algunos títulos exclusivos se pensaban para dar el espaldarazo a esta API, no será así, como es el caso de Forza Motorsport 6, que hará uso de la última versión de DirectX 11 que habrá.
El principal factor a tener en cuenta, es que DirectX 12 actualmente tiene el soporte del 50% del mercado, esperando que para su lanzamiento acapare hasta el 66%, lo que dejaría margen de expansión y, sobre todo, mejora, pues en la implicación de las desarrolladoras reside la posible evolución de esta API, la cual, podría intentar implicar en el desarrollo las herramientas necesarias para sacar un rendimiento adicional, a nivel técnico, con el uso del Cloud Computing, otra baza que parece estar todavía a expensas de ser explotada.
Caracteristicas principales
DirectX 11 ofrecía un rendimiento dispar, según observaron a la hora de mejorar la API, durante las llamadas que se realizaban en la ejecución de un proceso, se producían sobrecargas de la CPU y esto provocaba una reducción notable del rendimiento. Una de las primeras advertencias de Microsoft requerían una mejor disposición y orden de estas llamadas para que el proceso se pueda hacer de forma fluida y dinámica. Durante el análisis preliminar de DirectX12, se ha demostrado que resulta mejor combinar todos los objetos en un único y coherente Pipeline State Objet, donde se puede realizar la compilación y usarse para aunar los procesos de hardware de una sola tacada.
Centrándose en este aspecto, no solo era cuestión de un exceso de órdenes o comandos que saturaban los procesos. La falta de optimización del rendimiento también surgía con procesos que no requerían de introducir comandos en una única pipeline. Es por esto, que DirectX 12 también gestiona la cantidad de recursos según el número de procesos requeridos, de modo que gracias al pipeline state optimizations, se pueden diversificar los procesos habilitando para ello diferentes líneas que permitan mayor fluidez y división de las tareas para que el rendimiento sea superior. En cierto modo, este proceso supone la escisión de comandos para que los procesos sean ramificados y empleen diferentes recursos en vez de explotar una única vía que pueda llegar a saturar el proceso y ralentizarlo. Al fin y al cabo, no es solo cuestión de saturación de procesos, sino de optimizar los recursos incluso, cuando no haya tal saturación y aprovechar el conjunto lineas de proceso.
La saturación en DirecX 11 era un problema importante que retenía los procesos y no permitía sacar el rendimiento absoluto de los hardwares, generando en muchas ocasiones conflictos que daban rendimientos poco coherentes. El principal problema, es que los juegos comenzaron a saturar los procesos con shaders y renders que todavía empeoraban esta situación y provocaban conflictos debidos a una saturación excesiva de procesos que llegaban de forma poco coordinada. De este modo, la propuesta de DirectX 12 ofrece una opción por la que se genera un modelo de memoria explícita donde los objetos se almacenan como estructuras dentro de la GRAM, de modo que los desarrolladores puedan describir mediante un descriptor que permita copiar los procesos, apilándose en forma de array, simplificando y ordenando los procesos, a los que se accede de forma más rápida y eficaz.
En el fondo, los descriptores son un recurso que se ha ido implementando con el paso del tiempo, mediante los cuales los códigos han podido simplificarse mediante el uso de estos elementos que se suelen disponer como un array. De este modo, un descriptor incluye en su descripción los comandos para un proceso sin que estos se encuentren ocupando un espacio en el código que suponga una saturación para el procesamiento. Los descriptores sirven cual acceso rápido al proceso una vez se hace la llamada correspondiente. La gestión de estos descriptores resulta de vital importancia, pues almacenados como una fuente externa, solo se accede realmente a ellos cuando se requiere, y no se cargan en memoria o se añaden como un proceso innecesario, si no es necesario.
En el fondo, este principio busca la mayor eficiencia en el código, bien empleando estos descriptores y aunándolos en pequeños grupos o bundles, llevando el orden y el almacenamiento de elementos a diferentes niveles que pueden gestionarse con llamadas puntuales y que requerirán los procesos única y exclusivamente cuando son necesarios de forma ordenada y coherente, sin saturar los recursos de forma innecesaria.
Cambiando un poco de tema, los Resource Binding Tiers (Recurso de Encuadernación de Tiers) son el recurso que Microsoft ha diseñado para optimizar el rendimiento de las GPU al máximo posible, abordando los descriptores en forma de agrupaciones. Dentro de este proceso, Microsoft ha contemplado la existencia de diferentes niveles para las diferentes GPUs, estableciendo un diverso nivel de complejidad a aprovechar dentro de las posibilidades encontradas, siendo el primer nivel para los hardwares tempranos, hasta el tercer nivel para el caso de las nuevas GPU y las que están por llegar al mercado en un futuro próximo, las cuales, también podrían habilitar una nueva evolución en un futuro.
En cierto modo, el recurso explícito vinculante busca asegurar que no haya riesgos alguno en el uso de los recursos que puedan ocasionar problemas a la hora de mantener la coherencia entre la GPU o los objetos en el proceso de renderizado hacia y desde las texturas. Pare esto, la API ResourceBarrier es la encargada de gestionar estos procesos con el fin de evitar que se generen conflictos que puedan ocasionar problemas de rendimiento posteriores por acumulación de tareas y procesos que no sean procesados en el momento oportuno.
En el fondo, todos estos procedimientos buscan optimizar los procesos y gestionar bien los recursos. Uno de los aspectos más relevantes del desarrollo de Mantle, era sacar el máximo rendimiento posible de los hardwares, aplicándose, en este particular caso, a los nuevos procesadores que AMD había construido, los cuales, tenían en sus diversos núcleos grandes capacidades que generalmente quedaban ocultas al hacer uso de GPUs independientes. DirectX 12, como un heredero de esta herramienta, quiere buscar la optimización de procesos para que la unión de CPU y GPU se armoniosa y bien coordinada. Es precisamente este el aspecto que DirectX 12 ha publicitado, por ser un concepto más comprensible.
Según se ha explicado, DirectX 12 permitirá a los desarrolladores acceder de forma más sencilla a todos los recursos disponibles, aunando las capacidades de CPU y GPU. Gracias a esta API, los desarrolladores podrán cambiar los descriptores durante los procesos mediante el uso de rutas rápidas, como serían los registros que se realizan al pasar los parámetros por el pipeline. Esta función sería equiparable al que se emplea en el pipeline para la generación de sombras, consistente en una lista de argumentos, enteros o flotantes, que van circulando por el pipeline dedicado para este fin.
En las anteriores API existían procesos que quedaban como residuos que secuestraban recursos que debían estar disponibles. Es el caso de numerosos procesos que DirectX 11 no eliminaba de la memoria de la gráfica hasta que los comandos requerían ese espacio para otros procesos, lo que provocaba una sobrecarga de procesos que podía evitarse. En cierto modo, el desarrollador va a tener un control absoluto sobre que elementos quedan como residentes en la memoria y cuando dejan de estar disponibles en este proceso. De este modo, la sincronización resulta más efectiva, al poder recurrir a ellos cuando se debe y se puedan eliminar por completo cuando se requiera. Gracias a DirectX 12 se puede asignar un gran volumen de memoria y manejarla para que los procesos procedentes tanto de la CPU como de la GPU la tengan disponible.
En las API anteriores, si el desarrollador elimina un recurso, la API no lo borrará de la memoria de vídeo hasta que los comandos de representación se ejecuten en la GPU que, obviamente, resulta en más sobrecarga. Pero a medida que los desarrolladores de juegos saben lo que va a ser eliminado y cuando, sólo tendrían que sincronizarlos con la GPU y eliminarlos según la necesidad. Un buen ejemplo que McMullen afirmó durante el discurso fue la transmisión constante de la geometría entre la CPU y la GPU. Se puede asignar una gran cantidad de memoria que se puede acceder tanto por la CPU y la GPU, escribirlos en el buffer, hacerlas y en consecuencia realizar un seguimiento cuando esas llamadas de renderizado se completan en la GPU. Una vez que estén completos, la memoria puede ser utilizada para cualquier otro propósito. Esto es lo que vino a describirse como la Transmisión Constante de la Geometría entre la GPU y CPU, mediante la cual se puede asignar una gran cantidad de memoria tanto por la GPU como la CPU, escribiéndolos en el buffer y gestionando un seguimiento cuando las llamadas de los renders son completadas. Una vez estos procesos están completos, la memoria puede ser utilizada por cualquier otro propósito al liberarse de la carga del proceso terminado.
Otra de las novedades que incluye DirectX 12 es el Conservative Rasterization mediante la cual detecta los procesos complejos como la oclusión, la representación de curvas o las transparencias. Gracias a esta inclusión, los desarrolladores podrán ahorrar un precioso tiempo en encontrar soluciones a estos procesos, al poder emplearse este recurso para la gestión de estas tareas. La inclusión de nuevas tecnologías y la compleja disposición de código por parte de algunos desarrolladores hacían demasiado complejos los procesos y, en muchas ocasiones, resultaban códigos ineficaces que ralentizaban el rendimiento general. La Conservative Rasterization permite que cualquiera pueda emplear estos procesos sin tener que crear un código, de este modo, no solo se permite un mejor aprovechamiento de los recursos, sino que se incentiva a los desarrolladores ahorrándoles tiempo.
Del mismo modo, el Tiled Resources Tier 3 viene a ser algo similar, pero en esta ocasión con el fin de ordenar los volúmenes, que anteriormente quedaban dispersos, ahora se pueden montar fácilmente y se puede especificar el valor de la plantilla dentro de los shaders. De este modo, se puede realizar un «precocinado» de los procesos en base a estos volúmenes para que cuando han de ser ejecutados puedan hacerlo de forma más rápida y efectiva. En cierto modo, es un nuevo ejemplo de la optimización de recursos, ubicando procesos livianos en largos periodos previos a su ejecución para que en el momendo dado no tengan que procesarse por completo.
Pruebas iniciales, rendimiento en Unity
Uno de los primeros motores en ser testigo y portavoz de los beneficios de DirectX 12 fue Unity, quienes declararon haberse puesto en contacto con esta SDK en noviembre de 2014 y comenzaron a probar los beneficios de esta nueva API. Según aseguraron meses después, la tasa de éxito fue rotunda, alcanzando un 95% en sus pruebas internas. De hecho, se mostraron pruebas irrefutables del rendimiento mejorado, es decir, de que este éxito era notable para el caso de este motor en particular.
En las particulares pruebas que se llevaron a cabo, uno de los primeros procesamientos que se llevo a cabo fueron las tareas de sombreado, siendo una de las cualidades descritas en la lista de aspectos optimizados por DirectX 12. El objetivo era poner a prueba diferentes mapas de sombras lejos del hilo principal, usando otros hilos para otras tareas. En cierto modo, Unity tiene la capacidad de funcionar como un cliente dentro de un dispositivo gráfico, generando una lista de comandos que se ven obligados a pasar por la API a través del dispositivo cliente. Claro que, haciendo uso de DirectX 12, se pueden generar múltiples hilos, permitiendo saltarse listas intermedias, traduciéndose en mejoras de rendimiento efectivas. De este modo, mientras unos hilos trabajaban los sombreados, otros podían estar trabajando en otros procesos, que si bien pueden tratarse como tareas en segundo plano, también pueden acaparar funciones relevantes para trabajar elementos en tiempo real, como pueden ser, por ejemplo, las físicas. Ahora bien, no tiene porque priorizarse la generación de sombras, permitiendo que sea este el proceso que transcurra en un segundo plano y se permita que los procesos importantes tomen recursos y se obtenga una eficacia notable en la priorización de procesos en base a los recursos disponibles.
De este modo se consiguió reducir una escena que constaba de 7.000 elementos, de 23ms a 13ms, lo que supone una ventaja considerable. Todo esto fue posible por la posibilidad que se ofrecía de separar procesos en diferentes hilos y dar cabida a procesos latentes en segundo plano a modo de precarga. Puede parecer irrelevante, pero las pequeñas diferencias puntuales deben ser consideraras, a todo efecto, como parte de un todo. Si vamos acumulando este ahorro de tiempo, al final, la suma ofrece resultados realmente alentadores para la optimización del rendimiento. Si matizamos que este ahorro de 10ms se traduce en un proceso concreto por cada fotograma, no se puede negar la evidencia. Desde Unity, esto se traduce en algo realmente sorprendente, no es algo que haya surgido por arte de magia, sobre todo, porque no se requiere una maestría por parte del desarrollador para poder acceder a este recurso.
Ahora, con un acceso más directo sobre el procesamiento multihilo, no cabe duda de que hay que optimizar mucho código anterior a esta API, lo que se traduce en un trabajo que muchos no van a realizar, pero que abre las puertas a futuros proyectos, tal como dejó entrever el CEO De Stardock, Brad Wardell. De hecho, si estos datos basados en unidades temporales puede ser algo sombríos e incomprensibles, la realidad de cual es el beneficio de DirectX 12 puede traducirse a una unidad más conocida, los frames por segundo. Haciendo alusión a este aspecto, la demostración del uso del Shaders Caché y el ExecuteIndirect es una nueva prueba de los beneficios que esta nueva API supone.
Un frame típico tiene alrededor de 200 a 400 pipelines, incluso, puede llegar a rondar las 1000. Gracias al Shader Caché, el desarrollador controlará por completo este procedimiento, de modo que cuando se quiere optimizar el procesamiento de partículas, PSO (Particle Swarm Optimization), se puede especificar la caché que almacenará la salida para ejecutarse. De este modo, la API dará una representación binaria totalmente compilada de todas las instrucciones que debe ejecutar el hardware, de modo que todo el peso del procesamiento están realizados para el momento de la ejecución.
Si combinamos este proceso con el que genera ExecuteIndirect, sustituto de DarwIndirect y DispatchIndirect, se pueden realizar múltiples llamadas en una, además, recurriendo a la CPU o GPU según convenga.
Entre estas dos galerías se puede comprobar los beneficios de los procedimientos basado sen Shaders Caché y ExecutionerIndirect, a través de la demo Intel Asteroids, la cual obtiene una considerable mejora de rendimiento. Gracias a la optimización del proceso, se obtiene un salto interesante que pasa de los 28fps a los 70fps, en el caso de la optimización de la CPU. No obstante, esta mejora puede optimizarse aún más si se diversifican los procesos y se obtienen los recursos combinados de CPU y GPU llegando hasta los 90fps. En un primer movimiento, se procedió al uso de los procesos ‘precocinados’, alcanzando 80fps y gracias a ExecutionerIndirect se obtuvo un 10% más de rendimiento, alcanzando la cifra citada de 90fps. Todo esto, además, supuso una reducción del uso de la CPU en torno a un 9%. Es decir, más por menos.
Pero esto no es el único procesamiento novedoso que aporta un efecto directo sobre el rendimiento, también podemos encontrar algo similar, aunque aplicado a otro ámbito, a la hora de describir el Multiengine, basado en el proceso Compute and Copy. DirectX 12 no tendría una cola monolítica como DirectX 11, para lo que emplearía una técnica que, según se puede entender, se permite la obtención de determinados elementos que son copiados para ser posteriormente reubicados tras un procesamiento de streaming. Usando la estructura de cola, los desarrolladores pueden priorizar entre cargas de trabajo o las tareas de fondo. Las primeras versiones de la API apenas diferenciaban tres niveles de prioridad, baja, media o alta, no obstante, según se dio a conocer, se pretende diversificar este aspecto incluyendo más niveles de prioridad en base a prioridades espaciales en tiempo real.
En Fable Legends se marca la diferencia
Como era de esperar, no solo los desarrolladores externos han tenido opción de conocer las bondades de DirectX 12, también desde dentro de algunos de los estudios de Microsoft han tenido un primer contacto con esta API. Es el caso de Lionhead Studios y su futuro título Fable Legends, el cual, se ha puesto a prueba para mostrar las diferencias que esta API permite en el rendimiento de un título. Evidentemente, el trabajo realizado para compatibilizar el código a las multitareas y los multihilos de DirectX 12 ha obtenido resultados realmente sobresalientes, tal como demostraron a través de este vídeo.
Gracias a DirectX 12, el rendimiento del juego se vio claramente optimizado, si bien, desde Lionhead aseguraron que no se había procedido a aprovechar todo el potencial de la API, sino que se había trabajado en ciertos aspectos para intentar compatibilizar ciertos procesos. El resultado, evidente, si bien, se obtenía una tasa de frames en torno a los 43fps con DirectX 11, al ser ejecutado en DirectX 12 se obtenía una mejoría notable, no solo por alcanzar los 53fps de media, sino porque lo hacía a una mayor resolución, 1080p más concretamente. La diferencia efectiva entre una y otra API, a 1080p, era que con DirectX 11 se alcanzó, en el mejor de los casos, los 48fps, mientras que con DirectX 12 se alcanzaban los 61.
Conclusión, más y mejor, pero con tiempo
DirectX 12 es una API que realmente sirve para aprovechar bien los recursos de los hardwares. En cierto modo, parece una solución para los problemas actuales de Xbox One, la cual, se puede aprovechar de esta herramienta. A lo largo de las generaciones, los hardwares han tenido que ir descubriéndose con el paso de los meses y los proyectos, algo que parecía inviable en esta generación, ya que los hardwares que se han montado, parecían más convencionales. Es precisamente este aspecto el que ha dejado constancia los rendimientos dispares que se han ido obteniendo en los primeros juegos, surgiendo una brecha entre plataformas que ha sido empleada cual arma, aunque en este apartado, el beneficiado ha sido el usuario de PC que ve como esta batalla está lejos de su trono dentro del rendimiento.
Claro que no podemos decir que DirectX 12 sea una respuesta ante esta vicisitud, tal siquiera, una conclusión derivada de la incapacidad de sacar provecho de algunos factores de Xbox One, como la esRAM, que están totalmente desaprovechados. DirectX 12 era una API cuyo origen puede coincidir, aunque parece casual, con el origen real de esta, si bien, como hemos comentado al dar inicio a este artículo, la intención era sacar provecho de la evolución de los hardwares que llegan al mercado de PC, claro que, estos no son diferentes de las configuraciones de hardware de las consolas de esta última generación. Uno de los principales aspectos de los que podría beneficiarse Xbox One, es la mayor facilidad de acceso a la esRAM, que fue una de las apuestas fuertes de Microsoft, asegurando que su rendimiento, combinándose con la memoria DDR3, superaba la DDR5 de su rival.
Pero dejando esto a un lado, la realidad es que DirectX 12 es una solución para los desarrolladores que buscan alcanzar un mejor resultado para Xbox One. La llegada se producirá a lo largo de 2015, aunque tardará más que Windows 10, todavía lo harán más los juegos que hayan basado su desarrollo plenamente en esta API. Algunos títulos confirmados, incluso algunos ya lanzados, han apostado por DirectX 12, pero es una incógnita si su trabajo de optimización y adaptación también llegará a Xbox One. Se han dado muchos datos, se ha asegurado que Xbox One podría beneficiarse hasta alcanzar las fastuosas cifras de 1080p y 60fps en muchos de los casos, aunque lo más creible es el dato que aportaría entre un 10-20% de rendimiento adicional, siendo un porcentaje tan variable como lo es la capacidad de aprovechar esta API o de adaptarse a ella debidamente.
Los juegos a lo largo de una generación evolucionan y, según parece, esta API también podría seguir el mismo camino. DirectX 12 está en su primera build, por decirlo de algún modo, algo que, dada la implicación conjunta de Microsoft con las desarrolladoras, principalmente las que gestionan motores gráficos, podría servir para que con el paso del tiempo, se puedan optimizar los recursos y los lenguajes para el aprovechamiento de todo el potencial de los hardwares. Podemos observar que la continua evolución es un factor determinante en esta industria, DirectX 12 no será algo inamovible, sino que con el paso del tiempo, tanto desarrolladoras como motores gráficos irán mejorando su relación para obtener cada vez un mejor rendimiento. Existe un límite, evidentemente, pero parece que este está todavía lejos de ser vislumbrado.
En conclusión, no se trata de una revolución que vaya a aportar un cambio tan grande como es un salto generacional, pero si puede ser el elemento que falta para que el último salto dado sea realmente destacable y pueda igualar saltos anteriores entre generaciones. Considerando que en estas lides existen dos mundos, la brecha entre ellos también se abrirá un poco más, pero al menos, si se consiguiese cerrar polémicas vacías en torno al diferente rendimiento de las consolas, el incremento de la distancia con el rendimiento de los PC, será un tema que se terminará por obviar para disfrutar de una experiencia que sea de nueva generación y de un catálogo de juegos que cada día atesora más calidad y posibilidades.