Pourquoi OpenGL> = 3 n'autorise-t-il que les VBO?

21

Je vois que les versions 3 et supérieures d'OpenGL éliminent l'utilisation du rendu côté client. Le mode immédiat a été éliminé et les tableaux de sommets semblent obsolètes. Au lieu de cela, si je comprends bien, les VBO sont le principal moyen de rendre les sommets.

Alors que je vois la logique derrière une manière uniforme de tout rendre, est-ce le cas que les VBO n'ont pas d'inconvénients majeurs sur les tableaux de vertex? Je pensais que les VBO étaient censés être de grands tampons contenant> 1 Mo de données, en général. Et si j'ai une scène qui a beaucoup de géométrie plus petite? J'ai un graphique de scène avec un grand nombre de nœuds, chacun ayant besoin de sa propre transformation, etc. Chaque nœud devrait également pouvoir être supprimé séparément, ajouté séparément, etc. J'utilisais auparavant des tableaux de vertex. Donc, ma première question est de savoir si, si je passe aux VBO, il y aura une surcharge supplémentaire pour mes objets de graphique de scène maintenant, car un VBO doit être alloué pour chaque objet.

Une autre préoccupation est que la géométrie que je rends peut être très dynamique. Dans le pire des cas, il peut arriver que toute la géométrie doive être renvoyée à chaque image pendant une certaine période de temps. Les VBO auront-ils des performances moins bonnes que les tableaux de vertex dans ce cas d'utilisation, ou les VBO au pire fonctionnent-ils tout autant que les tableaux de vertex mais pas plus?

Donc, dans un format plus concis, mes questions sont:

1) Y a-t-il des frais généraux importants pour allouer / désallouer des VBO (je veux dire le simple fait de mettre en place un tampon)?

2) Si je mets à jour les données du CPU à chaque trame, cela peut-il être bien pire que si j'avais utilisé des tableaux de vertex?

Et enfin, j'aimerais savoir:

3) Si la réponse à l'une des questions ci-dessus est "oui", pourquoi déconseiller d'autres modes de rendu qui pourraient avoir des avantages par rapport aux VBO? Y a-t-il quelque chose qui me manque ici, comme des techniques que je suis censé utiliser pour atténuer certains de ces coûts d'allocation potentiels, etc.?

4) Les réponses à l'une de ces questions changent-elles considérablement en fonction de la version d'OpenGL que j'utilise? Si je refactorise mon code pour qu'il soit compatible avec OpenGL 3 ou 4 en utilisant les VBO de manière performante, les mêmes techniques seront-elles susceptibles de bien fonctionner avec OpenGL 2, ou est-il probable que certaines techniques soient beaucoup plus rapides avec OpenGL 3 + et d'autres avec OpenGL 2?

J'ai posé cette question sur le débordement de pile, mais je republie ici parce que j'ai réalisé que ce site pourrait être plus approprié à ma question.

La gravité
la source
1
Pourquoi un vote pour clore? Est-ce un dup? Si oui, puis-je voir un lien pour en bénéficier?
Gravity

Réponses:

23

Y a-t-il des frais généraux importants pour allouer / désallouer des VBO (je veux dire le simple fait de mettre en place un tampon)?

Définissez «substantiel». Il est généralement sage de ne pas les créer au milieu des cadres; ils doivent être configurés lors de l'initialisation ou n'importe où. Mais cela est vrai de la plupart des objets OpenGL, comme les textures, les rendus de tampons ou les shaders.

Si je mets à jour les données du CPU à chaque trame, cela peut-il être bien pire que si j'avais utilisé des tableaux de vertex?

Peut-il? Oui. OpenGL définit la fonctionnalité, pas les performances . Vous pouvez en effet ralentir les choses. Ou vous pouvez accélérer les choses. Tout dépend de la façon dont vous l'utilisez.

Le wiki OpenGL contient un bon article sur la façon de diffuser correctement les données .

Si la réponse à l'une des questions ci-dessus est "oui", pourquoi déconseiller d'autres modes de rendu qui pourraient avoir des avantages par rapport aux VBO? Y a-t-il quelque chose qui me manque ici, comme des techniques que je suis censé utiliser pour atténuer certains de ces coûts d'allocation potentiels, etc.?

Tout d'abord, ils n'étaient pas simplement obsolètes. La dépréciation signifie marquer quelque chose comme "à supprimer" dans les futures versions. Ils ont été dépréciés en 3.0 et supprimés en 3.1 core et au-dessus.

Deuxièmement, l'ARB a généralement expliqué la raison pour laquelle ils ont supprimé des éléments d'OpenGL. Cela rend la spécification plus petite et plus simple. Il rend l'API plus petite et plus rationalisée. Cela permet de savoir plus facilement quelles API vous devez utiliser; 2.1 avait 4 façons de fournir des données de sommet; 3.1+ a 1. Il se débarrasse de beaucoup de cruches. Etc.

Les réponses à l'une de ces questions changent-elles considérablement en fonction de la version d'OpenGL que j'utilise? Si je refactorise mon code pour qu'il soit compatible avec OpenGL 3 ou 4 en utilisant les VBO de manière performante, les mêmes techniques seront-elles susceptibles de bien fonctionner avec OpenGL 2, ou est-il probable que certaines techniques soient beaucoup plus rapides avec OpenGL 3 + et d'autres avec OpenGL 2?

Plus ou moins non. Ce n'est que sur MacOSX que la différence entre les versions 3.1 + core et pré-3.0 est vraiment apparente. Le profil de compatibilité est implémenté par tous les pilotes pour Linux et Windows, vous pouvez donc supposer que le profil de base de ces pilotes ajoute simplement des vérifications pour vous empêcher d'appeler des fonctions de compatibilité.

Sous Mac OSX 10.7, le noyau GL 3.2 est disponible, mais pas le profil de compatibilité. Cela ne signifie pas nécessairement quoi que ce soit pour les techniques de performance de l'un par rapport à l'autre. Mais cela signifie que s'il y a des différences, c'est sur la plate-forme que vous les verrez.

Nicol Bolas
la source
1
Puisque vous venez de poster cette question , je vais simplement poster ma réponse.
Nicol Bolas
Un autre avantage de la concision de l'API est qu'elle facilite la mise en œuvre de l'API OpenGL. C'était une grande considération dans la spécification originale d'OpenGL ES.
notlesh
@stephelton: C'est logique. Ma question "pourquoi tout déprécier sauf les VBO" était basée sur la pensée que bien qu'il soit parfaitement logique de maintenir l'API allégée, il n'est pas logique de déprécier des fonctionnalités qui pourraient être meilleures que les VBO pour de nombreux cas d'utilisation. D'après ce que j'entends, il semble qu'il n'y ait aucun inconvénient à utiliser des VBO, alors il est donc parfaitement logique de déconseiller tout le reste.
Gravity
@gravity Vous ne devez utiliser VBO de. Vous pouvez également utiliser un tableau de sommets.
2012
18

Le fonctionnement d'OpenGL, chaque fois que vous utilisez des données non VBO, le pilote doit en faire une copie - en pratique, créer un VBO temporaire - car rien ne vous empêche de modifier vos tableaux nus de l'espace utilisateur entre les appels à OpenGL.

Il peut y avoir une astuce côté conducteur pour rendre l'allocation temporaire plus rapide, mais vous ne pouvez rien faire pour éviter la copie.

Donc oui, tant que vous - et les développeurs de pilotes - faites tout correctement, les VBO devraient (tm) toujours accélérer les choses.

Jari Komppa
la source
6
J'aime mieux cette réponse. C'est plus court et plus précis, imo.
TravisG
@JariKomppa: Cela ressemble à une explication très raisonnable. J'ai toujours une préoccupation: les VBO sont censés être des objets assez grands, souvent alloués en tant que tampons de 1 Mo à 4 Mo la dernière fois que j'ai vérifié. Que se passe-t-il si mes objets de géométrie ne sont pas si grands, mais je suis toujours préoccupé par les performances car j'ai beaucoup d'objets? Je crains que les VBO ne soient juste pour un cas d'utilisation différent de celui que j'ai. Dois-je regrouper plusieurs objets ensemble dans un seul VBO, puis utiliser glDrawRangeElementspour dessiner chaque objet individuel, ou est-ce inefficace tout comme les tableaux de sommets?
Gravity
Je doute que cela fasse une différence, mais si vous sentez que c'est une préoccupation, comparez-la.
Jari Komppa
@JariKomppa: Qu'est-ce qui, selon vous, fera une différence? Utiliser glDrawRangeElementsplusieurs fois sur chaque VBO avec quelques VBO plutôt que de donner à chaque objet son propre VBO?
Gravity
1
Exactement. Je doute que vous constatiez une grande différence, mais le profilage de certains cas de test devrait vous donner plus d'informations. Je ne m'en inquiéterais pas non plus maintenant, car un tel changement pourrait être appliqué plus tard si nécessaire.
Jari Komppa
9

et les tableaux de vertex semblent obsolètes. Au lieu de cela, si je comprends bien,

Pas assez. Les tableaux de sommets sont le fondement des objets tampon de sommets. Seul le stockage est passé du côté client au côté serveur.

Et si j'ai une scène qui a beaucoup de géométrie plus petite?

Fusionnez des ensembles de géométrie plus petits dans des VBO plus grands. Il n'est pas nécessaire d'avoir un VBO par lot de géométrie. Vous pouvez parfaitement adresser des sous-ensembles d'un VBO pour le rendu. Utilisez un décalage non nul pour le paramètre de données gl… Pointer.

2) Si je mets à jour les données du CPU à chaque trame, cela peut-il être bien pire que si j'avais utilisé des tableaux de vertex?

Pour cela, il y a les drapeaux d'utilisation du tampon GL_DYNAMIC_DRAW et GL_STREAM_DRAW.

Si la réponse à l'une des questions ci-dessus est "oui", pourquoi déconseiller d'autres modes de rendu qui pourraient avoir des avantages par rapport aux VBO?

Parce qu'il n'y a aucun avantage. Dans tous les cas, les données de géométrie doivent être transférées vers le GPU. L'utilisation d'un tableau de sommets côté client normal entraînera toujours un transfert DMA vers le GPU, et le mode immédiat créera également un lot à transférer en premier.

Il n'y a absolument aucun avantage à ne pas utiliser de VBO.

datenwolf
la source
Donc, mes performances ne devraient généralement pas être plus mauvaises avec les VBO qu'avec les vertex arrays, mais uniquement si j'ai correctement défini le mode sur GL_STREAM_DRAW?
Gravity
@Gravity: En effet. Cependant, le mode tampon n'est qu'un indice sur l'utilisation attendue, mais bien sûr, cet indice doit être fidèle à ce que vous allez faire. N'oubliez pas non plus que vous pouvez mapper des tampons dans votre espace d'adressage de processus pour les mises à jour (glMapBuffer, glUnmapBuffer).
datenwolf
mais le tampon ne pouvait pas être en VRAM, non? Ou serait-il toujours en VRAM mais simplement adressable via des adresses d'espace de processus? L'accès aléatoire serait-il bon marché avec cette technique, ou devrais-je quand même essayer de mettre à jour seulement un petit nombre de plages contiguës?
Gravity
@Gravity: un tampon peut être mappé en lecture seule, en écriture seule ou en lecture-écriture. Pour les mises à jour, vous choisissez d'écrire uniquement. Maintenant, il devient important de savoir comment les systèmes d'exploitation modernes gèrent l'espace d'adressage virtuel, notamment via la mémoire paginée. Dans le cas d'une carte en écriture seule, vous êtes mappé sur un morceau de mémoire de transfert DMA et vos écritures sur cette plage mappée iront plus ou moins directement dans la mémoire du GPU (le contenu est d'abord écrit dans la RAM du CPU, puis transféré vers le GPU par DMA transfert). Il est important que ce chemin soit plus direct que si les données transitent par un tableau de vertex côté client: la mémoire de processus normale n'est pas adaptée au DMA
datenwolf