2013-05-31 10 views
5

Ich stelle diese Frage, weil ich nicht Zeit mit dem Schreiben von Code verbringen möchte, der die Funktionalität der OpenGL-Treiber dupliziert.Verwirrung in Bezug auf Speicherverwaltung in OpenGL

Kann der OpenGL-Treiber/Server mehr Daten als die Grafikkarte speichern? Ich habe genug Video-RAM, um 10 Texturen zu speichern. Kann ich OpenGL bitten, 15 Texturen zuzuordnen, ohne einen GL_OUT_OF_MEMORY Fehler zu bekommen?

Wenn ich mich darauf verlassen kann, dass der Treiber geschickt die Texturen/Puffer/Objekte aus dem 'normalen' RAM in den Video-RAM sendet, dann brauche ich diese Objekte nicht wirklich selbst zu erzeugen/löschen. Ich werde durch den "normalen" RAM eingeschränkt, der im Vergleich zum Video-RAM oft reichlich vorhanden ist.

+3

Da die Speicherverwaltung vom System abhängt (kann von System zu System unterschiedlich sein) und mehrere Anwendungen OpenGL gleichzeitig verwenden können, können Sie nicht einmal sicher sein, dass Sie den gesamten Speicher der Grafikkarte nutzen können. Sie würden also nicht um ein eigenes _Ressourcenmanagement_ herumkommen. Dies könnte von Interesse für Sie sein: [Ermitteln des verfügbaren Videospeichers] (http://StackOverflow.com/questions/4552372/Ermitteln-Vorhanden-Video-Memory) –

+1

Ja, der Treiber sollte das tun. Es wird jedoch wahrscheinlich sehr langsam sein, sobald es beginnt Texturen zu tauschen. – jcoder

Antwort

3

Einige zusätzliche Informationen zu meinem Kommentar, die nicht hineinpassen.

Es gibt verschiedene Gründe, warum dies nicht Teil von OpenGL ist.

Es ist keine leichte Aufgabe für das System/den Fahrer zu erraten, welche Ressourcen benötigt werden und werden. Der Treiber könnte mit Sicherheit eine interne Heuristik erzeugen, wenn die Ressource oft oder selten benötigt wird (wie es die CPU für if Anweisungen tut und die Ausführung bestimmter Code-Teile vornimmt). Aber die GPU weiß nicht (ohne den Anwendungscode zu wissen), welche Ressource als nächstes benötigt wird. Es hat sogar keine Kenntnis, wo die Geometrie Orte in der Szene ist (weil Sie dies mit Ihrem Modell tun und Martix anzeigen, das Sie selbst an Ihren Shader übergeben)

Wenn Sie z.B. Wenn Sie ein Spiel haben, in dem Sie durch eine Szene gehen können, rendern Sie normalerweise nicht die Teile, die nicht in der Ansicht sind. So könnte die GPU denken, dass diese Ressourcen nicht mehr benötigt werden, aber wenn Sie sich dann umdrehen, werden alle diese Texturen und Geometrien wieder benötigt und müssen von Systemspeicher GPU Speicher verschoben werden, was zu einer wirklich schlechten Leistung führen könnte . Aber die Game Engine selbst hat aufgrund der Verwendung von Octrees (oder ähnlichen Techniken) und der möglichen Wege, die man gehen kann, ein tiefgehendes Wissen über die Szene und welche Ressource könnte von der GPU entfernt werden und wohin man gehen könnte die GPU während der Wiedergabe und wo es notwendig wäre, einen Ladebildschirm anzuzeigen. Wenn Sie sich die Entwicklung von OpenGL anschauen und welche Funktionen veraltet sind, werden Sie sehen, dass sie in die Richtung gehen, um alles außer den wirklich benötigten Features zu entfernen, die am besten von der Grafikkarte, dem Treiber und dem System erledigt werden können. Alles andere bleibt dem Benutzer überlassen, um die beste Leistung zu erzielen. (Sie erstellen z. B. Ihre Projektionsmatrix selbst, um sie an den Shader zu übergeben, sodass OpenGl nicht einmal weiß, wo das Objekt in der Szene platziert ist).

+0

Das macht sehr viel Sinn. Ich habe noch nie OpenGL vor 3.3 angefasst, also weiß ich nicht, wie aufgebläht es früher war. Ich werde dann meinen eigenen Caching-Mechanismus erstellen, da ich weiß, was wann benötigt wird, und ich bin froh, dass ich nicht wirklich berücksichtigen muss, was OpenGL hinter meinem Rücken tut. – Niriel

+0

@Niriel Nun, es ist eine dünne Linie, auf der einen Seite ist es nützlich zu wissen, was hinter den Kulissen getan wird, um zu sehen, was zu Engpässen führen könnte (zB wenn man Textur-Lookups oder Attribut-Divisor verwendet, wenn man Multiple-Instanzen zeichnet) Mit einem Aufruf oder wenn eine Neustrukturierung des Problems eine stärkere Parallelisierung auf der GPU ermöglichen würde, birgt es andererseits das Risiko, für eine Systemimplementierung oder eine bestimmte Anbieter-GPU zu optimieren, anstatt das Problem neu zu überdenken. –

7

Der Ansatz "Speicher ist reichlich, so dass ich nicht löschen muss" ist schlecht, und der Ansatz "Speicher ist reichlich, so dass ich nie aus dem Speicher Fehler bekomme" ist fehlerhaft.

OpenGL Speicherverwaltung ist obskur, sowohl aus technischen Gründen (siehe t.nieses Kommentar oben) und aus ideologischen Gründen ("du musst es nicht wissen, du willst es nicht wissen"). Es gibt zwar Herstellererweiterungen (z. B. ATI_meminfo), mit denen Sie einige nicht autorisierende-Nummern abfragen können (nicht autorisierend, sofern sie die nächste Millisekunde ändern könnten, und sie berücksichtigen keine Auswirkungen wie Fragmentierung).

Im Allgemeinen ist Ihre Annahme, dass Sie mehr Speicher als GPU-Speicher verwenden können, korrekt.

Sie können jedoch normalerweise nicht den gesamten verfügbaren Speicher verwenden.Wahrscheinlicher ist, dass aufgrund von Beschränkungen, welche Speicherbereiche (und wie große Bereiche) der Treiber zuordnen, sperren und zu welchem ​​DMA gehören kann, ein Grenzwert deutlich unter "allen verfügbaren RAM" liegt. Und obwohl Sie normalerweise mehr Speicher verwenden können, als auf die GPU passt (selbst wenn Sie es ausschließlich verwendet haben), bedeutet dies nicht, dass unvorsichtige Zuordnungen nicht können und nicht schließlich fehlschlagen.

Normalerweise, aber nicht unbedingt, verbrauchen Sie so viel Systemspeicher wie GPU-Speicher (ohne es zu wissen, tut der Treiber das heimlich). Da der Treiber Ressourcen nach Bedarf ein- und austauscht, muss eine Kopie erstellt werden. Manchmal ist es notwendig, 2 oder 3 Kopien zu behalten (z. B. beim Streaming oder für ARB_copy_buffer-Operationen). Manchmal ist das Zuordnen eines Pufferobjekts eine weitere Kopie in einem speziell zugewiesenen Block, und manchmal dürfen Sie direkt in den Speicher des Treibers schreiben. Auf der anderen Seite ist PCIe 2.0 (und PCIe 3.0 noch mehr) schnell genug, um Vertices aus dem Hauptspeicher zu streamen, so dass Sie nicht einmal unbedingt GPU-Speicher benötigen (außer einem kleinen Puffer). Einige Treiber streamen dynamische Geometrie direkt aus dem Systemspeicher.

Einige Grafikprozessoren haben nicht einmal einen separaten System- und GPU-Speicher (Intel Sandy Bridge oder AMD Fusion).

Sie sollten auch beachten, dass das Löschen von Objekten sie nicht unbedingt löscht (zumindest nicht sofort). In der Regel ist das Löschen eines OpenGL-Objekts bis auf wenige Ausnahmen nur ein vorläufiges Löschen, das verhindert, dass das Objekt weiter auf das Objekt verweist (Sie). Der Fahrer behält das Objekt so lange wie es nötig ist.

Auf der anderen Seite, sollten Sie wirklich löschen, was Sie nicht mehr benötigen, und Sie sollten früh löschen. Zum Beispiel sollten Sie einen Shader sofort löschen, nachdem Sie ihn an das Programmobjekt angehängt haben. Dies stellt sicher, dass Sie keine Ressourcen verlieren und es funktioniert garantiert. Löschen und Neuangeben des verwendeten Vertex- oder Pixelpuffers beim Streaming (durch Aufrufen von glBufferData(... NULL); ist ein bekanntes Idiom. Dies betrifft nur Ihre Ansicht des Objekts und ermöglicht es dem Treiber, das alte Objekt weiterhin parallel für as zu verwenden . solange es ihn braucht

+0

** + 1 ** für die nette technische Information –

+0

Danke für die Details, es macht jetzt Sinn. Meine erste Idee war, den gesamten verfügbaren Speicher zu verwenden und auf Fehler wegen zu wenig Speicher zu warten, um zu signalisieren, wann ich Dinge löschen/tauschen sollte (bitte um Vergebung und nicht um Erlaubnis). Aber gl_out_of_memory ist nicht wiederherstellbar, so dass ich raten muss/hoffe, dass ich es nicht überfüllen werde. Ich schätze Profiling ist der Weg hierher zu gehen, ich wähle ein Speicherbudget und versuche, drinnen zu bleiben. Ich habe noch nicht mit Vertex-Animation gespielt, so dass ich nicht viel über Streaming weiß und glBufferData (.. null ..) nicht verstehe. Würde es Ihnen etwas ausmachen, das zu erklären? – Niriel

3

Hier ist meine TL; DR Antwort, empfehle ich auch den Daemon zu lesen und t.niese die Antworten:

Kann die OpenGL-Treiber/Server mehr Daten als die Grafikkarte halten

?

Ja

Angenommen, ich habe genug Video-RAM, um 10 Texturen zu speichern. Kann ich OpenGL bitten, 15 Texturen zuzuordnen, ohne einen GL_OUT_OF_MEMORY Fehler zu bekommen?

Ja. Abhängig von der Kombination aus Treiber und Grafikkarte kann es sogar möglich sein, eine einzelne Textur zuzuordnen, die den Speicher der GPU übersteigt, und sie tatsächlich für das Rendern zu verwenden. Bei meiner jetzigen Tätigkeit nutze ich diese Tatsache, um aus volumetrischen großen Datensätzen Schichten beliebiger Orientierung und Geometrie zu extrahieren, indem ich mit Shadern Filter auf die Voxeldaten in situ anlege. Funktioniert gut, funktioniert aber nicht für interaktive Bildraten.