[DX9] DeviceReset scheitert an Fensterfokus?

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
Schrompf
Moderator
Beiträge: 4855
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

[DX9] DeviceReset scheitert an Fensterfokus?

Beitrag von Schrompf »

Moin,

Splatter, letzter Bug, den ich jemals dafür fixen werde. Ehrlich jetzt. Das ist mein letztes Wort.

Wenn man aus dem Vollbild heraus Alt-Tabt, geht das Device verloren. Logisch. Wenn ich allerdings zurück ins Spiel gehe, sei es per Alt+Tab oder per Klick auf die Anwendung in der Taskleiste, kommt das Spiel nicht wieder. Es hängt stattdessen in der aus zig Tutorials seit Jahrzehnten etablierten Device-Reset-Schleife

Code: Alles auswählen

  HRESULT hr = D3DERR_DEVICELOST;
  while( hr == D3DERR_DEVICELOST ) 
  {
    hr = d3dDevice->Reset( &d3dpp);
    if (FAILED(hr) && hr != D3DERR_DEVICELOST )
      WirfAusnahmeOptional( "D3D9-Reset gescheitert");
  }
...und zwar endlos. Es kommt also kein sonstiger Fehlercode, sondern immer nur DEVICELOST. Und DirectX Debug gibt in einer ebensolangen Endlosschleife aus:

Code: Alles auswählen

Direct3D9: (ERROR) :ResetEx fails. D3DERR_DEVICELOST returned.
Direct3D9: (ERROR) :ResetEx failed and ResetEx/TestCooperativeLevel/Release are the only legal APIs to be called subsequently
Direct3D9: (WARN) :Window does not have focus. TestCooperativeLevel fails
Hat jemand eine Idee, woran das liegen könnte? Ich meine... das Fenster ist doch sicher fokussiert, wenn ich es mit dem Klick auf den Taskleiten-Eintrag wieder hochhole, oder?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8240
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [DX9] DeviceReset scheitert an Fensterfokus?

Beitrag von Krishty »

Puh, keine Ahnung. Aber was ich abchecken würde:
  • Alle Ressourcen freigegeben? Selbst wenn D3D vorher nicht meckert, könnte der interne Zustand kompromittiert sein.
  • Sleep(100) hinter Reset()? Habe eben auf Google einen Fall gefunden, bei dem das geholfen hat.
  • Zeigt WirfAusnahmeOptional() vielleicht irgendwas an? Eine MessageBox oder so? Dann hast du dein Fokusproblem right there.
P.S.: An welcher Stelle rufst du das Reset() auf? Ein erfolgreiches WM_ACTIVATE löst überhaupt erst WM_SETFOCUS aus, also solltest du es von letzterem aus tun.
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: [DX9] DeviceReset scheitert an Fensterfokus?

Beitrag von Schrompf »

Dank. Ich muss mal schauen, auf welchem Weg die Reset-Schleife überhaupt ausgelöst wird - es ist ein Callback irgendwo aus GLFW heraus, also braucht das einen genaueren Blick. An einem Sleep() oder gar mal ein Frame weiterrendern lassen und neu probieren hatte ich auch schon gedacht, werde ich auch mal ausprobieren.

WirfAusnahmeOptional() ist per #define entweder ein throw oder ein DebugBreak(), aktuell letzteres. Das würde ich also merken, wenn das klingelt. Die Bedingung ist aber nie erfüllt, daher ist das für den Moment irrelevant.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
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: [DX9] DeviceReset scheitert an Fensterfokus?

Beitrag von Schrompf »

Ok, Problem ist gelöst bzw. erstmal erkannt. Krishty hatte den Finger drauf mit seiner Vermutung, dass die Nachrichtenreihenfolge nicht hinhaut. Das Problem war zweiteilig: zum Einen hat GLFW bisher noch gar nicht WM_ACTIVATE verarbeitet, weswegen ich überhaupt nie mitbekommen habe, dass der Vollbildmodus verlassen wurde. Und zum Anderen kam bei Reaktivierung tatsächlich zuerst ein WM_SIZE, auf das ich mit einem DeviceReset reagiere, um mich an evtl. neue Fenstergrößen anzupassen. Erst danach kam ein WM_SETFOCUS, mit dem das Fenster dann auch fokussiert wurde. Ich muss also prüfen, ob das Fenster fokussiert ist, und ohne Fokus den DeviceReset bis zum Fokuserhalt verzögern.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8240
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [DX9] DeviceReset scheitert an Fensterfokus?

Beitrag von Krishty »

Obligatorische Stänkerei: Bei meiner eigenen Engine habe ich auf Direct3Ds Vollbildmodus verzichtet. Auf ALT+EINGABE reagiere ich, indem ich das Fenster auf Bildschirmgröße vergrößere. Damit schmeiße ich zwar ein paar Prozent Leistung(?) des exklusiven Vollbildmodus weg, aber erspare mir alles vom Enumerieren der Auflösungen bis hin zum Wiederherstellen des Devices nach Alt+Tab.

(Lost Device tritt natürlich weiterhin auf, aber der Code zur Größenänderung fängt automatisch auch alle anderen Ereignisse ab.)

Was für eine scheiß API, wenn man nach zehn Jahren immernoch keine Musterlösung für diesen belanglosen Dreck hat.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten