Ahora que la versión «doméstica» del AMD Vega esta a punto de salir, AMD nos ha dejado ir algo más de información acerca de la arquitectura de dicha GPU y aunque desde mi punto de vista vamos a ver una arquitectura más avanzada que esta, esta claro que hay una serie de elementos que vamos a ver en futuras iteraciones. Esta cuarta parte de la serie es para comentar elementos que vamos a ver en la siguiente generación a nivel de arquitectura de la GPU

Primitive Shaders

Los Primitive Shaders son un intento de cara al futuro de sustituir el pipeline geométrico convencional…

TraditionalGeometry.PNG

… Por uno completamente nuevo donde los Primitive Shaders son un sustituto tanto de los Vertex Shaders como de los Geometry Shaders.

PrimitiveShaders.PNG

Esto significaría tener que re-escribir el código de muchos juegos, aparte de que por el momento ninguna API los soporta por el momento. ¿Cual es la solucion temporal de AMD con Vega? Pues por lo visto los desarrolladores no tienen acceso a los mismos y son gestionados por el driver/controlador.

AutoPrimitiveShaders

AutoPrimitiveShaders2

¿Y como es que AMD lo llama Shader si al fin y al cabo no es programable? Pues por el hecho de que los Primitive Shaders aún no están expuestos a nivel de API en el caso de Vulkan y DirectX.

VegaDX13.PNG

¿El problema de ello? Por el momento no hay ninguno pero en una API de bajo nivel no hay controlador/driver… Por lo que la gestión no sería automática y haría falta una nueva API de bajo nivel o una versión actualizada de las ya existentes para utilizarse y estos cambios marcan siguiente generación. El motivo por el cual no es accesible por el programador es por el hecho de que la magia se encuentra en el pipeline interno entre el Vertex Shader y el Geometry Shader, pipeline en el que en ningún momento la GPU accede a una memoria interna. Esto explicaría el motivo por el cual no esta expuesto a nivel de API y AMD no ha publicado ninguna extensión al menos para Vulkan y OpenGL.

¿Y cual es la diferencia? La pregunta más bien sería… ¿Cual es su utilidad? Dejemos que Mike Mantor de AMD nos lo explique.

«Vamos a hablar de lo básico a alto nivel. Cuando una aplicación envía o renderiza objetos, cada objeto tiene carácteristicas: un modelo es construido para el objeto y se renderiza en un una escena en 3D. Un objeto es normalmente modelado como un objeto completo, no importa como lo veas y cual sea el campo de visión, la representacion esta ahí. El procesador gráfico procesa el triangul o los objetos en el campo de visión y decide si son o no visibles. Una de las primeras cosas que ocurrn cuando dibujamos un objeto, es que nosotros ejecutamos un shader más tarde o temprano para procesar esos vertices y se crean posiciones de los vertices en un espacio de visión común. Parte del estado de datos que define el espacio de visión común es el frustrum de visión (El frustum es una porción de una figura geométrica (usualmente un cono o una pirámide) comprendida entre dos planos paralelos. Las intersecciones del sólido con un plano cortante son las bases. El eje es el mismo que el del objeto original, si este lo tuviera. Si el eje es perpendicular a la base el sólido es recto y en caso contrario, oblicuo.). Esto es para decidir si todos los triangulos de un objeto, las primitivas del mismo se encuentran fuera del campo de visión.»

«Si el objeto esta fuera de la vista, no hy necesidad de enviarlo al pipeline gráfico. Muchas veces las aplicaciones realizan un primer nivel de «culling» antes que el objeto haya sido enviado a la GPU, o pueden enviar una burda representación de la goemetría (solo unos pocos trangulo) para preguntarle a la GPU si el objeto esta en la vista. Si no esta a la vista, no hay motivo de enviarlo al rasterizador. i el objeto es complejo, en vez de tomar tiempo en renderizarlo, puedes enviar un montón de volumenes delimitadores para ver si el objeto esta incluso visible.

«Cuando un objeto viene a un pipeline gráfico y hacemos el procesamiento de la posición, podemos pensar que hay diferentes tipos de culling: parte del objeto puede estar fuera de mi campo e visión, parte de los triangulos no están. La parte trasera del objeto esta hecha de triangulos que no son sisibles… Y entonces, nosotros tenemos un objeto que esta en un espacio como es la prte del triangulo ue esta bien lejos cuando se proyecta en el espacio de pantalla, vemos con un 50% de los triangulos que llegan al pipeline están en una posición que no hace falta renderizarlos. No necesitas escanearlos, convertirlos y procesarlos. Y lo antes que puedas determinar que el triangulo esta fuera del frustum de visión, entonces sabremos que el triangulo podrá crear pixeles potenciales.

¿De que me suena esto? Bueno, recientemente en la entrada acerca del hardware de PS3 comente que es posible utilizar los SPE para pre-procesar la geometría y eliminar los vertices no visibles durante la creación de la geometría. Aquí el concepto es el mismo, solo que realizando el proceso completo en la GPU sin necesidad de un chip de apoyo. La idea es descartar de manera temprana toda esa geometría no visible y que se puede convertir en fragmentos que luego acaban siendo procesados y aunque el DSBR que veremos más tarde se encarga de eliminar los objetos fuera del campo de visión, esto lo hace a nivel de fragmento y no lo hace a nivel de geometría.

Lo bueno es que parece que lo hace de manera automática, lo malo es que no sabemos cual es el coste, aunque la realidad es que la tasa de geometría de las GPUs modernas es muy superior a lo que las rasterizadores de las mismas pueden rasterizar. Es posible que por ello hayan decidido colocar este pipeline de descarte de primitivas no visibles con tal de que el rasterizador no pierda el tiempo con ellas. ¿Os acordáis de como en la entrada de PS3 comente que los SPE de utilizarse antes de la GPU para renderizar una escena podían utilizarse para descartar la geometría superflua de una escena. Pues esto es lo mismo pero realizado de manera automática.

¿Que mejor si no de hace un poco de memoria?

(Perdón por el pequeño Deja Vu)

¿La idea? La eliminacion de triangulos en la escena que:

… son transformados pero que al aplicar las coordenadas de cámara/eye coordinates acaba fuera de escena por estar de espaldas a la cámara.

… se encuentran fuera de la pantalla (Viewport) pero aún así son calculados por el Vertex Shader.

… son lo demasiado pequeños y estan a una distancia lo suficientemente lejana de la cámara como para que la GPU rasterice y luego texturice, por lo que es una tontería calcular la geometría de estos.

… a la hora de rasterizarse no llegan a tocar ni un pixel de la escena y por tanto el rasterizador los descartará de entrada

¿Y como es que esto es importante? Pues por el hecho que hemos llegado al punto en que tenemos varios rasterizadores al mismo tiempo transformando cada uno un triangulo en un fragmento, pero en el caso de Vega solo puede rasterizar unos 4 poligonos por ciclo de reloj y generar unos 4 fragmentos.  ¿Y que conseguimos con esto? Pues el hecho de poder enviar de manera efectiva mucha más geometría útil manera efectiva descartando la no visible que no sirve para nada.

Es decir, si tenemos un escena de 10 millones de poligonos visibles no tiene sentido que la GPU calcule unos 20 millones en total cuando esos 10 millones de más se pueden aplicar a elemento visibles en el juego como modelados de más detalle por ejemplo. ¿La otra motivación? Si tenemos en cuanta lo que comente en la primera entrada de una evolución clara hacía el Tile Rendering (algo que veremos en esta entrada aún más marcado) tiene sentido la aplicación de un sistema en el pipeline que elimine las primitivas sobrantes.

La única consola con un Tile Renderer que ha salido al mercado y que aqui he comentado fue Dreamcast, para que un Tile Renderer funcione hemos de almacenar la geometria en un búfer especial que se va a utilizar para construir la escena tile por tile…  ¿Que información puede contener dicho búfer?

  • Posición de los vertices (Vec4 FP16/FP32)
  • Normales de los vertices (Vec4 FP16/FP32)
  • Color de los vertices (RGBA8)
  • n*Cooredenadas de texturas (RGBA8 cada una)

Por lo que imaginaos lo que resulta la eliminación de la geometría superflua en la escena. Obviamente Vega no es un Tile Renderer, pero como se puede ver hay una tendencia a ello.

Se confirma lo de la Rasterización por Tiles

Esto es importante porque hace unos meses en los controladores de la RX Vega Frontier esta funcionalidad no estaba activa y es clave de cara al futuro y creedme que va a ser muy utilizada en la siguiente generación de consolas.

Cada vez que yo comentaba la rasterización por Tiles en el AMD Vega os daba una enorme explicación acompañada siempre de la siguiente diapositiva:

tilevega

Ahora tenemos la confirmación de que esto tiene que ver con la rasterizacion por tiles.

siggraph_vega_architecture_41

VegaPixelEngine

¿El objetivo? Poder descartar los fragmentos no visibles durante la rasterización… ¿Pero no los habíamos descartado en la anterior etapa? Aquí se trabaja a nivel de fragmento que es diferente mientras que en la anterior lo haciamos a nivel de vertices, aquí ya no tenemos un cúmulo de vertices sino un cúmulo de pixeles.

El concepto es que tenemos partes de cada objeto que se vean opacadas por otros objetos que se encuentran delante pero esas partes son los pixeles internos del triangulo y no podemos descartarlas eliminando el vertice. Esto significa reducir la cantidad de fragmentos que iran al Pixel/Fragment Shader, pixeles que terminaran siendo inutilmente texturizados y enviados al búfer de imagen (aunque luego sean re-escritos) ocupando ancho de banda de manera inútil.

Esta es la gran ventaja que tenían hasta ahora las GPUs de Nvidia sobre las de AMD desde Maxwell, pero para ello era necesario re-pensar por completo la Cache L2 de la GPU que es lo que hizo Nvidia.

De ahí a que la cache L2 (que por cierto en el caso que nos ocupa es de unos 4MB) haya sido re-posicionada para transformar a varios elementos de la GPU como son los Pixel Engines (Rasterizadores) y los RBEs en clientes de la Cache L2, cosa que en arquitecturas GCN antes de Vega no lo eran. Dicho de otra manera, ahora tenemos un rasterizador con cache asociada, aunque sea la cache L2 global de la GPU, lo que permite almacenar los fragmentos rasterizados en forma de tiles .

VegaL2Cache

El hecho de que los RBEs sean ahora clientes de la cache L2 tiene sentido en relación a la generacion de la escena. Los RBEs procesan el Depth Buffer/Z-Buffer durante el rasterizado por lo que el hecho que estos ahora estén cableados en la Cache L2 tiene sentido. Tenemos unos 64 ROPS en total, capaces de escribir hasta unos 8 bytes cada uno por ciclo de reloj, esto significa que el Crossbar de la Cache L2 para dar el suficiente ancho de banda a los RBEs para realizar sus operaciones sobre el búfer de imagen debería ser como mínimo de 4096 bits. El problema es que Vega no es un Tile Renderer… ¿Entonces? Simple y llanamente cuando los RBEs descargan su contenido ya no lo hacen sobre la RAM principal sino sobre la Cache L2 por lo que en el caso de necesitar recuperar un dato del Tile Anterior la GPU no tiene que realizar todo el camino de datos… ¿El problema? El renderizado por Tiles como explique en la primera entrada de esta serie, aún no esta implementado del todo.

Ahora bien… Y volviendo al tema ¿Como es que es importante el hecho de eliminar la geometría superflua de repente? Esto lo explique en la entrada sobre la GPU y los anchos de banda, lo voy a citar a continuación para que la gente tenga una referencia y una motivación para ello, pero tiene que ver con el overdraw que es el hecho de procesar fragmentos que no aportan en la escena y que se acaban procesando igualmente si no son previamente descartados. A eso se le llama overdraw y a medida que la geometría de la escena más alta el nivel de overdraw es más alto.

Overdraw/Depth Complexity

Antes de ir directamente a calcular el ancho de banda necesario hemos de tener en cuenta un factor que es el sobredibujado u overdraw. La forma ideal de renderizar una escena es hacerlo de delante hacía atrás y descartar los polígonos que se encuentran detrás y son opacos, pero en la etapa de geometría el pipeline no sabe el color del pixel de cada polígono y cuando un polígono esta fisicamente presente pero tiene un nivel de transparencia resulta en un problema, no solo eso, sino que se ha de esperar a la fase de rasterización y generar el búfer de profundidad para comprobar donde realmente esta cada primitiva e ir descartando las no visibles del proceso.

En todo caso hemos de tener en cuenta que:

  1. El hecho de renderizar de atrás en adelante o de adelante hacía atrás depende de la elección a los desarrolladores.
  2. Son las GPUs la que llevan años implementando tecnicas de reduccion del overdraw, es decir, el envió de fragmentos correspondientes a partes no visibles en el fotograma.

Normalmente calculamos las escenas en teoría como si el overdraw no existiese y desgraciadamente existe. La gente confunde el overdraw con los pasos múltiples por pixel visible para hacer ciertos efectos. En realidad es cierto porque a nivel de pantalla por cada pixel estamos gastando recursos inutilmente. ¿Pero como medimos el impacto del overdraw realmente?

Hemos de tener en cuenta lo que llamamos serie harmónica en matemáticas.

H(n)=1+1/2+1/3+1/4… 1/n

La logica detrás de esto es que el primer polígono se dibuja durante el primer dibujado de la escena, el segundo en el segundo paso pero tiene un 50% de posibilidades de tenerse que dibujar, el tercer polígono tiene 1/3 de posibilidades de existir… Obviamente el nivel de overdraw

Al final esto se resume en:

limn→∞ H(n) = ln(n) + γ,

Donde γ es la constante Constante de Euler-Mascheroni.

Lo interesante es que si hay d polígonos cubriendo un pixel entonces la cosa se convierte en:

limn→∞ O(d) = ln(n) + γ

Dado que es la seríe harmónica entonces dependiendo del nivel de overdraw en la escena incluso teniendo la misma carga teórica por pixel la carga en el ancho de banda primero y en la computación después crecerá como la gráfica de la serie harmónica que es la siguiente:

600px-harmonicnumbers-svg

¿Y cual es el número de d? No olvidemos que el búfer Z almacena la posición de los pixeles según la profundidad y hoy en día es de 24 bits por lo que sería 2^24, obviamene esto es un limite teórico nada realista pero el nivel de overdraw dependerá de cada juego y de la cantidad de elementos en escena pero es un factor variable dependiendo no solo de cada motor gráfico, ni tan siquiera de cada juego sino a nivel de cada escena porque cada juego puede diferentes escenas con un nivel de overdraw distinto. ¿Y cual es el valor de d ideal Pues 1, porque si es 1 esto significa que todos los pixeles no visibles por el espectador no se renderizan.

Por otro lado no podemos confundir el Overdraw con el multitexturizado, el multitexturizado es el hecho de realizar varias operaciones concatenadas o no sobre cada uno de los pixeles de un búfer de imagen y no olvidemos que hay casos como el renderizado en diferido donde se trabaja con varios búfers de imagen. Es importante tener en cuenta dicha diferenciaciación antes de irnos directamente a los cálculos.

Ancho de Banda explicado de manera simple

La complejidad del hardware de la GPU lo que ha hecho es que las formulas del ancho de banda vayan variando con el tiempo, pero todas ellas se pueden resumir de la siguiente manera:

B = Bc + Bz + Bt.

Donde:

  • B es el Ancho de Banda Total
  • Bc es el Ancho de Banda del búfer de color.
  • Bz es el ancho de banda del búfer de profundidad
  • Bt es el ancho de banda de acceso a las texturas.

Pero añadiendo el factor del overdraw entonces la formula evoluciona es to:

B = d × Zr + o(d) × (Zw + Cw + Tr)

Donde:

  • d y o(d) sabemos que valores son, los he comentado antes.
  • Zr: Es la lectura del búfer de profundidad, el búfer de profundidad suele variar en el hardware aunque habitualmente es de 24 bits como mucho, aunque hardware de finales de los 90 lo tenía de 16 bit.
  • Zw: Es lo mismo que Zr pero en el sentido de la lectura. Zr y Zw suelen tener la misma precisión.
  • Cw: Es la precisión de color del búfer de color.
  • Tr: Es la profundidad de color por textura.

Normalmente Tr y Cr deberian ser lo mismo pero se le separa porque hay hardware muy antiguo que pese a que la cantidad de colores en global en pantalla era alta la cantidad de colores por ejemplo era baja. Por ejemplo la primera PlayStation podía colocar una paleta de 15 bits en pantalla pero a nivel de texturas solo soportaba formatos de 4 y 8 bits. El caso de Tw no existe porque esto es algo que viene de la multitextura y habitualmente esto se realiza en la misma cache de texturas que es independiente por completo del ancho de banda de la memoria principal, aunque de esto ya hablare más adelante.

Siguiendo con la ecuación del Ancho de Banda de ha de tener en cuenta que esta se puede desglosar.

Bz = d * Zr + o(d) *  Zw

Bc = o(d) * Cw

Bt = o(d)*Tr

B= Bz+Bc+Bt

La idea con el descarte es que el overdraw se reduzca a cero y de ahí el ahorro en ancho de banda pero sobretodo tiene sentido porque son fragmentos a procesar. Da igual cual sea la potencia de la étapas previas… Lo importante es la cantidad de pixeles que puede dibujar la GPU y más vale que dibuje un pixel visible que no que uno invisible o acabe repintando sobre otro ya procesado.

VegaPixelEngine2

¿La otra utilidad? Tiene que ver con el apartado que comentare a continuación que es la Voxelización de la escena… ¿El motivo? No nos interesa que durante el proceso de Voxelización existan fragmentos y geometría que no aportan en el fotograma y no son visibles porque si están de más enlentecen dicho proceso ya que esto también son procesados durante la voxelización.

Voxelización

Las cosas son un pelín más complicadas de cara al futuro si queremos utilizar métodos de iluminación mucho más complejos que los utiliados en los videojuegos actuales y para ello necesitamos una estructura de datos espacial que es generada tras la voxelización de la escena.

Voxelization2

Voxelization3

Y aquí entramos en otro elemento que esta desde las GPUs Maxwell en Nvidia pero no en las de AMD y tiene que ver con el nuevo rasterizador que he comentado antes.

VegaConservative

VegaConservative2.PNG

Esto es necesario para la voxelización de la escena y ninguna GPU con arquitectura GCN antes de Vega lo soportaba y ahora si, por lo que esto cambia ampliamente la situación de cara al futuro y permite la iluminación global en la siguiente generación de consolas en el caso de utilizarse esta arquitectura, aparte de que con AMD y Nvidia soportando la Conservative Rasterization en PC significa que ahora más y más juegos van a acabar adoptando la Voxelización dentro de su pipeline gráfico para la implementación de la llamada iluminacion global en una gran mayoría de juegos. Sobre la voxelización y su impacto en cosas como el ancho de banda ya hablare más adelante.

La idea de Voxelizar es para conseguir un tipo de iluminacion más compleja llamada iluminación global, para ello es necesario primero renderizar la escena solo con iluminacion directa, es decir, ignorar todas las fuentes de luz generadas por la interacción de la luz con los objetos y esa misma escena voxelizarla. El funcionamiento de la misma es diferente al renderizado en inmediato y en diferido, no voy a explicar aquí su funcionamiento al completo, dejemos en que para la voxelización la Conservative Rasterization acelera enormemente el proceso.

El HBCC (Ancho de banda)

Ya comente el HBCC en la entrada anterior, pero no lo comente a nivel de lo que supone en la GPU sino que lo comente en lo que supone en la organización del SoC. En esta entrada vamos a ver la organización a nivel de GPU.

Tomando como referencia lo explicado en la anterior entrada de esta serie, lo primero que tenemos que tener en cuenta es que en la nueva estructura la memoria HBMn seria la encargada de absorver todo el ancho de banda externo de la GPU, esto significa absorver los tres anchos de banda: Bt, Bc y Bz y por tanto la HBMn sería la memoria del video del sistema por lo que a ojos del observador tendríamos un sistema que tendría dos pozos de memoria separados y la GPU podría acceder a ambos según fuera necesario pero no habría contención sobre el pipeline gráfico cuando la GPU actue como cliente de la CPU.

¿Como se explica esto? Simple y llanamente la memoria HBMn sería una evolucion de la ESRAM de Xbox One pero con una densidad mucho mayor y con la capacidad de absorver el Bt. ¿El motivo de ello? Obviamente la mayor densidad de almacenamiento de la memoria HBMn. ¿Pero que tipo de memoria HBM vamos a ver? ¿La actual de segunda generación? ¿La de tercera? No, más bien…

lowcosthbm

La HBM utilizada actualmente tiene un bus de 1024 bits y puede cablear hasta unos 8 chips por pila, la HBM de consumo reduce la cantidad de chips por pila hasta 4 como mucho y a 2 como mínimo ya que el bus es de 512 bits. Esto significa que la configuración en una GPU como Vega con un bus de 2048 bits HBM… No seria con dos chips HBM de consumo.

AMD-Vega-GPU_2

Sino con 4, como ocurría con el AMD Fiji, obviamente con unos costes mucho más bajos que estos dos chips.

AMD-Fiji-GPU-High-Resolution-Shot

Suponiendo que no hay cambios en los ROPS y que pasamos a 64 ROPS en la siguiente generación, haciendo el cálculo inverso.

  • (3*10^9)*512 bits*4 chips de memoria= 768 GB/s
  • 768 GB/s /8 bytes por pixel= 96 Gpixeles/s
  • 96 Gpixeles / 16 pixeles triangulo (media)= 6 Triangulos Rasterizados por ciclo.
  • 6 Triangulos / 4 Rasterizadores= 1.5 Ghz de velocidad de reloj para la GPU

Como véis vamos concretando poco a poco la naturaleza del hardware de siguiente generación.

El HBCC (Densidad)

El hecho de dividir la memoria a vista de la GPU en paginas que podemos desplazar desde la memoria rápida (HBMn) a la memoria lenta tiene sentido de cara al Virtual Texturing donde podemos desplazar los tiles del atlas de texturas según sea conveniente y acelerar el proceso de renderizado.

¿Y no es mejor una memoria más densa y única?

  1. Una memoria más densa tarda mucho más en recorrerse y por tanto añade una enorme latencia en la búsqueda de datos.
  2. Las memorias más densas requieren complejos mecanismos para la interfaz con ellas y chips muy largos o en su defecto memorias muy lentas pero con mayor densidad.

La idea de trasladar a una memoria más cercana al procesador pero más rapida ya existia en Xbox One (ESRAM) pero con un problema, se hacía creando contención sobre el controlador de memoria y se consumía parte del limite de instrucciones del procesador de comandos para controlar los Move Engines, por no hablar que la densidad de la memoria era demasiado baja, haciendo que la posibilidad incluso de aplicar el Virtual Texturing se hiciese irrealizable, no porque el hardware de Xbox One no estuviese preparado para ello sino porque 32MB para almacenar todos los datos gráficos es una cifra muy baja, incluso utilizando un atlas de texturas para el Virtual Texturing

El hecho dividir la memoria en páginas todas del mismo tamaño tiene su utilidad con el Sparse Virtual Texturing, que ahora se podrá implementar de manera completa y automática sin tener que utilizar ciclos de los shaders para ir manejando la memoria al mover los datos entre memorias por parte del desarrollador, aunque lo mejor es hacer un poco de memoria, ya que esto se encuentra desde la primera versión de la arquitectura GCN.

prt2

Hace unos cuatro años antes de la salida de Xbox One comente la posibilidad de utilizar la ESRAM como atlas para el texturizado virtual. Era una era en la que no conociamos nada de la consola en concreto excepto especificaciones sueltas, el PRT en la memoria GCN lo que hace es cargar tiles de 64KB pero no carga un atlas de texturas completo en memoria en ningún momento.

¿Y cual sería el concepto de cara al futuro? Obviamente cada uno de los tiles ha de almacenar tanto la textura base como su Mip Map correspondiente, también hemos de tener en cuenta que el concepto seria el de ir cargando los tiles uno por uno en la cache L2 a medida que se van procesando. Una de las diferencias que tiene Vega respecto a las anteriores arquitecturas GCN es que puede volcar el resultado de los ROPS sobre la Cache L2. ¿Como es que importante esto? Si podemos tener los valores de color necesarios para el fragmento recien rasterizado en la Cache L2 que esta procesando la GPU entonces ganamos mucho en rendimiento.

VegaHBCC2

Ahora bien… ¿Pero que almacenamos en la memoria HBMn? Pues lo siguiente:

  • Todos los búfers de imagen.
  • El Atlas de Texturas.

El concepto sería utilizar secciones de 64KB de memoria para definir los tiles del atlas de texturas que se irían transmitiendo a la cache L2.  ¿Pero cuanta memoria HBMn necesitaríamos? Hemos de tener en cuenta que el atlas de texturas se almacena en una sola textura que puede tener un tamaño según las GPUs actuales de hasta 16384×16384 pixeles, pero en realidad no nos hará falta tanto para renderizar a 4K nativos.

Suponed que tenéis una escena a 4K…

4k-vs-1080p

Se puede realizar un mapa de texturas de 4096×2048 pixeles que haga de atlas de toda la escena, en realidad sería de 4096*4096 por el hecho que necesitamos almacenar los Mip Maps de cada una de las texturas disponibles.

mipmap

Supongamos que queremos almacenar unos 16 atributos por pixel, como el HDR será algo del futuro vamos a suponer que cada uno de los atributos esta en RGBA16FP, es decir, en FP16 por componente o lo que es lo mismo, 8 bytes por pixel.

Texture Atlas: 4096*4096*16*8= 2048 MB/2GB

Es decir, el tamaño máximo del atlas de texturas sería de unos 2GB, pero el atlas de texturas se utiliza unicamente para paliar el Bt, nos interesan ahora el Bc y el Bz que se procesarían también desde la memoria HBM, es decir, el búfer de imagen.

Bc: (4096*2048 pixeles)*8 bytes por pixel (RGBA16F)*8 MRT= 512MB

Se que el búfer es de 3840*2160 pixeles en 4K pero me va mejor hacer el calculo así porque los números son más redondos y el ratio es casi de de 1:1.

Bz: (4096*2048 pixeles)*4 bytes por pixel= 32MB

¿Que nos queda? El Front Buffer, que en este caso sería como mucho de 48 bits/6 bytes por pixel (RGB)

Front Buffer:  (4096*2048 pixeles)*6 bytes por pixel= 48MB

¿No nos dejamos nada? Pues si, nos dejamos un elemento muy importante que son los mapas de sombras, estos no son texturas sino que se generan de forma dinámica bajo el siguiente método.

  1. Renderizamos la escena pero desde una posición en la que la cámara esta donde se encuentra la fuente de luz global y de ahí generamos la escena pero almacenamos solo en memoria lo que es el Depth Buffer/Z-Buffer de la misma, el cual se utilizará como mapa de sombras.
  2. Renderizamos de manera normal la escena desde la posición de la cámara que pertoca, por cada fragmento a la hora de texturizar lo comparamos con su correspondiente posición en el mapa de profundidad previamente almacenado y que ahora es el mapa de sombras.

¿Y que resolución requiere el mapa de sombras de una escena? Pues a 1080P un mapa de sombras bueno tiene un tamaño de 4096×4096 pixeles, dado que este almacena los datos de un búfer de profundidad que luego se combinará con las texturas de la escena para el sombreado segun la posición y que hablamos de 4K pienso que lo mejor es hablar de un mapa de sombras de 16384 pixeles por lado

Mapa de Sombras: (16384*16384 pixeles)*4 bytes por pixel= 768MB

Por lo que en total tenemos:

2048+512+32+48+768= 3408 MB

Bueno… ¿Con esto hemos terminado no? Pues no, porque nos queda un elemento muy importante que tiene que ver con los bufers de imagen.

¿Son suficientes los 4K para prescindir del Antialiasing de una vez por todas? Actualmente tenemos dos tipos de Antialiasing, los primeros son lo espaciales que se basan en utilizar un búfer de imagen mucho más grande, el segundo utilizan el post-procesado y suelen necesitan 2 o 4 fotogramas renderizados internamente para poder funcionar bien y componer el fotograma final.

¿La gran verdad? Los 4K no son realmente perfectos en esto.

PanicRon

Es decir, continuaremos necesitando el uso de técnicas de Antialiasing para limpiar la imagen pero al contrario de antes donde el Aliasing era producido por la geometría, ahora las cosas se han complicado mucho más.

  • Dientes de sierra por Geometría: Dado que la geometría ha llegado a niveles de complejidad increibles. Esta se puede solventar utilizando anti-aliasing espacial sin problemas.
  • Dientes de sierra producidos por la iluminación: Esto no se puede solventar con ningún AA espacial, hace falta hacerlo utilizando un AA de post-procesado.
  • Dientes de sierra producidos por el post-procesado: Efectos como el Motion Blur, Depth of Field, Ambient Occlusion… Tienen el problema de necesitar mucha potencia para verse suaves lo que hace que muchas veces se creen dientes de sierra porque no hay la suficiente potencia para procesarlos de manera adecuada.

Los dos últimos no los solventamos aumentando la densidad de la memoria pero el primero si, que es de lo que estamos hablando. Los AA espaciales utilizan un búfer de imagen más grande por lo que el atlas de texturas queda fuera de esto… ¿El objetivo? Poder renderizar a 8192×4096 pixeles el búfer de imagen… La salida de imagen seguira siendo de 3840×2160/4096×2048 como bien sabréis.

Bc: (8192*4096 pixeles)*8 bytes por pixel (RGBA16F)*8 MRT= 2048MB

Bz:  (8192*4096 pixeles)*4 bytes por pixel= 128MB

Por lo que lo mejor es actualizar el cálculo anterior:

2048+2048+128+48+768 = 5040MB

Es decir, esta es la cantidad de memoria HBMn máxima que podemos esperar en un sistema de siguiente generación. ¿Sería posible con la HBM de consumo? Bueno, la actual memoria HBM2 si miramos su estandar…

sk_hynix_hbm_dram_2

Tenemos unos 8Gb por chip en cada pila (1GB), si la HBM de consumo tiene una configuración máxima de 4 chips por pila y tenemos unas 4 pilas esto serían unos 16 GB de memoria… Pero nos bastaría con una configuración de 2 chips por pila para tener unos 8GB de configuración. Los cuales serían de uso privado para la GPU.

¿Y que hay de la memoria principal del sistema? Bueno, llevamos más de 5000 palabras y aún no hemos terminado de explicar la GPU ya que no he explicado el tema de las Compute Units y los aceleradores de la GPU como los codificadores/descodificadores de video, pero estas dos cosas las voy a dejar para dos entradas más adelante. De la misma manera que el tema de la CPU y la memoria principal del sistema se merecen una entrada aparte.

PD: Llevo muchos días preparando esta entrada, de ahí la falta de contenido.