[D3D9] Render Targets nach Lost Device wiederherstellen

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag von dot »

Wirst wohl nicht drum herum kommen, dein Rendering in eine D3DPOOL_SYSTEMMEM oder D3DPOOL_MANAGED Texture zu kopieren, denk ich mal... ;)
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag von dot »

jap
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag von Krishty »

Also jeden Frame runterladen? Eeeeew :(
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag von dot »

Brauchst du denn wirklich noch unbedingt XP Support?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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...
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2112
Registriert: 25.02.2009, 13:37

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Alexander Kornrumpf
Moderator
Beiträge: 2112
Registriert: 25.02.2009, 13:37

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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 :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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...
Zuletzt geändert von dot am 08.07.2015, 13:11, insgesamt 3-mal geändert.
Benutzeravatar
Krishty
Establishment
Beiträge: 8239
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D9] Render Targets nach Lost Device wiederherstellen

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten