Seite 1 von 1

[D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 06.07.2015, 22:37
von Krishty
Also ich habe ein Render Target, in das etwas Wichtiges reingezeichnet wurde. Sehr wichtig. Und ich kann es nicht neu berechnen, weil der Rechenweg zu komplex ist. Und das beißt sich mit dem Lost Device:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb174714.aspx hat geschrieben:Internally, Direct3D does enough work to ensure that a lock operation will succeed after a device is lost. However, it is not guaranteed that the video-memory resource's data will be accurate during the lock operation. It is guaranteed that no error code will be returned. This allows applications to be written without concern for device loss during a lock operation.

[…]

Direct3D also allows applications to copy generated or previously written images from video-memory resources to nonvolatile system-memory resources. Because the source images of such transfers might be lost at any time, Direct3D allows such copy operations to fail when the device is lost.
Ich möchte also gern den Inhalt der Render Targets speichern und nach einem Lost Device wiederherstellen. Quasi schnell vom VRAM in den RAM retten sobald das Device verschwindet. Nur weiß ich ja leider nicht, wann das passiert, bis es zu spät ist. Oder?

Irgendwelche Ideen? Wo kriege ich im Fall eines Lost Device noch schnell eine Hundertstelsekunde her um meine Render Targets zu retten?

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 07.07.2015, 14:48
von dot
Wirst wohl nicht drum herum kommen, dein Rendering in eine D3DPOOL_SYSTEMMEM oder D3DPOOL_MANAGED Texture zu kopieren, denk ich mal... ;)

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 07.07.2015, 15:09
von Schrompf
Das musst Du aber leider sofort nach dem Ausrendern der Textur tun. Denn wenn Du von DEVICE_LOST erfährst, ist das Kind nach meinem Verständnis bereits in den Brunnen gefallen.

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 07.07.2015, 15:12
von dot
jap

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 07.07.2015, 18:12
von Krishty
Also jeden Frame runterladen? Eeeeew :(

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 09:49
von dot
Brauchst du denn wirklich noch unbedingt XP Support?

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 11:14
von Schrompf
Oder anders: wenn Du die eh jedes Frame neu renderst, dann brauchst Du sie gar nicht zu retten, sondern kannst sie einfach beim nächsten validen Frame wieder rendern. Dann existiert aber das ganze Problem gar nicht, weswegen ich mich jetzt ernsthaft frage, was genau Du da überhaupt vor hast.

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 11:18
von dot
Jo ich ging auch davon aus, dass du das Teil eben nur einmal Renderst und nicht in jedem Frame neu, weil ansonsten versteh ich auch net ganz, was genau das Problem ist...

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 11:34
von Krishty
dot hat geschrieben:Brauchst du denn wirklich noch unbedingt XP Support?
Ja :( Ich habe sogar schon eine Anfrage nach Windows 98-Support gekriegt. Mittlerweile sehe ich den Verzicht auf D3D 10 als sportliche Herausforderung, man lernt ja ’ne Menge durch Selbermachen :)
Schrompf hat geschrieben:Oder anders: wenn Du die eh jedes Frame neu renderst, dann brauchst Du sie gar nicht zu retten, sondern kannst sie einfach beim nächsten validen Frame wieder rendern. Dann existiert aber das ganze Problem gar nicht, weswegen ich mich jetzt ernsthaft frage, was genau Du da überhaupt vor hast.
Geht um meine Anzeigen aus dem Jammer-Thread. Die kommen aus Plugin-Code; werden seltener aktualisiert als der Bildschirm (manche mit 30 Hz, manche nur alle paar Minuten) und ich habe keine Kontrolle über den Code, der sie rendert. Wenn sich ein Bildschirm nur einmal pro Minute aktualisiert, hat er aber leider undefinierten Inhalt, falls in dieser Minute ein Lost Device auftritt, und das macht sich langsam bemerkbar. Beim Wechsel zu und von Vollbild merkt man es sogar bei Echtzeitanzeigen, weil das Spiel dann pausiert ist und erst wieder was Sinnvolles auf der Anzeige erscheint, sobald wieder Zeit vergeht. Nicht gerade hübsch.

Nachtrag: Jetzt verstehe ich – mit Frame meinte ich die Frames der Anzeigen, nicht die Frames auf dem Bildschirm. Ich würde die Anzeigen nach Aktualisierung herunterladen. Entschuldige die schwammige Formulierung!

Ich kann davon ausgehen, sechs Anzeigen von je 1024×1024 in BGRA zu haben. Das wären 25 MiB GPU-Download 30 Mal pro Sekunde (plusminus 5 MiB für andere Aktualisierungsraten). Damit wäre mein schnuckeliger kleiner 2008er Atom aus dem Spiel. Fuck my life.

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 12:27
von Alexander Kornrumpf
Und an der Constraint, dass das Neurendern prohibitiv teuer sei, kann man nicht drehen?

Muss ein verlorenes Device wirklich in Echtzeit wiederhergestellt werden? Ist eine Verzögerung an der Stelle nicht eher akzeptabel, als Bandbreite in jedem Frame zu verschwenden?

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 12:33
von Schrompf
Jo, da stimme ich Alexander zu. Klingt, als wärst Du gebeischlaft, egal was Du tust. Also solltest Du vielleicht eher damit leben, dass die Daten weg sind. Z.B. indem Du die betroffenen Rendertargets erstmal zu was neutralem clearst, bis die Plugins das nächste Mal rendern.

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 12:39
von Alexander Kornrumpf
In meiner grenzenlosen Naivität hatte ich mir vorgestellt, dass man dem Plugin einfach sagt, dass es nochmal rendern muss und dann wartet bis es fertig ist.

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 12:48
von Krishty
Naja; das Problem ist die Kopplung der Aktualisierungsrate an die Spiellogik. Wenn sich jemand entscheidet, einen Fernseher in das Spiel einzubauen, der jede 25tel Sekunde ein neues Bild zeichnet, kann ich beim Lost Device halt 0.04 s warten, bis das nächste Bild gezeichnet ist. Aber wenn jemand ein Kreditkartenterminal einbaut, das eine Stunde den „Willkommen“-Bildschirm anzeigt bis der erste Kunde seine Karte reinschiebt, kann ich diese Stunde natürlich NICHT abwarten.

Ja, ich bin so oder so behupst:
  • Ich könnte ja die API erweitern, und erzwingen, dass man zu jedem Bildschirm auch immer eine „Ich hab’ deinen Inhalt verloren, kannst du den bitte nochmal zeichnen?“-Funktion angeben muss (Alexanders Lösung). Aber damit würde ich bloß ein sehr D3D-9-spezifisches Problem in die Spielmechanik schleppen und es ab dem Tag der D3D->=10-Umstellung für den Rest meines Lebens bereuen.
  • Perfekte Abstraktion würde nach jedem Neuzeichnen den Inhalt in den RAM runterladen und dort sichern. (Wobei auch dabei schon ein Lost Device auftreten kann, wie Schrompf bereits sagte, aber dabei würde wohl nicht viel kaputtgehen, weil eine tote Kopie nichts überschreibt.) Aber das würde den Bandbreitenbedarf mal schnell verdoppeln, für sehr geringen Nutzen.
Vielleicht mache ich die blöden Dinger wirklich einfach schwarz und markiere es als WONTFIX – will be gone with new renderer. Alte Threads auf Gamedev und StackOverflow zeigen in eine ähnliche Richtung. Ich hatte halt nur gehofft, hier mal wieder die brillante technische Expertenlösung zur Simulation virtuellen Speichers zu finden, die man in anderen Foren immer vermisst :)

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 13:01
von Schrompf
Zum Thema "brilliante technische Expertenlösung": wahrscheinlich könntest Du da wirklich was mit der Auswahl des Memory Pools beim Anlegen des Rendertargets reissen. Ist jetzt ne reine Vermutung, ohne den Möglichkeiten auch nur nachgegoogelt zu haben. Leider kriegst Du die ganze clevere Speichervirtualisierung, die sowas ermöglichen würde, wieder erst mit Windows Vista.

Wenn's wirklich wichtig ist -> Plugin-Schnittstelle erweitern. Wenn's nicht so wichtig ist -> nächstes Problem. Und das ist jetzt wirklich mal ein "professioneller" Rat auf Basis von Industrieprojekt-Erfahrungen und der berühmten 80%-Regel. Tritt kein totes Pferd, wenn's dafür kein Budget gibt.

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 13:05
von dot
iirc kann ein Rendertarget nur im DEFAULT Pool liegen...

Eine Methode einzubauen, die das Plugin zum Updaten veranlasst, schadet aber vermutlich nicht, weil der Fall, dass der Plugin-generierte Content regeneriert werden muss ja wohl nicht nur im Zusammenhang mit einem Lost Device auftritt. Beispielsweise wirst du vermutlich nicht den Screencontent aller Kreditkartenterminals der ganzen Stadt immer im VRAM halten wollen...

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Verfasst: 08.07.2015, 13:06
von Krishty
Schrompf hat geschrieben:Zum Thema "brilliante technische Expertenlösung": wahrscheinlich könntest Du da wirklich was mit der Auswahl des Memory Pools beim Anlegen des Rendertargets reissen. Ist jetzt ne reine Vermutung, ohne den Möglichkeiten auch nur nachgegoogelt zu haben.
Joa, passt leider nicht:
Render-target surfaces are placed in the D3DPOOL_DEFAULT memory class.
Wenn's wirklich wichtig ist -> Plugin-Schnittstelle erweitern.
Wenn’s wirklich wichtig ist, würde ich lieber die Hardware-Anforderungen meines Steinzeit-Renderers hochschrauben als die Plugin-Schnittstelle mit sowas zu verpesten :) Aber ich verstehe schon.