Szenen-/Resourcenmanagement



  • Abend zusammen,

    ich habe mal ein paar Fragen zum Szenen-/Resourcenmanagement, allerdings nicht sehr allgemein sondern für folgenden doch sehr speziellen Fall.

    Es geht um Architekturvisualisierung, als API wird DirectX 9.0c verwendet (kein OpenGL, hat den Grund, dass die Renderpipeline, Shader etc. aus einem kommerziellen Spieleprojekt stammen und in guter Qualität vorliegen und auch nicht weitgehend verändert werden sollen.), die Anforderungen an die Hardware sind egal (in weiten Maßen), aufgrund der gewählten API werden konsumer Grakas aber bevorzugt (also ab NVIDIA 9800GTX+, keine Quaddro Karten). Wie man jetzt sicherlich erahnt geht es bei der Sache mehr um Presentation, also nicht darum ein Produkt für den Endanwender zu schreiben, und das soll aus Kostengründen auch stark die Entwicklung (-saufwand) beeinflussen.

    Die große Herausforderung bei dem eigentlich kleinem Projekt kommt jetzt:
    - wir hab ca. 3 GB Texturdaten (unkomprimiert inkl. MipMaps)
    - diese müssen zur LZ von Platte in die VRAM gestreamt werden.

    Machbar sollte das auf jeden Fall sein, bei GTA geht das ja auch und deren Engine muss nicht nur Visualisieren. Des weiteren lässt sich sagen, das die Menge an Daten die je Sekunde maximal von Platte und über den Bus müssen 30 MB nicht übersteigen werden und wir nur ca. 200 bis 300 MB im VRAM halten müssen.
    Geometrie und Rendertargets machen zusammen nochmal 150 MB.

    Ich habe im bezug auf 3D Grafik zwar schon einiges realisiert, aber noch nichts, bei dem ich so mit Daten jonglieren musste.

    Das eigentliche Problem ist, das Ladeportale auf jeden Fall vermieden werden sollen, und man das Gefühl haben soll, sich völlig frei bewegen zu können.

    Was sollte ich hier speziell im Bezug auf ID3DTextur* Objekte beachten.
    - Managed oder gleich ins VRAM?
    - static oder dynamic? (eigentlich sollte man ja nur eine einzige dynamschie Textur haben)
    - zwischen 2 Frames eine Textur komplett befüllen, oder mehrmals locken und häpchenweise, oder gleich durch einen Thread nebenbei.

    So, ich wäre dankbar für jede Antwort.

    MfG Wally


  • Mod

    3GB RGBA32 ?
    -> 384MB DXT1

    einfach als managed laden, ohne streaming, das passt scho 😉



  • @rapso, danke schonmal für die schnelle Antwort.

    3GB RGBA32 ?

    Ja, wobei DXT1 wegen der Interpretation von Kanälen mancher Texturen in den Shadern nicht immer angewandt werden kann.
    Bsp.:
    R,G := Tangentensteigung für Normalmapping.
    B := Detail-Helligkeit
    B := Specularintensität

    einfach als managed laden, ohne streaming, das passt scho 😉

    Meinst du damit, das ich Grundsätzlich nur managed nehmen soll?
    Wäre beim nachladen nun das nutzen von dynamischen Texturen Sinvoll.
    Ich hatte mir irgendwie so gedacht:
    -Textur laden, in statischen Buffer.
    -zwei Frames warten um sync zu vermeiden.
    -Primitive mit Textur in der Szene rendern.

    Ist schon spät, also entschuldigt, wenn ich mich gerade nicht sehr Verständlich ausdrücke.

    MfG Wally


  • Mod

    Wally schrieb:

    @rapso, danke schonmal für die schnelle Antwort.

    3GB RGBA32 ?

    Ja, wobei DXT1 wegen der Interpretation von Kanälen mancher Texturen in den Shadern nicht immer angewandt werden kann.
    Bsp.:
    R,G := Tangentensteigung für Normalmapping.
    B := Detail-Helligkeit
    B := Specularintensität

    dafuer gibt es auch entsprechende formate, z.b. 3dc.

    einfach als managed laden, ohne streaming, das passt scho 😉

    Meinst du damit, das ich Grundsätzlich nur managed nehmen soll?

    falls du den speicherverbrauch gut limitieren kannst, kannst du es eventuell ohne streaming hinbekommen.
    gutes streaming is nicht mal eben gemacht und deswegen sollte man erstmal die anderen alternativen ausschoepfen.

    und von architektur kenn ich es oft so dass die geometriedaten sehr sehr viel mehr sind als texturedaten. haste mal bei dir gecheckt ob das nicht der fall ist? 🙂



  • und von architektur kenn ich es oft so dass die geometriedaten sehr sehr viel mehr sind als texturedaten. haste mal bei dir gecheckt ob das nicht der fall ist? 🙂

    Noch nicht. Ich hoffe auch das es dabei bleibt.
    Es handelt sich um ein begehbares Firmengelände. 3D-Modell haben wir bekommen.
    Texturen sind Eigenproduktion, großteils aus Fotografien. Da wir die Meshdaten nicht selbst ertellt haben (so heisst es zumindest von unserem "3D-Artist"), kann man sie auch nicht effizient und teilkachelbar mappen.

    Zumindest muss ich es mit dem Streaming versuchen :p

    Hält es die Graka den auf , bzw. kommt es zu ungewollten Syncs, wenn ich eine Textur alloziiere und mit Daten befüll, sie aber noch nicht direkt benutze?

    MfG Wally



  • Wally schrieb:

    Da wir die Meshdaten nicht selbst ertellt haben (so heisst es zumindest von unserem "3D-Artist"), kann man sie auch nicht effizient und teilkachelbar mappen.

    Was meinst du mit effizient mappen und "teilkachelbar" machen?

    Hast du dir schon Artikel zu Mega Texturing und Geoclipmapping durchgelesen?



  • Was meinst du mit effizient mappen und "teilkachelbar" machen?

    Wenn man selbst Geometrie modelliert, passt man (ich zumindest) die Tesselation so an, das man effektiv mappen kann. Jetzt sind teils ganze Fassaden als ein Foto gemappt.

    Hast du dir schon Artikel zu Mega Texturing und Geoclipmapping durchgelesen?

    Geoclipmapping, stand mal was in den ShaderX glaub ich. Aber gings da nicht um Terraingeschichten?

    Mega Texturing, werd ich mal als Schlagwort nehmen, danke.


  • Mod

    this->that schrieb:

    Wally schrieb:

    Da wir die Meshdaten nicht selbst ertellt haben (so heisst es zumindest von unserem "3D-Artist"), kann man sie auch nicht effizient und teilkachelbar mappen.

    Was meinst du mit effizient mappen und "teilkachelbar" machen?

    das mann statt einer grossen texture einmal aufs objekt zu legen, eine kleinere wiederhollend draufpackt.
    das spart speicher, muss man aber beim erstellen des objektes schon beachten, sonst ist es wohl ne heiden areit es nachtraeglich drauf zu packen (da du ja mehrere solche kleinen texturen in eine grosse steckst um effizient zu bleiben).

    jedenfalls ist das meistens das problem.

    mit pixelshadern kann man das sehr schoen umgehen indem man pro dreieck erstmal ein tile auswaehlt und dann die texturecoordinate im shader mit
    Tex.xy=frac(IN.Tex.xy)*Scale+IN.Offset.xy;
    manuell wrappt und in die texture steckt.
    probleme: entstechen an den kanten, entweder muss die textur einen pixelrand haben, oder man muss mit 4 textureread pointsamplen und manuell filtern.
    alternativ kann man auch eine 3d texture nehmen und die tiles dort reinfuellen, die triangle ID selektiert dann immer den layer.
    problem: mipmapping geht nicht.

    Wally, loeschen und allokieren von texturen oder jeglichen anderen resourcen kann zu fragmentierung des speichers fuehren und dann je nach treiber/hardware zu ruckeln usw. auch das benutzen von resourcen mit der cpu ist unvorhersehbar. es kann sein dass eine graka mal 2 mal 10frames hinterher laeuft. das ist ausserhalb deines direkten einflusses.
    du solltest moeglichst nichts dynamich erstellen und loeschen, das macht einige dinge sehr kompliziert. was wenn du z.b. ploetzlich die 1GB an daten loescht und wieder allokierst, wenn noch die graka garnicht fertig mit denen ist?
    dann hast du theoretisch genug ram, praktisch ist es aber (noch) nicht frei. stallen? out of vidmem returnen?

    also halte deinen pool an texturen ;).



  • Wally, loeschen und allokieren von texturen oder jeglichen anderen resourcen kann zu fragmentierung des speichers fuehren.

    In dem Paper:http://www.insomniacgames.com/tech/articles/1107/files/texture_streaming.pdf schreiben die, dass sie die VRAM von der GPU defragmentieren lassen(nur leider nicht wie!).
    Auch würd mich interessieren, wie sie die in der Fixed-Bank geladenen kleinen Mip-Stufen in die dynamischen, großen kopieren.
    Ich würd da an GetSuface->SetRendertarget und in ein Quad rendern denken!?

    es kann sein dass eine graka mal 2 mal 10frames hinterher laeuft. das ist ausserhalb deines direkten einflusses.

    Mmmh, bei ner OcclusionQuery gehe ich ja auch von einem Frame aus.

    Also, trotzdem danke für die Antworten.

    @rapso: deine Shadertricks beziehen sich doch eigentlich auf Textur-Atlanten, oder?


  • Mod

    Wally schrieb:

    Wally, loeschen und allokieren von texturen oder jeglichen anderen resourcen kann zu fragmentierung des speichers fuehren.

    In dem Paper:http://www.insomniacgames.com/tech/articles/1107/files/texture_streaming.pdf schreiben die, dass sie die VRAM von der GPU defragmentieren lassen(nur leider nicht wie!).

    so wie man speicher nunmal defragmentiert wenn man den selber managed. auf ps3 haben wir einfach nur den ptr drauf. da kannst du alles machen, egal wie schlimm das ist was dabei rauskommt 😉

    Ich würd da an GetSuface->SetRendertarget und in ein Quad rendern denken!?

    das ist wohl suboptimal. in d3d10 gibt es copysubresource, ich kann mich nicht erinnern, dass es etwas passendes in d3d9 gab.

    Mmmh, bei ner OcclusionQuery gehe ich ja auch von einem Frame aus.

    kann aber weit mehr sein.

    @rapso: deine Shadertricks beziehen sich doch eigentlich auf Textur-Atlanten, oder?

    ja, denn das ist wohl das problem fuer deinen artist mit tiled textures, oder?



  • Also, wie ist scheint ist IDirect3DDevice9::EvictManagedResources aufrufen und ein paar Frames warten die einzige Möglichkeit unter DX9 die VRAM zu defragmentieren. Einen Pointer auf diese werd ich in der PC Welt wohl nicht bekommen (ich glaub nichtmal, das diese vom Prozessor direkt addressiert wird) auf jeden Fall erfordert Streaming wohl eine gut durchdachte Architektur im ResourcenManagement. Ich werd mich mal daran versuchen und Texturen komprimieren wo es nur geht.

    Thanks all 😉


  • Mod

    streaming ist nicht nur eine code-sache, es kommt auch auf die arbeit der artist an. es im nachinein einzubauen ist natuerlich manchmal eine unumgaengliche notloesung, aber schoen wird es nicht.

    btw. transferrate ist nicht das problem von streaming, zugriffszeiten sind das schlimmste. wenn du von einer dvd streamst mit 250ms zugriffszeit und du oeffnest eine datei, wird das laufwerk erstmal den sector mit den informationen der datei anspringen, dann zur datei selbst, worst case also 500ms -> 2texturen pro sekunde.
    auch mit HDD ist es noch nicht das optimale, besonders mit vista verdoppeln sich manchmal leider die zugriffszeiten (dafuer mehr sicherheit 😉 ).

    da du 'nur' 3GB an daten hast, versuch sie eventuell alle gut komprimiert im ram zu halten. selbst wenn es dann 1GB ram zieht, duerfte das danke extrem guter zugriffzeiten sehr viel bringen. (du kannst es natuerlich weiter komprimieren, z.b. jpg texturen im ram die du zur laufzeit in dxt oder auch nur rgba32 konvertierst, geht natuerlich nicht so gut fuer normalmaps usw.).



  • wir hab ca. 3 GB Texturdaten (unkomprimiert inkl. MipMaps)
    Texturen sind Eigenproduktion, großteils aus Fotografien

    Bedenke dass Du bei hochaufloesenden Texturen selten die groesste Mipmap-Stufe brauchst und die Summe der kleineren Mipmaps nur noch 1/3 der urspruenglichen Groesse ist.
    Man kann die notwendige Texturdetailstufe abschaetzen indem man einige sinnvoll ueber das Mesh verteilte Polygone transformiert und das maximale Delta-U/V berechnet.


Log in to reply