DirectX VertexBuffer Lockzeiten Frage



  • Vielleicht kommt ja noch jemand der was zu diesem Paradoxen evrhalten sagen kann (das übrigends bei nem Freund von mir nicht auftritt dem ichs mal zum testen geschickt habe).

    Das mti den Mehreren Texturen ist auch ne Gute Idee hatte ich so noch garnicht dran gedacht. Macht sich aber auch nicht so einfach weil man die ganzen Texturen unter einen Hut bekommen muß. Aber danke auf jedenfall für den Gedankenanstoß werd ich mal mit dran denken.



  • Was genau glaubst Du denn da jetzt gemessen zu haben?



  • Xebov schrieb:

    Macht sich aber auch nicht so einfach weil man die ganzen Texturen unter einen Hut bekommen muß.

    Ab D3D10 gibts dafür Texture Arrays.



  • hellihjb schrieb:

    Was genau glaubst Du denn da jetzt gemessen zu haben?

    Eingeschlossen in die Messung ist das Locken des Buffers und anschließende Kopieren der Daten und Unlocken. Das die Zeiten nicht ganz 100%ig stimmen ist mir klar, mir geht es primär einfach um die Frage wieso der jeweils 1. Buffer so extreme zeitschwankungen hinlegt obwohl das Programm immer nur genau das selbe tut und vor allem wieso die restlichen Buffer davon scheinbar nicht betroffen sind.



  • wieso der jeweils 1. Buffer so extreme zeitschwankungen hinlegt

    Weil die Command-Queue des Treibers irgendwann mal voll laeuft (sowie nur wenige Frames im Voraus abdeckt) und es dadurch zum Stall kommt.



  • hellihjb schrieb:

    wieso der jeweils 1. Buffer so extreme zeitschwankungen hinlegt

    Weil die Command-Queue des Treibers irgendwann mal voll laeuft (sowie nur wenige Frames im Voraus abdeckt) und es dadurch zum Stall kommt.

    Das wars leider nicht. Ich hab die Ursache nach einigen Versuchen jetzt gefunden. Bei 2 Freudnen von mir zeigt das Programm die erwarteten Daten. Bei mir Zeigt es Konstant 16ms für das Locken, wenn ich aber nach dem Beenden der Zeitmessung irgendwo ein Sleep(17) mache zeigt er mir Plötzlich die echte Zeit an, setze ichd as Sleep so das es zwischen Start und Endpunkt sitzt dann steigt die Zeit die er ausgibt auch nicht an. Aus irgendeinem mir nicht ersichtlichen Grund wird scheinbar bei einem der Messwerte bei mir die Restzeit die noch bis zum VSync übrig ist raufgerechnet.



  • Dann setz das presentation interval mal auf "immediate".
    Und stell im Treiber sicher, das nicht vielleicht "VSync=on" erzwungen wird.



  • hustbaer schrieb:

    Dann setz das presentation interval mal auf "immediate".
    Und stell im Treiber sicher, das nicht vielleicht "VSync=on" erzwungen wird.

    Hab ich mal gemacht er bleibt dann bei 62FPS stehen, ohne das ein Sleep irgendwo drin is. Ich kanns mir leider nicht genau erklären was er da treibt aber es ist defakto so das das Updaten des Buffers zwischen 2 QueryPerformanceCounter() steckt, und ich ein Sleep reinpacken kann das erst ab 17ms eine Auswirkung auf das Ergebniss hat. Ich kanns auch hinter die Messung klemmen dann zeigt er mir den Realen Wert an, ich find das reichlich komisch immerhin hat es aktiven Einfluß auf die FPS.



  • Ich hab jetzt noch etwas herumprobiert und bin imernoch zu keienr Lösung gelangt. Evtl hat ja jemand noch ne Idee was da los ist.

    Ich hab die gesammte Anwendung einmal auf Minimal geschraubt, dh Vorbereitung, dann die ganze Renderschleife und danach Aufräumen. Ich weiß zwar das die Timings in Sachen DX nicht unbedingt absolut aussagekräftig sind, aber ich komme hier nicht einfach nichtmehr weiter weil ich einfach keinen Fehler finden kann.

    Hier mal in kurzer Übersicht die Fakten:

    Wenn ich in der Schleife nur die Kamera setze, Clear, BeginScene, End Scene und Present verwende sinkt die FPS von ca 280k auf 2k, dafür ist einzig Present verantwortlich, ich weiß allerdings nicht ob das generell durch technische Limits kommt.

    Ich habe einen VertexBuffer zum testen erstellt der 120k Vertices hat, ergeben 40k 3Ecke, als xyzrhw. Und hier kommt das eigentlich merkwürdige, ich erstelle den Buffer als Dynamic/WriteOnly im Default Pool. Vor der Schleife. Rendere ich jetzt die 120k Vertices ohne vorher ein Update zu machen, also nur mit dem Datenmüll der an der Stelel ist, erhalte ich 660FPS, Update ich ihn aber dropt alles auf 6FPS, dabei ist es egal ob ich den Buffer 1x pro Frame oder einmal am Anfang des Programms fülle. Das macht mich etwas stutzig denn eigentlich dürfte der Bufefr ja keine weitere Auswirkung auf die Geschwindigkeit haben wenne r einmal sowieso befüllt ist. Das befüllen selbst geht relativ schnell nur das Locken dauert in jedem Frame sehr lang. Der Rest der Zeit geht bei Present drauf, der Befehl braucht 0,15s bis er durch ist. Nun frage ich mich allerdings wofür er so lange braucht, 40k 3Ecke sind zwar einiges, dürften aber eine Moderne Karte nicht in die Knie zwingen.

    Die Frage die ich mir jetzt stelle ist, was kann so ein Verhalten überhaupt auslösen? Ich weiß das es irgendwas mit meiner Anwendung zu tun hat, da die PCs auf denen ich es Ausprobiert habe auch in die Knie gehen. Alelrdings sind die Meisten Komponenten nicht aktiv, und die die Aktiv sind habe ich testweise auch schon abgeschalten um zu testen ob es an ihnen liegt. Es ist jedoch eher so als wenn die ganze Zeit einfach irgendwo Verschluckt wird ohne das richtig zu erkennen ist wo. Das der treiber hier vollläuft und ein Stall zwecks Sync auftritt kann ich mir irgendwie auch schlecht vorstellen, zumal er das selbe verhalten schon bei 4k 3Ecken zeigt, hier fällt er auf 62FPS. Momentan läuft das ganze bei 6FPS, der Bufefr wird 1x Pro Frame mir den 120k Vertices befüllt und bekommt ein Update und danach werden 20 DrawCalls a 6k Vertices gemacht.

    Hoffe mal jemand kann damit was anfangen und hat noch ne Idee was da los sein könnte.



  • Es kann nicht sein, dass du irgendwie falsche Werte an den Aufruf zum rendern hast, oder? - Also falsche Anzahl o.ä.? - Das in Verbindung mit Debug Ausgaben kann die FPS schon recht senken. (Also hast du DX Debug an?)

    Im release hast du auch kompiliert? (blöde Frage ich weiss, aber man muss mal sicher gehen. ;)) - Sollte hier zwar nicht allzu viel ausmachen, da du ja lediglich einmal befüllst, aber könnte sonst was sein.



  • drakon schrieb:

    Es kann nicht sein, dass du irgendwie falsche Werte an den Aufruf zum rendern hast, oder? - Also falsche Anzahl o.ä.? - Das in Verbindung mit Debug Ausgaben kann die FPS schon recht senken. (Also hast du DX Debug an?)

    Im release hast du auch kompiliert? (blöde Frage ich weiss, aber man muss mal sicher gehen. ;)) - Sollte hier zwar nicht allzu viel ausmachen, da du ja lediglich einmal befüllst, aber könnte sonst was sein.

    Falsche Werte sind ausgeschlossen. Ich habe den Vertexbuffer gekapselt, dort werden alle Primitiven zwischen gespeichert und dann in einem Rutsch mit nem Lock rübergeschoben. Der Drawcall ist auch Fehlerfrei, der Vertexbuffer ist korrekt im Stream gesetzt und die Anzahl der zu zeichnenden Primitiven stimmt auch. Debug Modus für DX is aus.

    Release hab ich auch gemacht, sonst wäre es ja auf den anderen Rechnern garnicht gelaufen.

    Ich hab auch das ganze mal durch ein Array im RAM ersetzt das befüllt und gerendert wird, da ist das Problem 1:1 das gleiche, das schließt den Vertexbuffer ansich schonmal aus. Einstellungen an DX werden sonst auch nirgens vorgenommen (auch nicht in der Nachrichtenfunktion). Neben einigen kleinen matrix berechnungen wird ind er Schleife nur die Kamera gesetzt, und die 40k Primitive in 20 Drawcalls gezeichnet.

    Ich bin mir sicher das irgendwo ein fehler sien muß, nur leider kann ich keine Unstimmigkeiten fidnen, vor allem Kurios ist die Tatsache das das einmalige Lock/Unlock des Bufefrs am start des programms die FPS in den Keller drückt.



  • OK, wollte nur mal sicher gehen. 😉

    Vor der Schleife. Rendere ich jetzt die 120k Vertices ohne vorher ein Update zu machen, also nur mit dem Datenmüll der an der Stelel ist, erhalte ich 660FPS, Update ich ihn aber dropt alles auf 6FPS, dabei ist es egal ob ich den Buffer 1x pro Frame oder einmal am Anfang des Programms fülle.

    Ich verstehe nicht ganz, was du meinst mit Updaten.. - Du erstellst ja einen VertexBuffer mit Device::CreateVertexBuffer (..) und da ist ja erstmal nix drin. Und dann füllst du da (random?) Dreiecke ein.
    Aber was für Datenmüll? - Oder meinst du, dass du zuerst random Vertices reinschiebst?



  • drakon schrieb:

    Ich verstehe nicht ganz, was du meinst mit Updaten.. - Du erstellst ja einen VertexBuffer mit Device::CreateVertexBuffer (..) und da ist ja erstmal nix drin. Und dann füllst du da (random?) Dreiecke ein.
    Aber was für Datenmüll? - Oder meinst du, dass du zuerst random Vertices reinschiebst?

    Naja du erstellt den Buffer ja eigentlich und machst dann ein Update (also locken reinschieben unlocken). Wenn man den Buffer erstellt ist ja aber schon irgendwas drin, der wurde ja erstellt und liegt auf einem Stück VRAM, so war das gemeint, mit Datenmüll meine ich das was ohne Updaten im Buffer wäre und ansonsten fülle ich ihn mit 120k Vertices die 20k Quadrate ergeben, die liegen alle übereinander, dh jedes verdeckt seinen Vorgänger, also im Grund ein Stack. Ich habe vorhin auchmal Zufallswerte genommen für die 4Ecke, bei denen sie sichtbar wären, dabei war dann die FPS nichtmehr ermittelbar, da wäre dann eine Angabe in Frames per Minute angebracht gewesen.



  • Hmm. Ich bin mir nicht mehr ganz sicher, aber ich dachte, dass ich auch mal relativ viele Vierecke aufeinander gehabt habe (also identische Position) und da sind mir die FPS ebenfalls abgekracht..
    Ordne die Dreiecke mal zu einer Tilemap an und schau, was dann passiert.

    Also ich kann mit ~5FPS (2 Jahre altes Notebook) ~1'800'000 Dreiecke rendern.

    Das sollte also prinzipiell gehen. Aber ich dachte wirklich,dass wenn die Dreiecke aufeinadner liegen die Graka i-wie ein Problem damit hat. (Vielleicht können gewisse Optimierungen nicht ausgenutzt werden, weil ja immer die gleichen Bereiche angesprochen werden müssen und so gewisse Parallele Operationen nicht gehen.. So stelle ich mir das in etwa vor)



  • Ja das is es, ich hab jetzt 12 Lagen a ~200k Polys in nen Buffer gestopft und damit ~2,7Mio mit 12FPS gerendert. Danke für den Anstoß, hätte nicht damit gerechnet da smir hier die Technik einen Strich durch die Rechnung macht.



  • OK. Das klingt jetzt realistisch. 🙂



  • Xebov schrieb:

    und ansonsten fülle ich ihn mit 120k Vertices die 20k Quadrate ergeben, die liegen alle übereinander, dh jedes verdeckt seinen Vorgänger, also im Grund ein Stack.

    Falls die alle Bildschirmfüllend waren, dann hast du da 20.000 mal auf jeden Pixel gerendert. Also Overdraw-Faktor 20.000. Natürlich ist das langsam.

    Oder waren da die Dreiecke flächenmässig ca. gleich gross wie beim späteren Test mit "12 Lagen"?



  • hustbaer schrieb:

    Xebov schrieb:

    und ansonsten fülle ich ihn mit 120k Vertices die 20k Quadrate ergeben, die liegen alle übereinander, dh jedes verdeckt seinen Vorgänger, also im Grund ein Stack.

    Falls die alle Bildschirmfüllend waren, dann hast du da 20.000 mal auf jeden Pixel gerendert. Also Overdraw-Faktor 20.000. Natürlich ist das langsam.

    Oder waren da die Dreiecke flächenmässig ca. gleich gross wie beim späteren Test mit "12 Lagen"?

    Nein, die waren 200x200 Pixel und lagen alel üebreinander, also 20k Facher Overdraw. Die 12 Lagen waren je 660k a 4x4.



  • Xebov schrieb:

    hustbaer schrieb:

    Xebov schrieb:

    und ansonsten fülle ich ihn mit 120k Vertices die 20k Quadrate ergeben, die liegen alle übereinander, dh jedes verdeckt seinen Vorgänger, also im Grund ein Stack.

    Falls die alle Bildschirmfüllend waren, dann hast du da 20.000 mal auf jeden Pixel gerendert. Also Overdraw-Faktor 20.000. Natürlich ist das langsam.

    Oder waren da die Dreiecke flächenmässig ca. gleich gross wie beim späteren Test mit "12 Lagen"?

    Nein, die waren 200x200 Pixel und lagen alel üebreinander, also 20k Facher Overdraw. Die 12 Lagen waren je 660k a 4x4.

    OK.
    Du weisst aber schon dass Grafikkarten nicht bloss für jedes Dreieck Zeit brauchen, sondern auch für jeden Pixel?



  • hustbaer schrieb:

    Xebov schrieb:

    hustbaer schrieb:

    Xebov schrieb:

    und ansonsten fülle ich ihn mit 120k Vertices die 20k Quadrate ergeben, die liegen alle übereinander, dh jedes verdeckt seinen Vorgänger, also im Grund ein Stack.

    Falls die alle Bildschirmfüllend waren, dann hast du da 20.000 mal auf jeden Pixel gerendert. Also Overdraw-Faktor 20.000. Natürlich ist das langsam.

    Oder waren da die Dreiecke flächenmässig ca. gleich gross wie beim späteren Test mit "12 Lagen"?

    Nein, die waren 200x200 Pixel und lagen alel üebreinander, also 20k Facher Overdraw. Die 12 Lagen waren je 660k a 4x4.

    OK.
    Du weisst aber schon dass Grafikkarten nicht bloss für jedes Dreieck Zeit brauchen, sondern auch für jeden Pixel?

    Ja, das Problem hing aber nur an den 20k Schichten, ich hatte es glaube ich garbnicht erwähnt das die mit Alphablending gemacht wurden.


Anmelden zum Antworten