Ich entwickle ein großes Spiel, das Level-Daten (einschließlich Shadern) einströmt, während du dich durch die Spielwelt bewegst. Ich möchte keine Probleme mit meiner Framerate haben, da Shader kompiliert / verlinkt sind oder wenn sie zum ersten Mal benutzt werden.
Ich habe meine Shaderkompilierung und -verknüpfung an einem separaten Thread mit einem eigenen open-gl-Kontext gearbeitet. Aber ich konnte die Vorerwärmung der Shader nicht auf den separaten Thread anwenden (so dass es keinen Leistungseinbruch gibt, wenn der Shader zum ersten Mal verwendet wird).
Die Vorwärmung wird nirgendwo in den iOS- oder OpenGL-Dokumenten erwähnt. Es wird jedoch im OpenGL ES Analyzer erwähnt (eines der Instrumente, die beim Profiling von xcode zur Verfügung stehen). In diesem Tool erhalte ich eine "Shader Compiled Outside of Prewarming Phase", die jedes Mal, wenn etwas gerendert wird, mit einem Shader angezeigt wird, der noch nicht zum Rendern von etwas verwendet wurde. Das "Erweiterte Detail" sagt das:
"OpenGL ES Analyzer hat eine Shader-Kompilierung entdeckt, die nicht Teil einer ersten Vorwarnungsphase ist. Die Shader-Kompilierung kann eine zeitaufwendige Operation sein. Um sie zu vermeiden, sollten Sie alle Shader für das Rendering vorwarnen Die Anwendung startet und führt einen Zeichnungsaufruf mit jedem der zu verwendenden Shader-Programme aus, wobei alle gl-Zustandseinstellungen verwendet werden, mit denen das Shader-Programm verwendet wird: Zustände wie Überblenden, Farbmaske, Logikoperationen, Mehrfachübersetzung, Texturformate und Punkt primitiver Zustand kann die Shader-Kompilierung beeinflussen. "
Der Begriff "Kompilierung" ist hier etwas verwirrend. Die Vertex- und Fragment-Shader wurden bereits kompiliert und das Programm wurde verlinkt. Aber das erste Mal, dass etwas mit einem gegebenen OpenGL-Status gerendert wird, macht es mehr Arbeit an dem Shader, um es für diesen Zustand zu optimieren, denke ich.
Ich habe Code, um die Shader vorzuwärmen, indem ich vor der ersten Verwendung ein Dreieck mit einer Größe von null rendert.
Wenn ich die Shader im Hauptthread mit dem gleichen Open GL-Kontext wie das normale Rendering kompiliere, verknüpfe und vorwarne, funktioniert es. Wenn ich es jedoch im Hintergrundthread mit seinem separaten OpenGL-Kontext mache, funktioniert es nicht (es wird immer noch die Analyzer-Warnung bei der ersten Verwendung erhalten).
Also ... könnte es sein, dass die Vorerwärmung eines Shaders in einem separaten Kontext keine Auswirkungen auf andere Kontexte hat. Oder es könnte sein, dass ich nicht den ganzen Staat den separaten Kontext eingerichtet habe. Es gibt viele mögliche Open GL-Status, die möglicherweise eingerichtet werden müssen. Ich verwende einen Offscreen-Render-Puffer im Hintergrund-Thread, der als Teil des Status angesehen werden kann.
Ist es jemandem gelungen, die Vorwärmung an einem Hintergrund-Thread zu arbeiten?
Um ehrlich zu sein, war ich in dieser Angelegenheit bis gestern ziemlich ignorant, obwohl ich eine Weile an meiner Motoroptimierung gearbeitet habe. Also, zuerst einmal vielen Dank für den Tipp:).
Ich habe seitdem das Shader-Erwärmungsthema studiert und ich habe nicht viel gefunden.
Ich habe die offizielle AMD-Dokumentation in einem Dokument mit dem Titel "ATI OpenGL Programming and Optimization Guide" erwähnt:
Dies ist ein Auszug, der sich auf die Erwärmung der Shader bezieht:
Quote:
Der R500 unterstützt nativ die Flusssteuerung in der Fragment-Shading-Einheit R300 und R400 Asics nicht. Die statische Flusskontrolle für den R300 und R400 wird durch das Zusammenstellen des Treibers emuliert unbenutzte Bedingungen und Abroll-Schleifen basierend auf den eingestellten Konstanten. Obwohl die R500 Asics-Familie nativ unterstützt die Flusskontrolle, der Treiber wird trotzdem versuchen, statische Flussbedingungen zu kompilieren um Shader-Anweisungen für eine bessere Befehlsplanung neu zu organisieren. Der Treiber versucht auch zu cachen weg von dem kompilierten Shader für eine bestimmte statische Flussbedingung, die in Erwartung ihrer Wiederverwendung gesetzt wird. Also wann Wenn Sie ein Fragmentprogramm schreiben, das die statische Ablaufsteuerung verwendet, wird empfohlen, den Shader-Cache zu "erwärmen" durch Rendern eines Dummy-Dreiecks auf dem allerersten Frame, der die allgemeine statische Bedingung verwendet Permutationen relevant für das Leben des Shaders.
Die beste Erklärung, die ich gefunden habe, ist die folgende:
Quote:
Übrigens ist dies auch der Grund, warum Sie oft eine Verzögerung sehen, wenn Sie zum ersten Mal einen neuen Shader oder eine neue Ressource verwenden. Viele der Erstellungs- / Kompilierungsarbeiten werden vom Treiber verzögert und nur ausgeführt, wenn es wirklich notwendig ist (Sie würden nicht glauben, wie viel unbenutzter Mist manche Apps erzeugen!). Grafikprogrammierer kennen die andere Seite der Geschichte - wenn Sie sicherstellen möchten, dass tatsächlich etwas erstellt wird (im Gegensatz zum reservierten Speicher), müssen Sie einen Dummy-Zeichnungsaufruf ausgeben, der ihn zum "Aufwärmen" verwendet. Hässlich und nervig, aber das war der Fall, seit ich 1999 angefangen habe, 3D-Hardware zu benutzen - was bedeutet, dass es bis zu diesem Punkt eine Tatsache des Lebens ist, also gewöhne dich daran. :)
In dieser Präsentation wird erwähnt, wie das Kryck-System es auf der Fern-Engine durchgeführt hat, obwohl es hauptsächlich mit DirectX verwandt ist.
Ich hoffe, dass diese Links in gewisser Weise helfen.