Dies ist eine komplexe Frage mit vielen kleinen Details, die wirklich wichtig sind. Die Leistung variiert je nach Plattform und Anwendung. Sie sollten sich daher auf mögliche Engpässe konzentrieren, bevor Sie in Optimierungen investieren.
Das heißt, erstens gehe ich davon aus, dass Sie Uploads und Updates so weit wie möglich reduzieren sollten, zum Beispiel Instanzen verwenden.
Beachten Sie zweitens, dass GPUs nicht gleichzeitig Puffer übertragen und rendern können, sodass alle OpenGL-Befehle in der Befehlswarteschlange vom Gerät nacheinander verarbeitet werden. Es gibt verschiedene Möglichkeiten, Daten zu kopieren und / oder für die Verwendung durch die GPU verfügbar zu machen.
Es gibt verschiedene Möglichkeiten, Daten zur GPU zu streamen
1- glBufferData
oder glBufferSubData
Methode
Verwenden glBufferData
oder glBufferSubData
ist wie memcpy. Wenn Sie einen Zeiger übergeben, wird möglicherweise eine DMA-Operation ausgeführt, da der Speicher möglicherweise im CPU-Speicher fixiert und direkt von der GPU verwendet wird, ohne dass je nach Verwendungsflag (GL_STREAM) eine Speicherübertragung zur GPU erfolgt. Meiner Meinung nach sollten Sie dies zuerst versuchen, da es einfacher zu implementieren ist.
2- Abrufen eines Zeigers auf den internen Speicher mit glMapBuffer
Wenn das oben Genannte nicht gut genug ist glMapBuffer
, erhalten Sie einen Zeiger auf den internen Speicher, und Sie können diesen Zeiger verwenden, um den Puffer direkt zu füllen. Dies ist gut bei Lese- und Schreibvorgängen für Dateien, da Sie die Dateidaten direkt zuordnen können in den GPU-Speicher anstatt zuerst in einen temporären Puffer zu kopieren. Wenn Sie nicht den gesamten Puffer zuordnen möchten, können Sie glMapBufferRange
einen Teil des Puffers zuordnen.
Ein Trick besteht darin, einen großen Puffer zu erstellen, die erste Hälfte zum Rendern und die zweite Hälfte zum Aktualisieren zu verwenden.
3- Buffer Orphaning
In Bezug auf das Verwaisen von Puffern kann dies mit glBufferData mit null und denselben Parametern erfolgen. Der Treiber gibt den Speicherblock zurück, sobald er nicht verwendet wird. Und wird beim nächsten glBufferData-Aufruf verwendet (es wird kein neuer Speicher zugewiesen).
Alle genannten Methoden verursachen eine Menge teurer Synchronisierungen. Auch hier können GPUs nicht gleichzeitig Puffer übertragen und rendern.
4- Unsynchronized Buffers
Die schnellste (und am schwierigsten zu ermittelnde) Methode besteht darin, Puffer ohne Synchronisation zu verwenden, mit denen Sie das GL_MAP_UNSYNCHRONIZED_BIT
Flag verwenden glMapBufferRange
können. Das Problem besteht darin, dass keine Synchronisierung durchgeführt wird, sodass wir möglicherweise Daten in einen Puffer hochladen, der verwendet wird, und daher alles vermasseln. Sie können mehrere Puffer mit unsynchronem Bit verwenden, um die Arbeit ein wenig zu vereinfachen.