El otro dia se filtro el esquema de la arquitectura Turing de Nvidia, lo que nos permite saber su organización interna y es interesante porque nos permite hacernos una aproximación de como se ha integrado el Raytracing en una GPU pensada para el rasterizado y en que se diferencia respecto al mismo concepto aplicado a los PowerVR que salió hace unos años.NVIDIA-TU102-GPU-Block-Diagram-1000x548_ret.png

Nos encontramos con que cada SM tiene su Tensor Core, la cual es una unidad de función fija que de lo único que se se encarga es de calcular la intersección de los rayos con la geometría de la escena (triangulos), se encuentra en cada uno de los 72 SM de la GPU. Esto algo que ya sabíamos previamente por un comentario en Reddit pero la diapositiva de la propia Nvidia nos lo confirma.

RTCore

Esto difere enormemente del hardware de Caustic Graphics para el Raytracing que Imagination integro en los PowerVR después de comprar dicha compañía, donde lo que es el hardware dedicado para el Raytracing esta fuera del equivalente a las unidades SM de Nvidia que serían los USC.

1_PowerVR GR6500 GPU - PowerVR Wizard GPUs

En realidad es completamente igual donde se encuentre la unidad de calculo de la intersección, su funcionalidad no cambia pero se ha de tener en cuenta que obviamente el rendimiento será distinto. Las partes en azul serían las equivalentes al RT Core y dan un rendimiento de 300 MRPS, esto contrasta con las especificaciones dadas por Nvidia en ese aspecto respecto a Turing, con cifras que irian de los 6.000 MRPS hasta los 10.000 MRPS. Pero claro, no podemos olvidar que en un caso tenemos una sola unidad y en el otro tenemos 72 unidades, por no hablar de las diferencias en lo que a velocidad de reloj se refiere a favor de las GPUs de Nvidia.

Como ya he explicado muchas veces los PowerVR renderizan por Tiles, el renderizado por Tiles requiere que se genere un búfer adional donde se almacene la información de manera ordenada según la posición de pantalla toda la geometría de la escena que ha sido calculada en las etapas anteriores, justo antes de rasterizar los poligonos (triangulos).

tiletriangle

Dicha lista luego es convertida en listas de pantalla para cada Tile.

tilebuffer

Pero lo que diferencia un Tile Rendering de un Inmediate Rendering es la organización del Back Buffer (Color+Z-Buffer), especialmente el último, el cual en vez de generarse a nivel de pantalla se genera a nivel de Tile y se almacena en una memoria interna desde donde es procesado hasta terminar el Tile, es decir, hasta que podemos escribir la imagen final (front buffer) en memoria.

El caso es que el otro día estaba hablando con una persona que sabe mucho pero que mucho más que yo y me dijo que en el rasterizado independientemente si hablamos de un Tile Renderer como una GPU convencional…

Graphics3D_Rasterization

… Todas las GPUs rasterizan por Tiles, la diferencia es que las GPUs convencionales:

  1. La mayoria de GPUs ordenan los fragmentos según su posición de pantalla cuando son escritos en el búfer de imagen. El motivo de hacerlo es que al contrario que con el Tile Rendering donde si que es necesario almacenar la información de la geometría relativa a la pantalla para el Tile Buffer, en el rasterizado tradicional no es necesario. sortlast
  2. No almacenan el resultado de las rasterización de cada tile en ninguna memoria interna por lo general, esto provoca el efecto de sobredibujado/overdraw donde varios triangulos son escritos en un mismo espacio de pantalla aunque no son visibles, hay muchas técnicas tanto por «software» (shaders) como por función fija para descartar la geometria sobrante.
  3. La técnica que se esta estandarizando es el Tile Caching. En esta técnica si que se ordena la geometria según su posición en la escena antes del rasterizado en la Cache L2.   sortmiddleCuando se va a rasterizar se rasterizan todos los polígonos del Tile en conjunto…  tiledcaching2tiledcaching3Esto permite descartar de entrada los polígonos no visibles para que no sean rasterizados… siggraph_vega_architecture_41 ….y una vez terminado el proceso este es re-enviado desde la L2 a los Shaders para ejecutar el Pixel/Fragment Shader en los elementos visibles de la escena.

¿Cual es el problema? Como el Raytracing representa el comportamiento de la luz en un espacio tridimensional en el fondo esto hace que incluso los objetos no visibles interactuen en la escena haciendo que si los descartas de alguna manera pues que te cargas el proceso por falta de información de como los rayos han de atravesar la escena. Eso si, hemos de tener en cuenta que necesitamos generar un BVH como estructura de datos para realizar el Raytracing… ¿Que es un BVH? Pues un mapa de la geometria de la escena en forma de arbol.

534px-Example_of_bounding_volume_hierarchy.svg.png

Pero en el caso que nos ocupa dicha geometría previa antes de ser rasterizada y por tanto descartada quedaria almacenada en la Cache L2 en forma de BVH para que luego el RT Core incluido en el propio SM haga el recorrido sobre el BVH correspondiente a ese Tile y devuelva el resultado al realizar una petición. Se ha de tener en cuenta que las ALUs de los Shaders no ven realmente más allá de sus registros y recorrer una estructura de datos de ese calado les es muy dificil. De ahí los RT Cores, pero los mismos RT Cores necesitarían un tiempo enorme para atravesar escenas sumamente complejas, de ahí a tener un RT Core por SM que es lo mismo que decir que tener un RT Core por Tile.

RTCore

Pero el RT Core no realiza los efectos especiales, solo dice si hay una intersección o no, esto se puede conseguir con los Compute Shaders pero con una eficiencia mucho más baja. Es más, la especificación del DXR es una extensión del DX12 pero con la diferencia en Turing que dicha parte del proceso es hecha por una unidad de función fija en vez de tirar de shaders por el hecho que como he dicho muchas veces es una parte recursiva y repetitiva. Microsoft afirma que se puede realizar por computacion:

«Os habréis dado cuenta que DXR no introduce ningún tipo de motor GPU que vaya junto a los motores de gráficos y computación ya existentes en DX12. Esto es intencional, las cargas de trabajo DXR pueden ser ejecutados en los ambos tipos de motores existentes. El motivo primario de de esto, fundamentalmene,e s que DXR es una carga de trabajo del tipo ocomputación. Nonecesita estados complejos como output merger blend modes o input assembler vertex layouts. La razón secundaria, es sin embargo, que representando el DXR como una carga de trabajo tipo computación es como vemos el futuro de los gráficos, digamos que el hardware se irá volviendo más de proposito general y eventualmente muchas unidades de función fija serán reemplazadas por código HLSL.

Obviamente que se puede, pero esta cantinela llevamos oyendola casi un lustro y nadie, repito, nadie va a complicarse la vida en tener que manejar manualmente y de forma re-iterativa cosas que durante años se han hecho con unidades de función fija. En Nvidia y AMD que saben mucho más de hardware que Microsoft después de años con el pipeline de computación aún no han descartado elementos como las unidades de textura, rasterizadores, ROPS… Todo eso se podría asignar a los shaders si… ¿Pero por qué no se hace? Pues porque a veces en un espacio pequeño y por temas de coste es mejor una unidad de función fija que te solvente un problema en concreto por un porcentaje infimo de coste del chip. ¿Por qué por ejemplo seguimos teniendo decodificadores de video especializados en las GPUS cuando los shaders son tan potentes? Pues por el hecho que las unidades de función fija hay veces donde son la solución, tan simple como eso.

El DXR tal y como lo plantea Microsoft es inutilizable, hace unos meses sin la integración de los RT Cores por parte de Nvidia el futuro pasaba por necesitar 4 GPUs GV100 de $3000 cada una para renderizar esto…

gdc-epic-games-nvidia-ray-tracing-demo-slim_1200x500

… En unos 55ms mientras que una sola Turing (TU102) con menos capacidad de computación y gráficos que la GV100 lo hace en 45ms. Que si, que no son cifras muy altas pero es un…

j-r-williams-batman-slap-robin

… muy, pero que muy grande por parte de Nvidia a Microsoft. Es decir, Microsoft defiende que con shaders puros y duros se puede conseguir el Raytracing y va Nvidia y les demuestra que son necesarios los RT Cores para tener un rendimiento aceptable en los juegos. ¿Y que hay de AMD? Pues AMD estaba invitada  del DXR, lo que han hecho es seguir con la especificación de Microsoft que no tiene en cuenta los RT Cores, es decir, la especificación de hacer Raytracing en un hardware DX12 estándar y sin cambios. Pero la existencia de los RT Cores es curiosa porque su utilidad no es solo de cara al Raytracing sino también de cara a la detección de colisiones que es un elemento clave para los videojuegos y no solo eso, sino que además los RT Cores nos pueden servir también para representar de manera fidedigna también la propagación del sonido, bueno, más bien acelerar porque el proceso de intersección de la onda sonora con el objeto matematicamente y algoritmicamente es igual y en juegos competitivos el hecho que la representación del sonido sea fidedigna según la distancia y la posición del mismo es un paso delante.

Es decir, tenemos una unidad que es sumamente útil no solo para Raytracing sino para otras cosas relacionadas con los videojuegos y que solventa uno de los problemas básicos de los shaders que es el recorrido de estructuras de datos espaiales y va Microsoft y nos dice que el Raytracing híbrido es posible sin problemas en un hardware DX12 estándar… Sinceramente…

Obelix Loco

La realidad es que el DXR es inutilizable en los juegos actuales con las GPUs actuales excepto Turing, la realidad es que Microsoft no tiene razón en plantear el DXR como algo que se puede hacer en una GPU estándar. ¿Como es que AMD por ejemplo esta muy callada sobre el tema? Pues porque saben de primera mano cual es el handicap en general.

Pero esta no es toda la historia, el Raytracing tal y como se va plantear es de juguete. ¿El motivo? La cantidad de objetos con la capacidad de reflejar y refractar la luz en un principio serán limitados. ¿El motivo? Pues que DXR nos obliga a marcar que objetos hacen rebotar la luz y como, no olvidemos además que a medida que aumentamos la cantidad de luces en escena la complejidad es más grande en la étapa de Raytracing por lo que nos vamos a encontrar con juegos que activarán y desactivaran el Raytracing dinámicamente y en diversos grados según la carga luminica de la escena. Es decir, nos encontraremos con escenas en las que ciertos objetos si y otros no harán rebotar la luz por motivos de potencia disponible en el hardware.

Pero sobretodo hay un tipo de escena que vamos a ver poco siendo renderizada por el pipeline hibrido… ¿Que tipo? Os pongo un ejemplo.

batman-arkham-knight-review-pc-485286-5

Escenas con multitud de fuentes de luz primarias y también con una gran cantidad de elementos reflectantes, en estas escenas vais a ver como el Raytracing durante años va a estar muy pero que muy recortado por la cantidad de calculos a realizar con los shaders y vais a ver análisis técnicos donde os comentarán que la impresionante iluminación de un juego determinado solo será en determinadas circunstancias. La inclusíón de los RT Core son un paso adelante, pero no hemos de olvidar que los efectos se van  seguir calculando en los shaders. Es cierto que hemos llegado al limite de la rasterización casi pero no os esperéis que el Raytracing vaya a solventar los problemas de entrada de la rasterización porque su implementación va a ser ciertamente limitada de entrada.