FSAA? Multisampling?



  • Kustl schrieb:

    Naja, wenn du immer die selbe Geometrie renderst und NUR die Bufferverteilung änderst, kannst du ja CPU-Limit, Transform-Limit, Pixelshaderbelastung, Draw Call-Limit, Raster Output-Performance, Vertex-Cache etc alles ausschließen? Dann bleibt als Resultat, dass es einfach keinen Unterschied macht.

    Wenn Du nur eine Sache änderst, und sich dadurch an der Gesamtperformance nichts ändert, kann das

    a) bedeuten, dass die Sache die Du änderst tatsächlich nix ausmacht
    oder
    b) du durch ganz andere sachen sowieso limitiert bist und es daher egal ist



  • Jester schrieb:

    Kustl schrieb:

    Naja, wenn du immer die selbe Geometrie renderst und NUR die Bufferverteilung änderst, kannst du ja CPU-Limit, Transform-Limit, Pixelshaderbelastung, Draw Call-Limit, Raster Output-Performance, Vertex-Cache etc alles ausschließen? Dann bleibt als Resultat, dass es einfach keinen Unterschied macht.

    Wenn Du nur eine Sache änderst, und sich dadurch an der Gesamtperformance nichts ändert, kann das

    a) bedeuten, dass die Sache die Du änderst tatsächlich nix ausmacht
    oder
    b) du durch ganz andere sachen sowieso limitiert bist und es daher egal ist

    Das ist ein Argument, ja 🙂

    Nur wir habens ja durchaus mit unterschiedlicher Vertexanzahl getestet, beginnend bei so ~20000, und da sind die FPS nachvollziehbar immer weniger geworden. Aber eben immer zwischen interleaved und einzelnen Buffern identisch, bis zu einer gewissen Größe. Ab da gabs dann immer diese kleinen Abweichungen, einmal in Richtung Nvidia und einmal in Richtung ATI.
    Klar, es könnte sein dass die Grafikkarte generell mit dem Transformieren nicht mehr nachgekommen ist, oder eventuell baut der Treiber irgendwo Mist und stallt irgendwo die gesamte Pipeline etc. Die Treiber für DX9 und Geforce 6/7 sind in der Tat eine grausliche Angelegenheit (wenn der Treiber meint den Shader on-the-fly "optimieren" zu müssen weil sich ein konstanter Parameter auf 0 oder 1 ändert, und plötzlich gibts dadurch Ruckler im Spiel...), also möglich ist natürlich alles. Und klar, mit neuen Treibern sieht die Performance vielleicht wieder ganz anders aus.

    Ich hab schon viele seltsame Dinge erlebt, Display Lists, die schneller sind als VBOs etc... (nicht bei mir selber, aber bei einem Kollegen am Computergraphik-Institut der TU Wien. Also wir sind nicht irgendwelche Anfänger, die ihr 1. OpenGL-Programm schreiben. Aus dem Demo ist dann ein Paper geworden zu dynamischem Terrain-LOD). Die einzige Möglichkeit dort ist auch, dass der Treiber irgendwas mit den Vertexdaten macht, wenn man eine DL kompiliert. In dem Fall haben uns nicht mal Engineers von Nvidia sagen können wieso das schneller ist 🙂 Die haben auch nur vermutet, dass es mit Bit-Alignment zu tun haben muss.
    Die Treiber sind halt eine Blackbox... ich wollte euch einfach nur meine persönlichen Erfahrungen mit dieser Blackbox mitteilen. Ich finde das ja selber desöfteren sehr seltsam, was da passiert, und deshalb bin ich inzwischen sehr vorsichtig geworden, irgendwelchen Herstellerinfos zu glauben.

    ...aber nachdem ich sowieso der Meinung bin, dass es egal ist, kann der Threadstarter also eigentlich ruhig auf interleaved buffers umstellen, wieso eigentlich nicht 😃


  • Mod

    Kustl schrieb:

    rapso schrieb:

    sowohl nvidia als auch ati sagen ein interleaved buffer ist besser. da gibt es nichts widerspruechliches. man muss natuerlich wissen wie und was man tested, viele testen einfach drauf los und wissen nichtmal was sie limitieren, manche benutzen nichtmal einen profiler wie es sie von ati bzw nvidia gibt um das rauszufinden. entsprechend gibt es ueberall im netz mal soeine, mal die gegenteilige aussage.

    Naja, wenn du immer die selbe Geometrie renderst und NUR die Bufferverteilung änderst, kannst du ja CPU-Limit, Transform-Limit, Pixelshaderbelastung, Draw Call-Limit, Raster Output-Performance, Vertex-Cache etc alles ausschließen?

    du kannst vertexcache, triangle setup, interpolator, rop bound sein.
    frag den profiler deines vertrauens statt rumzu-'gurun'.

    Dann bleibt als Resultat, dass es einfach keinen Unterschied macht.

    sorry, aber auf einen benchmark ohne tiefgehende messungen und analyse wuerd ich kein deut geben.

    Und ja, ich weiß, dass es früher hieß, dass interleaved immer schneller ist, das habe ich auch vor ein paar Jahren auch so gelernt im Studium, nur inzwischen merke ich da eben keinen Unterschied mehr (in der Regel liegen die Limits heutzutage ja sowieso ganz woanders, entweder bei den Pixelshadern oder beim Raster Output wenn ich viele Partikelsysteme hab). Ich weiß also nicht ob man da unbedingt an interleaved buffers "optimieren" sollte, da würde ich eher auf Dinge wie effiziente Vertex Cache-Ausnutzung optimieren. DAS bringt ja sogar wirklich merkbar etwas.

    man optimiert natuerlich fuer das bottleneck. wenn du nicht vertexbound bist, macht es keinen sinn (bzw mit einer unified architecture wenig sinn). aber wenn man optimiert, sollte man schon ein paar grundlegende dinge richtig sehen.


  • Mod

    Kustl schrieb:

    Jester schrieb:

    Kustl schrieb:

    Naja, wenn du immer die selbe Geometrie renderst und NUR die Bufferverteilung änderst, kannst du ja CPU-Limit, Transform-Limit, Pixelshaderbelastung, Draw Call-Limit, Raster Output-Performance, Vertex-Cache etc alles ausschließen? Dann bleibt als Resultat, dass es einfach keinen Unterschied macht.

    Wenn Du nur eine Sache änderst, und sich dadurch an der Gesamtperformance nichts ändert, kann das

    a) bedeuten, dass die Sache die Du änderst tatsächlich nix ausmacht
    oder
    b) du durch ganz andere sachen sowieso limitiert bist und es daher egal ist

    Das ist ein Argument, ja 🙂

    Nur wir habens ja durchaus mit unterschiedlicher Vertexanzahl getestet, beginnend bei so ~20000, und da sind die FPS nachvollziehbar immer weniger geworden. Aber eben immer zwischen interleaved und einzelnen Buffern identisch, bis zu einer gewissen Größe. Ab da gabs dann immer diese kleinen Abweichungen, einmal in Richtung Nvidia und einmal in Richtung ATI.

    und wo lag da die limitierung laut profiler?

    Klar, es könnte sein dass die Grafikkarte generell mit dem Transformieren nicht mehr nachgekommen ist, oder eventuell baut der Treiber irgendwo Mist und stallt irgendwo die gesamte Pipeline etc. Die Treiber für DX9 und Geforce 6/7 sind in der Tat eine grausliche Angelegenheit (wenn der Treiber meint den Shader on-the-fly "optimieren" zu müssen weil sich ein konstanter Parameter auf 0 oder 1 ändert, und plötzlich gibts dadurch Ruckler im Spiel...), also möglich ist natürlich alles. Und klar, mit neuen Treibern sieht die Performance vielleicht wieder ganz anders aus.

    wenn du wuestest *Hehe*

    Ich hab schon viele seltsame Dinge erlebt, Display Lists, die schneller sind als VBOs etc... (nicht bei mir selber, aber bei einem Kollegen am Computergraphik-Institut der TU Wien. Also wir sind nicht irgendwelche Anfänger, die ihr 1. OpenGL-Programm schreiben. Aus dem Demo ist dann ein Paper geworden zu dynamischem Terrain-LOD). Die einzige Möglichkeit dort ist auch, dass der Treiber irgendwas mit den Vertexdaten macht, wenn man eine DL kompiliert.

    gibt zig moeglichkeiten die ein treiber bei DL optimieren kann. z.b. frustum culling, optimierte triangleindices, optimierte interleaved vertexbuffern, optimiertes state handling.
    wenn man selbst nicht die performance von DL erreicht (und nichtmal rausfindet wieso), ist ein performance benchmark entsprechend aussagefaehig. ihr seit vielleicht keine anfaenger, aber wohl auch keine gurus.

    In dem Fall haben uns nicht mal Engineers von Nvidia sagen können wieso das schneller ist 🙂 Die haben auch nur vermutet, dass es mit Bit-Alignment zu tun haben muss.
    Die Treiber sind halt eine Blackbox... ich wollte euch einfach nur meine persönlichen Erfahrungen mit dieser Blackbox mitteilen. Ich finde das ja selber desöfteren sehr seltsam, was da passiert, und deshalb bin ich inzwischen sehr vorsichtig geworden, irgendwelchen Herstellerinfos zu glauben.

    ja, die behalten gerne etwas fuer sich, besonders wenn sie besser sind. wenn sie schlechter waeren mit DL als VBO oder die konkurenz, haetten sie vielleicht ein zweites mal drueber nachgedacht.



  • Ein nennenswerter Vorteil von getrennten Vertex-Streams *war* mal, dass man im Falle von Multipass-Rendering die notwenidgen Vertex-Attribute fuer jeden Pass frei waehlen kann waehrend man die interleaved-Daten teilweise doppelt (oder unnoetig gross) halten muss.



  • Ähem... eigentlich habe ich nach dem Unterschied zwischen einzelnen Buffern und einem großen Buffer gefragt, nicht nach dem Unterschied zwischen packed und interleaved Buffers. AAaaaber danke für die Info



  • rapso schrieb:

    und wo lag da die limitierung laut profiler?

    Tut mir leid, das weiß ich echt nicht mehr. Ist schon fast zwei Jahre her. Wir haben, soweit ich mich erinnern kann, damals mit NVPerfKit gearbeitet. Und inzwischen werde ich keine wagen Erinnerungen mehr äußern, ich denke es ist klar wieso 🙂 Ich gebe dir recht, ohne sinnvolle Profiling-Daten ist es nicht möglich, das seriös zu analyisieren. Ich wollte sicher nicht guru-haft erscheinen, tut mir leid wenn das so rübergekommen ist.

    rapso schrieb:

    wenn du wuestest *Hehe*

    Wenn du mehr dazu weißt, nur zu. Ich bin für Informationen immer dankbar.
    Wir hatten in dem Fall seinerzeit einen Supershader mit Normal- und Shadowmapping für bis zu 8 Lichtquellen, das war auch der einzige Shader wo diese "Ruckler" beim Umstellen wirklich messbar waren. Dass so ein "Supershader" nicht unbedingt eine gute Wahl ist, ist eine Sache, aber in dem Fall hat uns das benutzte Framework da keine Wahl gelassen. Und ja, da haben wir geprofilet :). Auf jeden Fall, egal ob 1 oder 7 Lichtquellen, die Performance war immer ok, nur beim Wechseln der aktiven Lichtquellenanzahl gabs plötzlich spürbare Ruckler, wo einem 2 oder 3 Frames fehlen. Und das eben nur auf Geforce 6 und 7, weder auf ATI noch Geforce 8.
    Irgendwo online haben wir dann rausgefunden, dass auch andere Leute ein Problem mit den Shader Compiler-"optimierungen" gehabt haben, die Nvidia für Gefurce 6 und 7 eingebaut hat. Da wurde dann geraten, statt 0 oder 1 lieber 0.01 oder 1.01 zu setzen etc. Also das kann doch auch nicht die Lösung sein... Naja, später hab ich (aus anderen Gründen) auf Deferred Shading umgestellt, da gabs diese Probleme dann sowieso nicht mehr.
    Wobei ich sagen muss, dass seit Geforce 8 die Treiber viel angenehmer geworden sind.

    um noch mal auf die Ursprungsfrage zurückzukomen: Ich mag getrennte Buffer, weil ich sie zum Bearbeiten für flexibler halte. Wir haben oft Meshdaten aus verschiedenen Ursprungsmodellen (z.B. als Vertex Colors gepaintet), die dann alle in 1 Model zusammengemergt werden sollen, bzw generieren wir da neue Attribute wie Tangents im Model Distiller, das geht über hinzufügen von neuen Buffern natürlich wirklich simpel. Also wir bauen vorhandene Models oft im Nachhinein um. Für Blendshapes haben wir das auch gut gebrauchen können, dass einzelne Buffer für Positions und Normals, wohin oder wovon interpoliert wird, jederzeit "auswechselbar" sind, während z.B. Colors und Texcoord-Streams immer fix bleiben. Aber das ist schon etwas her, inzwischen kann man das sicher besser mit Vertex Texture Fetch lösen.
    Wenn du das alles nicht vorhast, gibts wohl wirklich keinen Grund für getrennte Buffer für die einzelnen Attribute.



  • Also ich hab grad von mehreren Buffern auf einen Großen umgestellt. Und hab ca 30-40% weniger fps... Gibts da noch etwas besonderes zu beachten? Das Ergebnis gefällt mir nämlich garnicht 😞


  • Mod

    sicher dass alle elemente im vertexbuffer benutzt werden?
    gut indiziert?
    ist das allignment/padding auf 32byte?



  • 16 bit anstatt 32 Bit Indices geben 2-3 frames mehr (bei 200 frames insgesamt)

    Ich bin dem Artikel bei oZone3D gefolgt und meine Datentypen so definiert:

    #pragma pack(push, 1)
    typedef struct
    {
        float x;
        float y;
        float z;
    } AL_VertCrd;
    #pragma pack(pop)
    

    das soll weniger datenscheffel verursachen. hatte diese pragmas auch grad weggelassen - kein performanceunterschied. Hatte meine Datentypen auf 32 bits um leere member ergänzt - hatte performanceverlust von 5-10%.

    Im Vertexbuffer wird jeder vertex mindestens einmal im element array buffer indiziert...



  • Das 1-Byte-Alignment hat keine Auswirkungen weil die floats eh 32bit gross sind.
    Du solltest Deinen Indexbuffer so sortieren, dass moeglichst linear aus dem Vertexbuffer gelesen wird und moeglichst viele Vertices aus dem (kleinen) Post-T&L-Cache wiederverwendet werden koennen.



  • hellihjb schrieb:

    Das 1-Byte-Alignment hat keine Auswirkungen weil die floats eh 32bit gross sind.
    Du solltest Deinen Indexbuffer so sortieren, dass moeglichst linear aus dem Vertexbuffer gelesen wird und moeglichst viele Vertices aus dem (kleinen) Post-T&L-Cache wiederverwendet werden koennen.

    Das mit dem Sortieren ist mir jetzt irgendwie unklar.
    Ich habe ne Menge triangles mit ziemlich durchgemischten Indizes. Was ist denn da eine gute Sortierung?
    wenn ich jetzt die Dreiecke
    1,2,3
    5,1,3
    4,2,5
    2,4,1
    5,4,3

    hätte... Ich kann mir jetzt nicht wirklich etwas überlegen um die indices linear verlaufen zu lassen... Ich könnte natürlich auch schon beim exportieren die vertices sortieren...



  • Selbst bei nur 17 vertices und 36 indizes sieht man den unterschied in der framerate (ca. 5-6 frames) da kann doch irgendwas nicht stimmen?
    edit: ich glaube das mit dem sortieren des Indexbuffers hat einen eigenen Thread verdient...


  • Mod

    Azrael, il Meraz schrieb:

    16 bit anstatt 32 Bit Indices geben 2-3 frames mehr (bei 200 frames insgesamt)

    Ich bin dem Artikel bei oZone3D gefolgt und meine Datentypen so definiert:

    #pragma pack(push, 1)
    typedef struct
    {
        float x;
        float y;
        float z;
    } AL_VertCrd;
    #pragma pack(pop)
    

    das soll weniger datenscheffel verursachen. hatte diese pragmas auch grad weggelassen - kein performanceunterschied. Hatte meine Datentypen auf 32 bits um leere member ergänzt - hatte performanceverlust von 5-10%.

    Im Vertexbuffer wird jeder vertex mindestens einmal im element array buffer indiziert...

    aber du hast nicht jede deiner structs sondern schon das ganze vertex auf 32byte alligned, oder?



  • Ich poste mal hier, weils hier eher um mehrere buffer/ein buffer geht.

    Kann es sein, dass die GeForce FX serie eine ziemliche ausnahme bei mehreren buffern/einem Buffer ist? Ich habe nähmlich bei gleichem Code mit meiner GeForce FX 5500 bei mehreren Buffern einen performancegewinn von ca. 30-40%. während bei einer integriertel inten GMA x3100 die performance um ca. 10-15% sinkt. mit einer GeForce 8800gt spürt man bei meinem ursprünglichen model kaum was, bei einem model mit 30x sovielen vertices kann man bei mehreren Buffern auch einen performanceverlust von ca 20% erkennen.

    Frage: ist die GeForce FX ein krüppel? :D:D:D



  • Ich hab eine Geforce 8800 GTS und auch mehrere Buffer. Je einen für Vertices, TextureCoords und Material. Ich sehe keinen Unterschied, wenn ich es auf einen reduziere, was die FPS angeht. Auch bei meiner ATI die onboard läuft ist kein Unterschied. Hab auch schon beide Methode ausprobiert. Bei NEHE propagieren Sie 3 Buffer im Tutorial zu VBO, auf anderen Seiten einen Buffer.
    rya.



  • Wenn die einzelnen Buffer sequentiell, dh streaming- & cache-freundlich, ausgelesen werden koennen macht es *keinen* Unterschied wieviele Buffer es gibt weil die zu uebertragende Datenmenge gleich ist (grobe Fehler in Treiber und/oder Hardware ausgenommen).
    Die Kosten "eines" Cache-Miss multiplizieren sich aber mit der Anzahl der Buffer.

    Der Vorteil getrennter Buffer liegt aber auf der anderen Seite:
    Will man die Geometrie CPU-seitig veraendern (Animation/Skinning) muessen nicht alle Vertexattribute uebertragen werden und man spart einen erheblichen Prozentsatz Bus-Traffic.



  • Passt vielleicht ganz gut, was ich gestern gecodet habe: Ich bake in einem größeren Level für alle statischen Models per-Vertex-Ambient Occlusion (per Vertex reicht, da die Models sowieso eher organisch sind und deshalb eine ziemlich hohe Tesselierung haben). Das habe ich so implementiert, dass jede Instanz von einem statischen Model im Level ihren eigenen AO-Daten-Stream hat. Die anderen Daten für Position, Normal, Texcoord, Tangent etc werden klarerweise geshart.

    Das lässt sich relativ problemlos ins Rendering integrieren, indem einfach je nach Model-Instanz ein anderer AO-Stream reingehängt wird, die Vertex Declaration bleibt immer dieselbe (die sagt ja nur, dass es einen zusätzlichen Stream für AO gibt, nicht welchen). Das würde natürlich auch funktionieren wenn Positions, Normals etc in einem interleaved buffer gespeichert wären, aber es ist mir gerade eingefallen als nette Verwendungsmöglichkeit für mehrere Stream Sources.


  • Mod

    hellihjb schrieb:

    Wenn die einzelnen Buffer sequentiell, dh streaming- & cache-freundlich, ausgelesen werden koennen macht es *keinen* Unterschied wieviele Buffer es gibt weil die zu uebertragende Datenmenge gleich ist (grobe Fehler in Treiber und/oder Hardware ausgenommen).
    Die Kosten "eines" Cache-Miss multiplizieren sich aber mit der Anzahl der Buffer.

    mit steigender anzahl buffer hast du spruenge im speicher, random reads sind dabei teuerer als wenn alles in der sellben speicherbank waere. cachemisses hast du wie gesagt nicht, alle speicheranfragen sind vorhersehbar und somit kann auch alles im voraus geladen werden. stalls hast du jedoch, wenn das reinstreaming nicht schnell genug ist z.b. eben wegen random reads.



  • Tut mir leid die Werte die ich oben angegeben hab waren nicht richtig. Ich hab paar fehler im code gemacht die mir auf den anderen systemen performance gekostet haben. Ein großer Buffer macht wohl nicht wirklich Sinn wenn er keine Interleavte Vertexattribute speichert :).

    Habs jetzt mit optimierter Geometrie versucht... Die war zuvor wohl noch besser optimiert :D.

    Ich bleib jetzt auf jeden Fall bei mehreren Buffern 🙂


Anmelden zum Antworten