Registriert: Mo Mai 06, 2002 20:27 Beiträge: 479 Wohnort: Bremen
Ich knappse jetzt schon seit Stunden an einem Problem. Meine VBOs scheinen nicht so schnell zu sein wie sie sollen. Zur Demonstration habe ich eine Testanwendung erstellt, bei der nix weiter passiert, als ein Würfel in einem VBO abzulegen und daraus zu rendern. Die Dreiecksleistung meiner Radeon 9700 von 190 Millionen Tris/s wird dabei nicht annähernd erreicht. Ich messe lediglich ca 30 Millionen.
Vielleicht könnt ihr mal gucken, welche Fps ihr mit dem dem Beispiel-Programmhabt? Der Würfel hat nach meiner Rechnung 1,2 Millionen Dreiecke. (Die Auflösung des Würfels lässt sich in der Cubeklasse im Konstruktor einstellen) Wer sich mit VBO's auskennt, findet vielleicht auch den Fehler den ich bis jetzt übersehen habe... ich habe den Quellcode extra nochmal aufgeräumt!
Am fehlenden Treiber-Support kanns eigentlich nicht liegen. Eine andere Beispielanwendung aus dem Netz macht locker 125 Tris/s.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Da ich auf meinem System mit meiner eigenen VBO-Demo schon bis zu 150 MTris/s erreicht habe, hat mich die Performance deiner Demo zuerst erschreckt. Aber ich glaube dein Problem liegt im glDrawArrays, denn dieser Befehl ist im Zusammenhang mit VBOs sehr langsam, und bei deiner Würfelauflösung wird der pro Frame stolze 600 mal aufgerufen. Probiers mal mit anderen Renderkommandos, dann dürfte die Performance eigentlich stark steigen, oder dreh es so, dass du diese 600 Aufrufe durch einen ersetzen kannst.
Registriert: Mo Mai 06, 2002 20:27 Beiträge: 479 Wohnort: Bremen
Ja, das war auch mein erster Gedanke. Leider liegts daran aber nicht. Wenn du die Segmente in X Richtung (XDet) auf 100.000 setzt und die Segmente in Y Richtung auf 1 setzt, hast du die selbe Anzahl an Tris, also grob immer noch 1,2 Millionen aber nur noch 6 Tri-Strips. Und die FPS bleiben weitestgehend Konstant.
Das selbe passiert wenn man anstatt mit Triangle-Strips mit Quads arbeitet, also den kompletten VBO mit nur einem gDrawArrays-Aufruf zeichnen kann. Die Tri-Leistung wird eher noch etwas langsamer! Mein Schluss war deshalb, dass ich aus irgend einem Grunde doch keinen Speicher auf der Grafikkarte bekomme sondern irgendwo im Hauptspeicher und deshalb der AGP-Bus das Nadelöhr ist. Diese Vermutung erhärtet sich durch folgenden Test. Eine Reduktion von AGP4x auf AGB1x bewirkt einen Rückgang der Fps von 24 auf 7. Die Frage ist nur: Warum? Was mach ich falsch?
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Hab wohl dein Problem gefunden, nämlich dein Vertexformat. Habe es mal testweise (weil ich sowas vermutet habe) von T2F_N3F_V3F auf T2F_V3F umgestellt, und siehe da : statt mickriger 26 FPS ( ~31 MTris/s) ists gleich auf 64 FPS ( ~80 MTris/s) gestiegen. Wenn du dann noch Texturemapping deaktiverst (nur mal zu Testzwecken), dann steigts auf 82 FPS ( ~100 Mtris/s) an. Diese Werte können sich also für ein einziges VBO einer solchen Größe sehen lassen.
Liegt also am Vertexformat, das der Radeon wohl im Zusammenhang mit VBOs nicht schmeckt. Warum kann ich dir leider nicht sagen, denn zum einen sind 32 Bit (die T2F_N3F_V3F ja hat) eigentlich ein ideales Alignment, und zum anderen steht selbst in der GL-Programmingguide für Radeons von ATI nix davon drin.
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Hat's geklappt? Würde dir sowieso empfehlen dich komplett vom interleaved Format zu trennen, denn spätestens beim Multitextzuring kannste damit ja nix anfangen. Die beste Lösung sind daher dreit Puffer, einmal für die Vertices, einmal für die Texturkoordinaten (bzw. mehrere wenn man versch. Koordinaten pro TMU braucht) und einmal für die Normalen. Dann kannste die mittels glVertexPointer, glNormalPointer und glTexCoordPointer festlegen. Ist die elegantere und auch flexiblere Lösung.
Registriert: Mo Mai 06, 2002 20:27 Beiträge: 479 Wohnort: Bremen
Ich hatte gelesen, dass Interleaved-Puffer Performance-Vorteile bringen sollen. Aber ich denke mal welche Nutzung der VBO's die effektivste ist, wird sich erst herausstellen, wenn die ersten großen Spiele damit arbeiten und die Treiber entsprechend optimiert werden. Der Standard ist da ja relativ offen!
Ich hatte leider noch nicht wieder Zeit mich weiter damit zu beschäftigen. Im Moment bin ich wegen Ende des Semesters und einiger anderer Angelegenheiten ziemlich ausgebucht. Ich hoffe morgen nochmal dazu kommen zu können. Besonders die Tatsache, dass das vierteln des AGP-Bus die Leistung ebenfalls gedrittelt hat, weist darauf hin, das das VBO nicht (komplett) im Speicher der Graka liegt.
Man kann auch mehrere Arrays interleaved in einem Buffer unterbringen ohne die standard Format zu benutzen, wenn man dieses Offset benutzt.
Da gibt es keine Geschwindigkeitsprobleme. Ob und wieviel das schneller als getrennte Buffer ist, habe ich noch nicht getestet. Vielleicht ist das für den Cache günstiger wenn nur aus einer Stelle des Speichers gelesen werden muß. Dafür ist es aber dann ziemlich unflexibel, falls man einige Komponenten dynamisch ändern möchte oder so was in der Richtung.
Registriert: Mo Mai 06, 2002 20:27 Beiträge: 479 Wohnort: Bremen
So... ich will diesen alten Thread mal wieder aufwärmen.
Um die ganze VBO-Geschichte mal ein bissl besser analysieren zu können habe ich heute Nacht ein kleines Programm geschrieben, in dem wieder der bekannte Würfel gerendert wird. Jetzt kann man allerdings Dreieckszahl, Anzahl der Draw-Array Aufrufe, das Vertexformat, und die Render Methode wählen und benchen. Und das stellt sich als erstaunlich spannend heraus!
Ein Beispiel:
830.000 Tris (1000 Draw Calls)
GL_C4F_N3F_V3F
Interleaved Array bzw ein VBO & Pointer
---> 58 MTris/sec
840.000 Tris (1000 Draw Calls)
GL_C4F_N3F_V3F
Interleaved bzw One VBO & Pointer
---> 24,75 MTris/sec
Mit seperaten VBOs für Pos, Farbe und Normalen bleibt der Durchsatz bei 57 MTris/sec und zwar bis 2.800.000 Tris. also ungefähr dem 3fachen. Ein einzelner VertexBuffer scheint also bei > 33Mb schlapp zu machen.
Auch erstaunlich: Ob ich 1.000.000 Tris mit 6000 oder 6 glDrawArrays rendere macht keinen wesentlichen Unterschied! Ich hätte nicht gedacht, dass Draw-Aufrufe annähernd kostenfrei sind!
Ich fänds interessant, wenn ihr das Toolmal auf euren System ausprobiert und ein bissl herumdeutelt! Der Source ist zwar dabei aber weder kommentiert noch besonders aufgeräumt. Ich werde das ganze aber sicher noch weiterentwickeln!
-lith
EDIT: Ich habe den AGP-Takt auf 1x gesetzt und noch mal geguckt. Bis zu einer Größe von 33Mb bleibt die Performance gleich, ist der VB größer bricht die Performance nicht nur auf 24MTris/sec sondern sogar auf ca 7MTris/sec ein. ---> Offenbar liegt ab dieser größe der VB nicht mehr auf der Grafikkarte. Ist diese Limit in der größe eines VBO eigentlich irgendwo erwähnt?
Also ich hab das Programm mal durchlaufen lassen. Sobald die VBO Size über 32 MB steigt, bekomm ich eine Zugriffsverletzung in der atioglxx.dll. Ich verwende den Ati - Catalyst Treiber 4.4.
Das würde also in der Tat für eine Grenze sprechen, ist das bei Nvidia Karten auch so?
Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.