Esta entrada va a ser muy pero que muy matemática, pero creo que es necesaria para aclarar ciertos conceptos a un nivel de complejidad que hasta ahora no he tratado en el blog, por lo que os aviso que en esta entrada veréis muchas ecuaciones por el medio y números con tal de poder explicar bien las cosas.

Geometría

Obviamente la GPU ha de acceder a los datos de geometría de los modelados en memoria para empezar a componer la escena. En el hardware actual por suerte hay una serie de caches que almacenan de manera temporal los datos de realizar una serie de operaciones que son fijas para todos los objetos y esto se puede hacer porque OpenGL y las APIs que en diseño derivan de esta (el 100% de las APIs que se utilizan en consola) renderizan los triangulos/polígonos de uno en no.

Un vertice necesita unos 56 bytes de memoria (3×4 para la posición, 3×4 para la normal y 4x2x4 para las coordenadas de texturas) y este se encuentra normalmente indexado en un array que pongamos que es de 6 bytes y hemos de tener en cuenta que existe normalmente una relación de 2:1 en cuanto al número de vertices respecto a los triangulos, por lo que:

(56 + 6 * 2)/2 = 34 bytes por triangulo.

Tomemos por ejemplo un juego de la actual generación del que sepamos cuantos triangulos/polígonos mueve por fotograma.

infamous-second-son-wovow-org-02

Infamous Second Son es un buen ejemplo de ello, sabemos que mueve unos 11 millones de polígonos por fotograma a una velocidad de 30 fotogramas por segundo.

11.000.000*30*34= 10.45 GB/s

La geometría en principio es fácil, el problema viene ahora y es que hemos de tener en cuenta que las GPUs son procesadores cuyo rendimiento depende de manera directa del flujo de datos (ancho de banda) que les va llegando y que tienen que procesar, siendo las etapas correspondientes al Pixel/Fragment Shader las que más peso computacional tienen y por tanto las que más datos necesitan.

captura-de-pantalla-2012-10-04-a-las-10-24-53

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

En el caso de Bz y Bc estos son los anchos de banda relacionados con el búfer de imagen y es interesante tratarlos aparte d entrada porque hay casos en los que con tal de ahorrar memoria en un sistema por costes se han buscado técnicas de ahorro de memoria como pueden ser el Tile Rendering y el uso de memoria embebida que no son otra cosa que técnicas que consisten en el renderizado del búfer de imagen dentro de una memoria intermedia de alto ancho de banda con tal de ahorrar la carga por ancho de banda a la memoria principal que se acaba reduciendo a geometria por un lado y captación de texturas por otro pero en el caso concreto del Tile Rendering hay un problema añadido, duplica la geometría necesaria y en el caso de la memoria embebida no basta con tener el ancho de banda necesario sino que ha de caber el búfer de imagen entero.

El caso de la memoria embebida es mucho más facil de explicar, para ello voy a tomar un hardware antiguo como es PlayStation 2.

ps2-console

Y voy a utilizar un juego de muy, pero muy a principios de la vida de la consola como es el Quake 3: Arena.

f25

Quake 3: Arena es un juego que utiliza Z-Buffering de 24 bits y color de 32 bits, sabemos que su d media es de 3.4 aunque lo vamos a rendondear a 4 por lo que o(d) es de 3.4. A partir de aquí podemos deducir Bz+Bc de manera desglosada.

Bz = 4*3+2,08*3= 18,24 bytes/pixel

Bc = 2,08 *4= 8,32 bytes/pixel

Bz+Bc= 26,56 bytes/pixel.

El juego en PS2 se movía a 512×384 a una tasa de 60fps en versión NTSC (La PAL iba peor y nos comiamos 50) por lo que a partir de aquí podemos calcular el ancho de banda necesario para mover el juego.

512*384*60*26,56=313314509 bytes/seg= 299 MB/s

El ancho de banda de la memoria embebida para Color y Z no es que fuera 10 veces más que eso sino que era más de 100 veces por lo que en este caso no había cuello de botella ninguno.

gs-capabilities

En el caso concreto de la GameCube de Nintendo que apareció por el mismo tiempo tampoco hubiese sido un problema.

flipper-datapath

 

El otro tema ejemplo es el de Dreamcast y su Tile Rendering, desconocemos cual es el ancho de banda de la memoria interna de la GPU de Dreamcast para ejecutar el Tile Rendering pero de no haberlo hecho hubiese tenido problemas, no obstante sabemos que el juego en ducha version funciona a 640×480 pixeles y 30 fotogramas por segundo por lo que la cantidad de información que mueve en cuanto a búfer de imagen es algo menor realmente pero no sabemos realmente si ese es el cuello de botella del juego o no, en teoría no debería serlo y estar el cuello de botella en la Bt y es aquí donde hay más miga.

La formula de la Bt esta simplificada y esta sin tener en cuenta el filtrado de texturas y la precisión de este varia completamente según el tipo de filtro utilizado para el filtraje y con ello el ancho de banda utilizado, si no utilizamos ningún tipo de filtro de texturas la formula es:

Bt = o(d)*Tr

Pero con filtro de texturas es:

Bt = o(d)*(Ft*Tr)

Donde el valor de Ft varia según el filtro de texturas utilizado, siendo 4 si es bilineal, 8 si es trilineal, 16 si es anisotropico, 32 si es anisotropico x2…

picture_4_large

El otro tema es el multitexturizado, o mejor dicho los pasos por textura, estos son completamente variables pero la realidad es que la cifra ha ido en aumento pero la formula siempre es la siguiente:

Bt = o(d)*Ft*Tr*Mt

En el caso que nos ocupa que es el Quake 3 Arena tenemos texturas de 32 bits, filtro trilineal y 2 pases de texturas.

Bt= 2,08*8*4*2= 133.12 bytes/ciclo

Esto significa que el ancho de banda para texturas en el caso de la versión de PS2 sería de:

512*384*60*133,12= 1570347418 bytes = 1.45 GB/s

La cifra es mucho más alta que el resto pero PS2 texturiza sobre una memoria embebida con un ancho de banda de 9.6 GB/s pero en el caso de Dreamcast tenemos una memoria de 800MB/s pero no podemos olvidar que el juego funciona a 640×480 pixeles en ese caso.

640*480*30*133,12= 1226833920 =1.14 GB/s

Pero no olvidemos la compresión de texturas que es otro factor importante aquí, por lo que la formula cambia de nuevo con esto:

Bt = o(d)*Ft*(Tr/Tc)*Mt

La compresión VQ de Dreamcast tenía un ratio de 4:1 por lo que al final el resultado que quedaba era el siguiente:

2,08*8*1*2= 33.28 bytes

Y por tanto:

640*480*30*33,28= 306708480 bytes = 285 MB/s

De esta manera no hay problema en el ancho de banda pero es que Dreamcast no texturizaba con memoria embebida pero PS2 y GameCube si que lo hacían y es en este punto donde tenemos que hablar de la memoria de texturas porque el concepto tiene ciertas confusiones.

Cache de Texturas.

El concepto Cache de Texturas es erroneo para cierto hardware desde el momento en que no hablamos de un cache al uso sino de una memoria aparte desde donde se procesan las texturas pero ha de ser manejada manualmente por el propio programa, pero la idea en ambos casos es la misma y se situan en el mismo punto ambos elementos, la diferencia es que en uno el mecanismo es automático y es muy poca memoria y en el otro no es automático y es mucha memoria.

Su utilidad es:

  1. Dar un acceso de poca latencia y mucho ancho de banda a los shaders para operar en el caso de que las GPU los tenga.
  2. Dar el ancho de banda suficienemente bueno como para poder aplicar el filtrado de texturas.

En el caso de PS2 y GameCube estas dos consolas tenían una cache de texturas de 1MB y en parte eso era trampa, porque tu en cada escena no necesitas más informacion de texturas que el búfer de imagen que precisamente era también de 1MB por lo que no se producía jamás que un dato no se encontrase en la cache por lo que m en estos casos es 0… ¿m? ¿que m? En los sistemas con una cache pero sin participación del desarrollador (todas las GPUs desde la GeForce 3 en adelante) lo que hay es una GPU de unos pocos KB que almacena la textura que se esta filtrando en esos momentos, no obstante es posible que se produzca lo que llamamos una cache miss que se produce cuando el dato no esta en la cache o en su defecto esta no se encuentra disponible y se ha de buscar el mismo dato en nivel inferior de la cache de la GPU.

La formula de Bt en este caso pasa a ser:

Bt = o(d)*Ft*(Tr/Tc)*Mt*m

¿Y cual es el valor real de m? Sinceramente.

no-lo-se

En realidad m es el porcentual sobre 1 de lo que es una cache miss, es decir, teoricamente los datos siempre están en la cache pero el ratio de m depende de dos cosas:

  1. El hardware en el cual se esta ejecutando el juego.
  2. El código mismo del juego.

Por lo que m fluctua enormemente dependiendo de la situación e incluso en escenas completamente dispares de un mismo juego pueden dar resultados distintos y estos valores las empresas se los guardan. De ahí a que sea completamente imposible saber cual es el valor de m pero si que sabemos que si m es igual 1 esto significa que la cache o no funciona para ese caso en concreto o en su defecto no esta mientras que si es 0 entonces es completamente efectiva en ese caso en concreto. Ahora bien, hay una trampa que tiene que ver con el nivel de multitexturizado y el filtraje y es que no se trabaja nunca con todo el polígono entero sino en grupos de 2×2 pixeles para asegurarse que el bilineal como mínimo salga gratis y es aquí donde tenemos que entender la relación directa entre el multitexturizado y la precisión del filtraje, si mi hardware puede con dos muestras entonces puedo realizar trilineal, si puede con 4 muestras entonces anisotrópico (siempre y cuando el hardware este preparado para esos filtros), aunque en este caso la formula no varía porque como veremos después el valor de Mt puede ser más grande incluso que 16.

Supongamos que tenemos una escena más compleja, por ejemplo la de Doom 3.

doom-3-image202098

Mantenemos la resolución de 640×480 pero tenemos en cuenta que su Mt no es de 2 sino que puede subir hasta los 20 por un lado y por otro que Zw y Zr aumenan hasta los 32 bits (4 bytes), y el filtraje del juego paso a ser anisotrópico.

Queremos ejecutar el juego a 30fps que es como se movía en la primera Xbox y suponemos que su d y o(d) es la misma que Quake 3 para simplificar y por el hecho que son del mismo estilo de juego.

Antes de nada calculamos Bz y Bc.

Bz= 4*4+2,08*4= 24,32

Bc= 4*2,08= 8,32

Bz+Bc= 32.64

Por lo que:

640*480*30*32,64= 300810240= 280 MB/s

Pero el tema esta en la Bt donde:

Bt =2,08*16*1*20*m

No sabemos el valor de m y es por eso que hecho una tabla que va desde el 0.1 al 1.

0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
Bt  66,56 133,12 199,68 266,24 332,8 399,36 465,92 532,48 599,04 665,6
B en GB/s 0,85 1,42 1,99 2,57 3,14 3,71 4,28 4,85 5,42 5,99

¿Que significa esto? Pues que si por ejemplo el NV2A no tuviese cache de texturas entonces Doom 3 no hubiese sido posible en su día en la consola.

Ahora bien, supongamos que queremos renderizar Doom 3 en una GPU contemporanea y por tanto a 1080p60 y con anisotropico x16 antes de nada hemos de calcular el valor de Bz y Bc.

1920*1080*60*32,64= 3.78 GB/s

Por lo que la tabla nos quedaría de la siguiente manera:

0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
Bt  66,56 133,12 199,68 266,24 332,8 399,36 465,92 532,48 599,04 665,6
B en GB/s 11,49 19,20 26,92 34,63 42,34 50,05 57,77 65,48 73,19 80,90

Como véis la petición en ancho de banda es enorme pero ya que estamos… ¿Que ocurre si el mecanismo de overdraw es completamente efectivo y por tanto d= 1 y o(d)= 1 Pues…

Bz= 1*4+1*4= 8

Bc= 1*4= 4

Bz+Bc= 12

Bz y Bc de entrada tienen ya una reducción considerable del ancho de banda necesario en los 640×480 a 30 fotogramas por segundo:

640*480*30*12= 103 MB/s

Y la tabla correspondiente evoluciona de la siguiente manera:

0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
Bt 32 64 96 128 160 192 224 256 288 320
B en GB/s 0,38 0,65 0,93 1,20 1,48 1,75 2,03 2,30 2,57 2,85

Como véis el cambio es sustancial y en el caso de los 1080P60.

1920*1080*60*12= 1.4 GB/s

Por tanto:

0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
Bt  32 64 96 128 160 192 224 256 288 320
B en GB/s 5,11 8,82 12,52 16,23 19,94 23,65 27,36 31,06 34,77 38,48

Como véis una buena optimización del overdraw hace cambiar enormemente las cosas.

¿Y que ocurre con los sistemas que hay multiples niveles de cache? En las GPUs actuales no hay más que dos niveles de cache, pero en ese caso la formula variaria de la siguiente manera:

Bt = o(d)*Ft*(Tr/Tc)*Mt*(m*n)

Pero hemos de tener en cuenta que el camino de datos pasa por la cache L2, en nuestro caso supuesto vamos a suponer que si, veamos primero la tabla con d=4 y por tanto o(d)=2,08.

Bt = 2,08*256*(1)*20*(m*n)

La table Bt con eso se hace más complicada, primero la haré con el valor de d=4 y por tanto o(d)=2,08.

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
0,1 0,00 6,66 13,31 19,97 26,62 33,28 39,94 46,59 53,25 59,90 66,56
0,2 0,00 13,31 26,62 39,94 53,25 66,56 79,87 93,18 106,50 119,81 133,12
0,3 0,00 19,97 39,94 59,90 79,87 99,84 119,81 139,78 159,74 179,71 199,68
0,4 0,00 26,62 53,25 99,84 99,84 166,40 199,68 232,96 266,24 299,52 332,80
0,5 0,00 33,28 66,56 159,74 159,74 199,68 239,62 279,55 319,49 359,42 399,36
0,6 0,00 39,94 79,87 139,78 186,37 232,96 279,55 326,14 372,74 419,33 465,92
0,7 0,00 46,59 93,18 139,78 186,37 232,96 279,55 326,14 372,74 419,33 465,92
0,8 0,00 53,25 106,50 35,94 47,92 59,90 71,88 83,87 95,85 107,83 119,81
0,9 0,00 59,90 119,81 179,71 239,62 299,52 359,42 419,33 479,23 539,14 599,04
1 0,00 66,56 133,12 199,68 266,24 332,80 399,36 465,92 532,48 599,04 665,60

Los anchos de banda necesarios se convierten en este caso en los siguientes (las cifras están en GB/s)

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 3,71 3,71 3,71 3,71 3,71 3,71 3,71 3,71 3,71 3,71 3,71
0,1 3,71 4,48 5,25 6,02 6,79 7,57 8,34 9,11 9,88 10,65 11,42
0,2 3,71 5,25 6,79 8,34 9,88 11,42 12,96 14,51 16,05 17,59 19,13
0,3 3,71 6,02 8,34 10,65 12,96 15,28 17,59 19,91 22,22 24,53 26,85
0,4 3,71 6,79 9,88 15,28 15,28 22,99 26,85 30,70 34,56 38,42 42,27
0,5 3,71 7,57 11,42 22,22 22,22 26,85 31,47 36,10 40,73 45,36 49,98
0,6 3,71 8,34 12,96 19,91 25,30 30,70 36,10 41,50 46,90 52,30 57,70
0,7 3,71 9,11 14,51 19,91 25,30 30,70 36,10 41,50 46,90 52,30 57,70
0,8 3,71 9,88 16,05 7,87 9,26 10,65 12,04 13,43 14,82 16,20 17,59
0,9 3,71 10,65 17,59 24,53 31,47 38,42 45,36 52,30 59,24 66,18 73,12
1 3,71 11,42 19,13 26,85 34,56 42,27 49,98 57,70 65,41 73,12 80,83

Veamos ahora la tabla con d=1 y por tanto o(d)=1.

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
0,1 0,00 3,20 6,40 9,60 12,80 16,00 19,20 22,40 25,60 28,80 32,00
0,2 0,00 6,40 12,80 19,20 25,60 32,00 38,40 44,80 51,20 57,60 64,00
0,3 0,00 9,60 19,20 28,80 38,40 48,00 57,60 67,20 76,80 86,40 96,00
0,4 0,00 12,80 25,60 48,00 48,00 80,00 96,00 112,00 128,00 144,00 160,00
0,5 0,00 16,00 32,00 57,60 76,80 96,00 115,20 134,40 153,60 172,80 192,00
0,6 0,00 19,20 38,40 67,20 89,60 112,00 134,40 156,80 179,20 201,60 224,00
0,7 0,00 22,40 44,80 67,20 89,60 112,00 134,40 156,80 179,20 201,60 224,00
0,8 0,00 25,60 51,20 76,80 102,40 128,00 153,60 179,20 204,80 230,40 256,00
0,9 0,00 28,80 57,60 86,40 115,20 144,00 172,80 201,60 230,40 259,20 288,00
1 0,00 32,00 64,00 96,00 128,00 160,00 192,00 224,00 256,00 288,00 320,00

Por otro lado recordemos que en este caso Bz+Bz a esta resolución es de 1.4 GB/s, la tabla resultante acaba siendo:

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 1,40 1,40 1,40 1,40 1,40 1,40 1,40 1,40 1,40 1,40 1,40
0,1 1,40 1,77 2,14 2,51 2,88 3,25 3,62 4,00 4,37 4,74 5,11
0,2 1,40 2,14 2,88 3,62 4,37 5,11 5,85 6,59 7,33 8,07 8,82
0,3 1,40 2,51 3,62 4,74 5,85 6,96 8,07 9,19 10,30 11,41 12,52
0,4 1,40 2,88 4,37 6,96 6,96 10,67 12,52 14,38 16,23 18,09 19,94
0,5 1,40 3,25 5,11 8,07 10,30 12,52 14,75 16,97 19,20 21,42 23,65
0,6 1,40 3,62 5,85 9,19 11,78 14,38 16,97 19,57 22,16 24,76 27,36
0,7 1,40 4,00 6,59 9,19 11,78 14,38 16,97 19,57 22,16 24,76 27,36
0,8 1,40 4,37 7,33 10,30 13,27 16,23 19,20 22,16 25,13 28,10 31,06
0,9 1,40 4,74 8,07 11,41 14,75 18,09 21,42 24,76 28,10 31,43 34,77
1 1,40 5,11 8,82 12,52 16,23 19,94 23,65 27,36 31,06 34,77 38,48

Deferred Rendering

 

Lo que hemos visto sobre el Forward Rendering, por lo que ahora toca paso al Deferred Rendering, el cual pide un ancho de banda mucho mayor por el hecho de trabajar con varios Render Targets.

deferred_overview

El problema del Deferred Rendering es que debido a esto cuadriplica las necesidades de ancho de banda, no voy a colocar la tabla d=4 por el hecho que el mensaje esta claramente dado pero si la d=1 porque es realista para lo que hay hoy en día y utilizando Deferred Rendering.

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60
0,1 5,60 7,08 8,57 10,05 11,53 13,02 14,50 15,98 17,47 18,95 20,43
0,2 5,60 8,57 11,53 14,50 17,47 20,43 23,40 26,36 29,33 32,30 35,26
0,3 5,60 10,05 14,50 18,95 23,40 27,85 32,30 36,75 41,20 45,65 50,09
0,4 5,60 11,53 17,47 27,85 27,85 42,68 50,09 57,51 64,93 72,34 79,76
0,5 5,60 13,02 20,43 32,30 41,20 50,09 58,99 67,89 76,79 85,69 94,59
0,6 5,60 14,50 23,40 36,75 47,13 57,51 67,89 78,27 88,66 99,04 109,42
0,7 5,60 15,98 26,36 36,75 47,13 57,51 67,89 78,27 88,66 99,04 109,42
0,8 5,60 17,47 29,33 41,20 53,06 64,93 76,79 88,66 100,52 112,39 124,25
0,9 5,60 18,95 32,30 45,65 58,99 72,34 85,69 99,04 112,39 125,74 139,08
1 5,60 20,43 35,26 50,09 64,93 79,76 94,59 109,42 124,25 139,08 153,92

Como podéis ver tenemos un problema con el ancho de banda de cara al futuro, obviamente aquí no he incluido el ancho de banda del Frontbuffer (el cual no se ve afectado por el overdraw) ni los efectos de post-procesado. Pero se puede ver como tenemos un problema enorme en lo que a los anchos de banda de cara al futuro y que es el mayor cuello de botella de todos de cara al futuro.

El futuro: 4K HDR

Con los 4K HDR los costes en ancho de banda van a aumentar una barbaridad, os pongo la table con la d=1 y con 12 bits de color por componente, la table Bt quedaría de la siguiente manera:

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
0,1 0,00 4,80 9,60 14,40 19,20 24,00 28,80 33,60 38,40 43,20 48,00
0,2 0,00 9,60 19,20 28,80 38,40 48,00 57,60 67,20 76,80 86,40 96,00
0,3 0,00 14,40 28,80 43,20 57,60 72,00 86,40 100,80 115,20 129,60 144,00
0,4 0,00 19,20 38,40 72,00 72,00 120,00 144,00 168,00 192,00 216,00 240,00
0,5 0,00 24,00 48,00 86,40 115,20 144,00 172,80 201,60 230,40 259,20 288,00
0,6 0,00 28,80 57,60 100,80 134,40 168,00 201,60 235,20 268,80 302,40 336,00
0,7 0,00 33,60 67,20 100,80 134,40 168,00 201,60 235,20 268,80 302,40 336,00
0,8 0,00 38,40 76,80 115,20 153,60 192,00 230,40 268,80 307,20 345,60 384,00
0,9 0,00 43,20 86,40 129,60 172,80 216,00 259,20 302,40 345,60 388,80 432,00
1 0,00 48,00 96,00 144,00 192,00 240,00 288,00 336,00 384,00 432,00 480,00

Y los anchos de banda para 4K30:

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60
0,1 5,60 10,05 14,50 18,95 23,40 27,85 32,30 36,75 41,20 45,65 50,09
0,2 5,60 14,50 23,40 32,30 41,20 50,09 58,99 67,89 76,79 85,69 94,59
0,3 5,60 18,95 32,30 45,65 58,99 72,34 85,69 99,04 112,39 125,74 139,08
0,4 5,60 23,40 41,20 72,34 72,34 116,84 139,08 161,33 183,58 205,83 228,07
0,5 5,60 27,85 50,09 85,69 112,39 139,08 165,78 192,48 219,17 245,87 272,57
0,6 5,60 32,30 58,99 99,04 130,18 161,33 192,48 223,62 254,77 285,92 317,06
0,7 5,60 36,75 67,89 99,04 130,18 161,33 192,48 223,62 254,77 285,92 317,06
0,8 5,60 41,20 76,79 112,39 147,98 183,58 219,17 254,77 290,37 325,96 361,56
0,9 5,60 45,65 85,69 125,74 165,78 205,83 245,87 285,92 325,96 366,01 406,05
1 5,60 50,09 94,59 139,08 183,58 228,07 272,57 317,06 361,56 406,05 450,55

Y para 4K60:

m/n 0 0.1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1
0 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60 5,60
0,1 5,60 14,50 23,40 32,30 41,20 50,09 58,99 67,89 76,79 85,69 94,59
0,2 5,60 23,40 41,20 58,99 76,79 94,59 112,39 130,18 147,98 165,78 183,58
0,3 5,60 32,30 58,99 85,69 112,39 139,08 165,78 192,48 219,17 245,87 272,57
0,4 5,60 41,20 76,79 139,08 139,08 228,07 272,57 317,06 361,56 406,05 450,55
0,5 5,60 50,09 94,59 165,78 219,17 272,57 325,96 379,35 432,75 486,14 539,54
0,6 5,60 58,99 112,39 192,48 254,77 317,06 379,35 441,65 503,94 566,23 628,52
0,7 5,60 67,89 130,18 192,48 254,77 317,06 379,35 441,65 503,94 566,23 628,52
0,8 5,60 76,79 147,98 219,17 290,37 361,56 432,75 503,94 575,13 646,32 717,51
0,9 5,60 85,69 165,78 245,87 325,96 406,05 486,14 566,23 646,32 726,41 806,50
1 5,60 94,59 183,58 272,57 361,56 450,55 539,54 628,52 717,51 806,50 895,49

¿Por qué Doom 3 como ejemplo?

Pues por el hecho que una vez se ha calculado la geometría la parte de la rasterización en adelante es completamente igual independientemente de cual sea la geometría del juego, espero que con esta entrada hayáis aprendido y os aclare muchos de los conceptos en cuanto a hardware gráfico de manera general.