¿Cuánta memoria ocupa una textura en la GPU?

9

Un png grande en el disco solo puede ocupar un par de megabytes, pero me imagino que en el gpu el mismo png se almacena en un formato sin comprimir que ocupa mucho más espacio. ¿Es esto cierto? Si es cierto, ¿cuánto espacio?

Miguel
fuente

Respuestas:

16

Los archivos JPG y PNG casi siempre serán más pequeños en el disco que en la memoria; necesitan descomprimirse sobre la marcha para adquirir datos RGB sin procesar, lo que requiere más potencia de procesamiento para la carga y más RAM después. Muchos motores modernos optan por almacenar el mismo formato en el disco que en la memoria, lo que lleva a archivos que tienen el mismo tamaño que los requisitos de memoria de la textura (pero también más grandes que PNG o JPG). RGB / RGBA y S3TC / DXTn / BCn son los formatos más utilizados, ya que se leen directamente en la memoria sin ningún procesamiento (las texturas DXT están precomprimidas).

Entonces, estos son los tamaños para diferentes formatos de textura comunes:

  • L (luminancia, p. Ej. Escala de grises): ancho * alto * 1 byte.
  • LA (luminancia y alfa, común para fuentes): ancho * alto * 2 bytes.
  • RGB (color, sin alfa): ancho * alto * 3 bytes.
  • RGBA (color con alfa): ancho * alto * 4 bytes.
  • DXT1 / BC1 (color, alfa binario): (ancho * alto * 4 bytes) / 8 (relación de compresión 8: 1).
  • DXT3 / BC2 (color, alfa nítido) / DXT5 / BC3 (color, alfa degradado): (ancho * alto * 4 bytes) / 4 (relación de compresión 4: 1).

Si usa una imagen con mipmaps , la textura requerirá 4/3 de memoria. Además, el ancho y la altura de la textura pueden redondearse internamente para ser una potencia de dos en el hardware antiguo o menos capaz, y en un hardware muy limitado, también forzado a ser un cuadrado.

Más información sobre DXT: es una compresión con pérdida; Esto significa que algunos datos de color se pierden al comprimir la textura. Esto tiene un impacto negativo en su textura, distorsionando los bordes afilados y creando "bloques" en los gradientes; pero los beneficios son mucho mejores que las desventajas (si tiene una textura que se ve terriblemente mal en DXT, simplemente manténgala sin comprimir; las otras compensarán la pérdida de tamaño). Además, dado que los píxeles están comprimidos por bloques de tamaño fijo, el ancho y la altura de la textura deben ser múltiplos de cuatro.

r2d2rigo
fuente
Esto es correcto, excepto su primera oración: el formato de la textura en el disco puede ser cualquier formato altamente comprimido, por lo que no ocupa el mismo espacio en el disco que en VRAM, excepto en los formatos de disco que son serializaciones directas de los formatos de memoria.
Por supuesto que puede, pero verifique los recursos utilizados en los juegos creados con Unreal Engine, Source, etc. No suelen estar comprimidos en el disco, porque hoy en día hay espacio en disco más que suficiente para dejar los recursos sin comprimir; y el espacio ahorrado no compensa el tiempo adicional de RAM y CPU necesario para descomprimir los archivos en cada carga.
r2d2rigo
1
Creo que encontrarás que varía de un motor a otro. Muchos de los motores más grandes, especialmente aquellos que funcionan en consolas, usarán un formato de disco idéntico o cercano al formato de memoria. Pero es bastante fácil encontrar juegos solo para PC que se envían con recursos PNG o JPEG. Si tiene que ir al disco para una carga que dominará su tiempo de todos modos. Además, Mike menciona específicamente PNG y JPEG como formato de disco.
Principalmente correcto, excepto que los formatos RGB normalmente no existen en las GPU; ver: opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads
Maximus Minimus
9

Obviamente: depende del formato.

Tomemos una textura cuadrada de 256 por 256 píxeles. Si está sin comprimir de 32 bits con un canal alfa ( Coloren XNA), entonces toma 256 KB ( 256*256*4bytes).

Los formatos de 16 bits (p. Ej . :)Bgr565 obviamente tendrán la mitad del tamaño: 128 KB .

Luego llegas a los formatos comprimidos. En XNA tienes DXT1, DXT3 y DXT5 (también conocido como Compresión S3 ). Este es un formato de compresión con pérdida. También es un formato basado en bloques, lo que significa que puede tomar muestras de él (porque sabe en qué bloque está un píxel). También es más rápido porque usa menos ancho de banda.

La relación de compresión de DXT1 es 8: 1 y para DXT3 y DXT5 es 4: 1.

Entonces, una imagen DXT1 de 256x256 es 32KB . Y DXT3 o DXT5 es de 64 KB .

Y luego está el mipmapping . Si esto está habilitado, esto crea una serie de imágenes en la memoria gráfica cada mitad del tamaño de la anterior. Entonces, para nuestra imagen de 256x256: 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2, 1x1. Una textura con mipmapping es aproximadamente el 133% del tamaño del original.

Andrew Russell
fuente
4

La mayoría de las GPU solo pueden leer un formato de compresión muy específico. p.ej. BC *, DXT *, no formatos como png. Entonces, sí, es cierto en su mayor parte que un .png ocupará más espacio en la memoria de video que en el disco.

Las texturas se pueden almacenar comprimidas o sin comprimir tanto en la memoria de video como en la memoria del sistema.

Para texturas sin comprimir, la regla general es que ocupará la misma cantidad de espacio en la memoria de video que en la forma sin comprimir de la memoria del sistema.

Para texturas comprimidas DXT1. la GPU almacena 8 bytes para cada mosaico 4x4 en su textura. Los datos sin comprimir (a 8 bits por canal RGB) normalmente serían 4x4x3 = 48 bytes, por lo que es una relación de compresión de 6: 1. Para las texturas comprimidas DXT3 / DXT5, la GPU almacena 16 bytes por cada mosaico 4x4 en su textura. Esa es una relación de compresión ligeramente menor de 3: 1.

Hay algunas advertencias con texturas sin comprimir y comprimidas:

  • La mayor parte de la memoria se asigna en páginas (cuyo tamaño varía entre las GPU) de un tamaño fijo. p.ej. 4KB y, a menudo, eso no está subasignado y compartido con otros datos de gpu. Es decir. Si su huella de textura es más pequeña que el tamaño de la página, la huella en la memoria de video a menudo seguirá siendo el tamaño de la página.

  • Algunos gpus tienen requisitos de alineación muy específicos. En el pasado, algunas GPU tenían el requisito de que las texturas tuvieran una potencia de 2 en tamaño. Esto a menudo se requería para admitir una representación borrosa (ver Morton Ordering: http://en.wikipedia.org/wiki/Z-order_(curve )) para mejorar la localidad de acceso al tomar muestras de la textura. Esto significaba que las texturas de tamaños impares se rellenarían para preservar estos requisitos (generalmente, el controlador maneja este relleno). Si bien el orden de morton no se usa necesariamente en gpus modernos, todavía puede haber hinchazón para respaldar los requisitos específicos de la gpu.

  • Pueden existir múltiples representaciones de su textura en la memoria en cualquier momento, especialmente si está usando bloqueos de descarte en ellas. Esto puede aumentar el uso de su memoria hasta que la gpu ya no use representaciones (que generalmente se encuentran unos pocos fotogramas detrás del procesamiento de la CPU)

  • Si habilita mipmapping, los mips adicionales consumirán en promedio alrededor de un tercio del nivel base de mip. YMMV basado en las advertencias anteriores.

jpaver
fuente
0

AFAIK es el ancho * alto * BPP de las imágenes, independiente si es PNG, JPG o BMP. No sé cómo se distribuyen DDS u otros formatos comprimibles.

Mip-mapping aumentará la necesidad de memoria de video para.

Mi conocimiento en este tema puede estar un poco desactualizado. He abandonado el 3D hace un tiempo.

ermitaño
fuente
2
Las imágenes también tienen un tono (o zancada), que es la cantidad de bytes entre el final de una línea y el comienzo de la siguiente línea de píxeles. Nadie más ha mencionado esto, así que podría estar equivocado.
CiscoIPPhone el
1
Por lo general, "tono" se refiere a la longitud de una línea de exploración en bytes (como en Freetype y SDL), y "paso" se refiere al espacio entre elementos, que pueden ser píxeles o líneas de exploración (como en OpenGL y el argumento de la tercera porción de Python). Ambos valores son necesarios para hacer el procesamiento de imágenes, pero "generalmente" pitch = ancho * bytes_per_pixel y stride = 0. Los términos a menudo se usan de forma flexible y confusa, por lo que es mejor consultar los documentos API para la biblioteca de su elección.