N'est-ce pas exactement ce que faisait OpenGL sans le shader de géométrie?
Non, ça ne l'est pas. La GS est une étape facultative , pas une étape qui a une valeur par défaut.
Pour qu'OpenGL exécute un shader de géométrie , il doit effectuer ce que l'on appelle un « assemblage primitif ». Lorsque vous effectuez le rendu d'une série de triangles via GL_TRIANGLE_STRIP
, OpenGL fera des trucs internes pour convertir tous les 3 sommets adjacents en un triangle individuel, en modifiant l'ordre d'enroulement de manière appropriée.
Normalement, lorsque vous n'utilisez pas de GS, ce processus est effectué une fois. Cependant, lorsque vous utilisez une GS, elle doit être effectuée avant l'exécution de la GS. Mais elle doit également être effectuée après la GS, car une GS peut produire un type primitif totalement différent (par exemple des quads).
Alors maintenant, vous faites en sorte que le système fasse un tas de travail supplémentaire pour rien. Après tout, OpenGL ne peut pas supposer que votre GS ne fait rien (c'est un problème indécidable).
De plus, un certain nombre d'optimisations ne fonctionnent plus en présence d'un GS. Considérez le rendu indexé.
Chaque index d'un tampon de tableau d'éléments produira les mêmes sorties d'un vertex shader. Ainsi, le GPU mettra souvent ces sorties en cache dans un cache post-T&L . S'il voit un index qui est déjà dans le cache, le VS n'est pas exécuté à nouveau; il récupère simplement les données du cache.
Qu'Est-ce que c'est"? "It" est ... l' unité d'assemblage primitif . Oui, cette chose qui s'exécute deux fois lorsque vous utilisez une GS. Les trucs de mise en cache d'index? Cela ne fonctionne que pour les entrées du GS.
Qu'advient-il donc des sorties de la GS? Eh bien, cela dépend du matériel. Mais il doit aller dans une sorte de tampon mémoire. Et c'est là que réside le problème: ce tampon n'est pas du tout indexé. C'est comme une situation glDrawArrays.
Donc, si vous envoyez un tampon d'index de 0, 1, 2, 0, 2, 3
, cela se traduirait par 4 sommets dans le cache post-T & L. Mais le tampon de sommets post-GS contient désormais 6 sommets. Le tampon post-GS utilise plus d'espace. Donc, si vous avez du mal à créer des listes ou des bandes de triangle optimisées post-T & L et que vous basculez sur une GS pass-through comme la vôtre, vous avez essentiellement tué environ la moitié de vos gains de performances grâce à cette optimisation.
Ce n'était pas inutile, mais ça fait mal.
À cela s'ajoute le fait que de nombreux GPU de classe GL 3.x (aka: DX10) avaient des tampons post-GS plutôt petits. Plus le tampon est petit, moins vous pouvez activer simultanément GS invocations. Ainsi, votre matériel est efficacement goulot d'étranglement sur la GS. Étant donné que la tessellation est une caractéristique importante du matériel de classe 4.x, la plupart de ces matériels ont des tampons suffisants pour rendre viable l'utilisation de GS plus lourdes.
Ainsi, l'utilisation d'un GS est plus susceptible de goulot d'étranglement de votre traitement de vertex de code. Bien sûr, vous pouvez toujours utiliser cela à votre avantage en complexifiant vos shaders de vertex et de fragments, car il s'agit simplement de performances gratuites à ce stade.
Pour plus d'informations sur les ralentissements induits par GS, lisez cet article .
Voici une règle de base à propos des GS: n'utilisez jamais de GS car vous pensez que cela rendra le rendu plus rapide . Vous devez l'utiliser lorsque cela rend possible ce que vous essayez de faire . Si ce que vous essayez de faire est une optimisation, utilisez autre chose.
Les exceptions générales à cette règle sont les suivantes:
layout(points) in;
? Ou est-ce la taille de sortie fixe? Ou peut-être les deux?