Direct3D 9 Device nach Monitor-Abstecken 'lost', aber erholt sich nicht wieder



  • Ich habe hier eine Applikation die mit D3D 9 arbeitet (Windowed Mode).

    Folgende Situation:

    Die Applikation wird auf einem System mit zwei Monitoren gestartet.
    Die Applikation hat genau ein D3D Device, und zwar für den 1. Adapter (Adapter-Nummer 0).

    Wenn man nun den 2. Monitor (Adapter-Nummer 1) absteckt, dann wechselt das D3D Device in den "D3DERR_DEVICELOST" Status. Soweit OK, müsste man es halt resetten. Bloss wechselt es leider nie mehr in den "D3DERR_DEVICENOTRESET" Status.

    Wenn man in dem Zustand das D3D Device einfach freigibt, und ein neues erzeugt, geht wieder alles.

    Frage: kann ich irgendwie mitbekommen, dass ein D3D Device "irreperabel" kaputt gegangen ist?

    Sonst fällt mir als Workaround nur ein, bei "D3DERR_DEVICELOST" grundsätzlich immer das Device zu zerstören und neu anzulegen. Was mir irgendwie nicht so toll gefällt...

    ps: Es muss automatisch gehen, dem User können wir das leider nicht aufhalsen. Also ein Menupunkt/Shortcut/... mit dem man das Neu-Erstellen des Device triggern kann ist leider keine Option.

    nochwas:

    OS = Windows XP Embedded SP2 (passiert aber auch mit Windows XP Pro SP3)
    Grafikkarte = ATI HD 4650 mit 2x DVI bzw. 1x DVI + 1x HDMI
    Treiberversion = Catalyst 10.12



  • Hm, ich mein evtl. ist das ein Treiberproblem, muss gestehen mit Monitor abstecken hab ich da keine Erfahrung. Aber kanns nicht einfach sein dass du irgendwo vergisst eine Ressource zu releasen bevor du device->Reset() aufrufst?



  • Aber kanns nicht einfach sein dass du irgendwo vergisst eine Ressource zu releasen bevor du device->Reset() aufrufst?

    Ich rufe erstmal device->TestCooperativeLevel() auf.

    Da TestCooperativeLevel() in dem Fall immer D3DERR_DEVICELOST und nie D3DERR_DEVICENOTRESET zurückgibt, versucht das Programm erst gar nicht Reset() aufzurufen.

    In anderen Fällen (z.B. Desktop gesperrt oder andere D3D Fullscreen Applikation "klaut" das Device) funktioniert das so auch problemlos. Von daher würde ich vergessene Resourcen ausschliessen.
    (Die Resourcen werden auch alle automatisch getrackt, "vergessen" kann man da kaum was.)



  • Hm Ok. Schonmal probiert ob das mit einer NVIDIA Karte auch passiert?



  • Nö, aber was bringt es mir?
    Es muss mit genau der Hardware/Software laufen die ich angeführt habe. Zu wissen "wer schuld ist" bringt mir wenig, ich muss es beheben.

    Hab es jetzt mal umgestellt, so dass immer versucht wird das Device neu zu erzeugen wenn TestCooperativeLevel() D3DERR_DEVICELOST oder D3DERR_DEVICENOTRESET zurückgibt. Scheint zu klappen, auch wenn es nicht die schönste Lösung ist.



  • hustbaer schrieb:

    Nö, aber was bringt es mir?

    Wenns bei NVIDIA nicht so wär wüsste man mit ziemlicher Sicherheit dass es ein Treiberproblem und nicht einfach das Verhalten der Direct3D Runtime ist. Dass es nur für exakt eine Hardware-Software-Konfiguration gedacht ist wusste ich ja nicht 😉

    Was Besseres als einfach neu erzeugen fällt mir jetzt leider auch nicht ein.



  • dot schrieb:

    hustbaer schrieb:

    Nö, aber was bringt es mir?

    Wenns bei NVIDIA nicht so wär wüsste man mit ziemlicher Sicherheit dass es ein Treiberproblem und nicht einfach das Verhalten der Direct3D Runtime ist.

    Ja, OK, das wäre vielleicht interessant zu wissen. Mag aber deswegen nicht die Graka umbauen - und das Programm auf meinem PC daheim (=NIVEA Karte) zum Laufen zu bringen wäre auch einiges an Action.

    Aber ich könnte zu Hause mal mit nem Video Player testen. Der VMR9 verweigert nach an- oder abstecken eines Monitors nämlich auch den Dienst. Das werd ich wohl mal machen, einfach nur interessehalber...

    dot schrieb:

    Was Besseres als einfach neu erzeugen fällt mir jetzt leider auch nicht ein.

    Naja, das war ja eigentlich nicht die Frage 🙂
    Sondern ob man irgendwie draufkommen kann ob man auf "not-reset" warten soll, oder ob man neu erzeugen muss, weil "not-reset" nie mehr kommen wird.



  • Hm, naja, evtl. hilft dir das ja weiter (D3DERR_DEVICEREMOVED klingt interessant)!? Gibts aber leider nur für D3D9Ex, ist damit also vermutlich eher hinfällig (weil wenns Vista+ only wär würdest du wohl kein D3D9 verwenden...)

    EDIT: Ok, sry, XP hast du ja oben schon gesagt...


Log in to reply