Ist das nicht genau das, was OpenGL ohne den Geometrie-Shader tat?
Nein, das ist es nicht. Der GS ist ein optionaler Schritt, kein Schritt mit Standardeinstellung.
Damit OpenGL einen Geometrie-Shader ausführen kann , muss es eine sogenannte " primitive Assembly " ausführen . Wenn Sie eine Reihe von Dreiecken über rendern GL_TRIANGLE_STRIP
, wandelt OpenGL alle 3 benachbarten Scheitelpunkte in ein einzelnes Dreieck um und ändert die Wicklungsreihenfolge entsprechend.
Normalerweise wird dieser Vorgang einmal ausgeführt, wenn kein GS verwendet wird. Wenn Sie jedoch eine GS verwenden, muss diese ausgeführt werden, bevor die GS ausgeführt wird. Es muss aber auch nach dem GS durchgeführt werden, da ein GS einen völlig anderen primitiven Typ (zB Quads) ausgeben kann.
Jetzt veranlassen Sie das System im Grunde genommen, eine Menge zusätzlicher Arbeit für nichts zu erledigen. Schließlich kann OpenGL nicht davon ausgehen, dass Ihre GS nichts tut (das ist ein unentscheidbares Problem).
Darüber hinaus funktionieren einige Optimierungen bei Vorhandensein einer GS nicht mehr. Betrachten Sie indiziertes Rendern.
Jeder Index aus einem Elementarray-Puffer erzeugt die gleichen Ausgaben von einem Vertex-Shader. Daher speichert die GPU diese Ausgaben häufig in einem Post-T & L-Cache . Wenn ein Index angezeigt wird, der sich bereits im Cache befindet, wird der VS nicht erneut ausgeführt. Es werden nur Daten aus dem Cache abgerufen.
Was ist es"? "Es" ist ... die primitive Montageeinheit . Ja, das Ding, das zweimal ausgeführt wird, wenn Sie eine GS verwenden. Das Index-Caching-Zeug? Es funktioniert nur für die Eingänge der GS.
Was passiert nun mit den Ausgängen der GS? Nun, das ist hardwareabhängig. Aber es muss in eine Art Speicherpuffer gehen. Und darin liegt das Problem: Dieser Puffer ist überhaupt nicht indiziert. Es ist wie in einer glDrawArrays-Situation.
Wenn Sie also einen Indexpuffer von senden 0, 1, 2, 0, 2, 3
, würde dies zu 4 Eckpunkten im Post-T & L-Cache führen. Der Post-GS-Puffer von Vertices enthält jetzt 6 Vertices. Der Post-GS-Puffer benötigt mehr Platz. Wenn Sie sich also die Mühe machen, nach dem Test ordnungsgemäß optimierte Dreieckslisten oder -streifen zu erstellen, und eine Pass-Through-GS wie Ihre umblättern, haben Sie im Grunde genommen etwa die Hälfte Ihres Leistungsgewinns durch diese Optimierung getötet.
Es war nicht nutzlos, aber es tut weh.
Hinzu kommt, dass viele GPUs der GL 3.x-Klasse (auch bekannt als: DX10) eher kleine Post-GS-Puffer hatten. Je kleiner der Puffer, desto weniger GS-Aufrufe können gleichzeitig aktiv sein. Ihre Hardware hat also effektiv Engpässe bei der GS. Da Tessellation ein großes Merkmal von Hardware der 4.x-Klasse ist, verfügen die meisten dieser Hardware über Puffer, die ausreichen, um eine stärkere GS-Nutzung zu ermöglichen.
Die Verwendung eines GS führt daher mit größerer Wahrscheinlichkeit zu Engpässen bei der Verarbeitung von Code-Vertexen. Natürlich können Sie dies immer zu Ihrem Vorteil nutzen, indem Sie Ihre Vertex- und Fragment-Shader komplexer gestalten, da dies zu diesem Zeitpunkt nur eine kostenlose Leistung ist.
Weitere Informationen zu GS-induzierten Verlangsamungen finden Sie in diesem Artikel .
Hier ist eine grundlegende Faustregel für GS: Verwenden Sie niemals eine GS, da Sie denken, dass dies das Rendern beschleunigen wird . Sie sollten es verwenden, wenn es das ermöglicht, was Sie versuchen zu tun . Wenn Sie versuchen, eine Optimierung durchzuführen, verwenden Sie etwas anderes.
Die allgemeinen Ausnahmen sind: