Combien de mémoire une texture occupe-t-elle sur le GPU?

9

Un grand png sur disque ne peut prendre que quelques mégaoctets mais j'imagine que sur le gpu le même png est stocké dans un format non compressé qui prend beaucoup plus d'espace. Est-ce vrai? Si c'est vrai, combien d'espace?

Mike
la source

Réponses:

16

Les fichiers JPG et PNG seront presque toujours plus petits sur le disque qu'en mémoire; ils doivent être décompressés à la volée pour acquérir des données RVB brutes, nécessitant ainsi plus de puissance de traitement pour le chargement et plus de RAM par la suite. De nombreux moteurs modernes choisissent de stocker le même format sur disque que dans la mémoire, ce qui conduit à des fichiers de la même taille que les besoins en mémoire de la texture (mais également plus grands qu'un PNG ou JPG). RGB / RGBA et S3TC / DXTn / BCn sont les formats les plus utilisés, car ils sont lus directement dans la mémoire sans aucun traitement (les textures DXT sont précompressées).

Voici donc les tailles des différents formats de texture courants:

  • L (luminance, par exemple niveaux de gris): largeur * hauteur * 1 octet.
  • LA (luminance et alpha, commun pour les polices): largeur * hauteur * 2 octets.
  • RVB (couleur, pas d'alpha): largeur * hauteur * 3 octets.
  • RGBA (couleur avec alpha): largeur * hauteur * 4 octets.
  • DXT1 / BC1 (couleur, alpha binaire): (largeur * hauteur * 4 octets) / 8 (taux de compression 8: 1).
  • DXT3 / BC2 (couleur, alpha net) / DXT5 / BC3 (couleur, dégradé alpha): (largeur * hauteur * 4 octets) / 4 (taux de compression 4: 1).

Si vous utilisez une image avec des mipmaps , la texture nécessitera 4/3 de mémoire. De plus, la largeur et la hauteur de la texture peuvent être arrondies en interne pour être une puissance de deux sur du matériel ancien ou moins performant, et sur du matériel très limité, également forcé d'être un carré.

Plus d'informations sur DXT: c'est une compression avec perte; cela signifie que certaines données de couleur sont perdues lors de la compression de la texture. Cela a un impact négatif sur votre texture, déformant les bordures nettes et créant des "blocs" sur les dégradés; mais les avantages sont bien meilleurs que les inconvénients (si vous avez une texture qui a l'air horriblement mauvaise dans DXT, gardez-la simplement non compressée; les autres compenseront la perte de taille). De plus, comme les pixels sont compressés par des blocs de taille fixe, la largeur et la hauteur de la texture doivent être un multiple de quatre.

r2d2rigo
la source
C'est correct sauf pour votre première phrase - le format de la texture sur le disque peut être n'importe quel format hautement compressé, et donc il ne prend pas le même espace sur le disque qu'en VRAM, sauf pour les formats de disque qui sont des sérialisations directes des formats de mémoire.
Bien sûr, mais vérifiez les ressources utilisées dans les jeux construits avec Unreal Engine, Source, etc. Ils ne sont généralement pas compressés sur le disque, car de nos jours, il y a plus qu'assez d'espace disque pour laisser les ressources non compressées; et l'espace économisé ne compense pas la RAM supplémentaire et le temps CPU nécessaires pour décompresser les fichiers à chaque chargement.
r2d2rigo
1
Je pense que vous constaterez que cela varie d'un moteur à l'autre. La plupart des moteurs plus gros - en particulier ceux qui fonctionnent sur les consoles - utiliseront un format de disque identique ou proche du format de mémoire. Mais il est assez facile de trouver des jeux PC uniquement livrés avec des actifs PNG ou JPEG. Si vous devez aller sur le disque pour une charge qui va de toute façon dominer votre temps. De plus, Mike mentionne spécifiquement PNG et JPEG comme format de disque.
Généralement correct, sauf que les formats RVB n'existent normalement pas réellement sur les GPU; voir: opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads
Maximus Minimus
9

Évidemment: cela dépend du format.

Prenons une texture carrée de 256 par 256 pixels. S'il est non compressé 32 bits avec un canal alpha ( Colordans XNA), cela prend 256 Ko ( 256*256*4octets).

Les formats 16 bits (par exemple Bgr565:) auront évidemment la moitié de la taille - 128 Ko .

Ensuite, vous accédez aux formats compressés. Dans XNA, vous avez DXT1, DXT3 et DXT5 (également connu sous le nom de compression S3 ). Il s'agit d'un format de compression avec perte. C'est également un format basé sur des blocs - ce qui signifie que vous pouvez en échantillonner (car vous savez dans quel bloc se trouve un pixel). C'est aussi plus rapide, car vous utilisez moins de bande passante.

Le taux de compression de DXT1 est de 8: 1 et pour DXT3 et DXT5 est de 4: 1.

Donc, une image DXT1 de 256x256 fait 32 Ko . Et DXT3 ou DXT5 est de 64 Ko .

Et puis il y a le mipmapping . Si cette option est activée, cela crée une série d'images dans la mémoire graphique chaque moitié de la taille de la précédente. Donc, pour notre image 256x256: 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2, 1x1. Une texture avec mipmapping représente environ 133% de la taille de l'original.

Andrew Russell
la source
4

La plupart des GPU ne peuvent lire qu'un format de compression très spécifique. par exemple. BC *, DXT *, pas des formats comme png. Alors oui, il est vrai pour la plupart qu'un .png prendra plus d'espace dans la mémoire vidéo que sur le disque.

Les textures peuvent être stockées compressées ou non compressées dans la mémoire vidéo et la mémoire système.

Pour les textures non compressées, la règle générale est qu'elle prendra la même quantité d'espace dans la mémoire vidéo que sous forme non compressée dans la mémoire système.

Pour les textures compressées DXT1. le GPU stocke 8 octets pour chaque tuile 4x4 dans votre texture. Les données non compressées (à 8 bits par canal RVB) seraient normalement 4x4x3 = 48 octets, donc c'est un taux de compression de 6: 1. Pour les textures compressées DXT3 / DXT5, le GPU stocke 16 octets pour chaque tuile 4x4 dans votre texture. C'est un taux de compression légèrement inférieur de 3: 1.

Il y a quelques mises en garde avec les textures non compressées et compressées:

  • La plupart de la mémoire est allouée en pages (dont la taille varie entre les GPU) de taille fixe. par exemple. 4Ko et souvent ce n'est pas sous-alloué et partagé avec d'autres données GPU. C'est à dire. si votre empreinte de texture est inférieure à la taille de la page, l'empreinte dans la mémoire vidéo sera souvent toujours la taille de la page.

  • Certains gpus ont des exigences d'alignement très spécifiques. Dans le passé, certains GPU exigeaient que les textures aient une puissance de 2. Cela était souvent nécessaire pour prendre en charge une représentation accélérée (voir Morton Ordering: http://en.wikipedia.org/wiki/Z-order_(curve )) pour améliorer la localité d'accès lors de l'échantillonnage à partir de la texture. Cela signifiait que les textures de tailles impaires seraient rembourrées afin de préserver ces exigences (généralement ce rembourrage est géré par le pilote). Bien que l'ordre morton ne soit pas nécessairement utilisé dans les GPU modernes, il peut encore y avoir des ballonnements pour soutenir les exigences spécifiques du GPU.

  • Plusieurs représentations de votre texture peuvent exister en mémoire à tout moment, en particulier si vous utilisez des verrous de suppression. Cela peut gonfler votre utilisation de la mémoire jusqu'à ce que les représentations ne soient plus utilisées par le processeur graphique (qui est généralement à quelques images derrière le rendu du processeur)

  • Si vous activez le mipmapping, les mips supplémentaires consommeront en moyenne environ un tiers du niveau de mip de base. YMMV basé sur les mises en garde ci-dessus.

jpaver
la source
0

AFAIK c'est les images largeur * hauteur * BPP, indépendant si c'est un PNG, JPG ou BMP. Je ne sais pas comment le DDS ou d'autres formats compressables sont disposés.

Le mip-mapping augmentera le besoin de mémoire vidéo.

Mes connaissances dans ce sujet peuvent être un peu dépassées. J'ai abandonné la 3D il y a quelque temps.

ermite
la source
2
Les images ont également un pas (ou une foulée), qui est la quantité d'octets entre la fin d'une ligne et le début de la ligne suivante de pixels. Personne d'autre ne l'a mentionné pour que je puisse me tromper.
CiscoIPPhone
1
Habituellement, "pitch" fait référence à la longueur d'une ligne de balayage en octets (comme dans Freetype et SDL), et "stride" fait référence à l'espace entre les éléments, qui peut être des pixels ou des lignes de balayage (comme dans OpenGL et le troisième argument de tranche de Python). Les deux valeurs sont nécessaires pour effectuer le traitement d'image, mais "généralement" pitch = width * bytes_per_pixel et stride = 0. Les termes sont souvent utilisés de manière lâche et confus, il est donc préférable de vérifier les documents API pour la bibliothèque de votre choix.