Device Lost Problem

I am having a problem with losing the device that I'm not sure about. The window can be minimized, lose focus to another app, and be resized with no problem. The problem occurs if in WinXP the user hits cntl-alt-del and then goes back (either by canceling or by unlocking later). The device can't seem to recover properly from this. Sometimes I can even continue drawing to the device after coming back but resizing it immediately breaks it (when you could resize fine before). Has anyone had this kind of experience and solved it Does somebody have a clear example in C# for how to handle the device lost, resize, and reset events cleanly in MDX Thanks

Answer this question

Device Lost Problem

  • Qa Dept

    It is still crashing in the same way. I added the code you gave and it passes through the following section with no problems and doesn't throw exceptions:

    case ResultCode.DeviceNotReset:

    try

    {

    device.Reset(this.presentParams);

    deviceLost = false;

    return true;

    }

    But the next time it tries to paint it dies. I have this inside of the override to OnPaint and the OnPaint method calls Invalidate() at the end. I am changing a parameter to my pixel shader at each pass which makes it draw a slightly different image on each iteration. I also pass in the texture the effect uses on each pass to emulate incoming video so its not a matter of the device not having the texture the shader is using after its lost. Any more ideas Thanks


  • jamie r

    Your profile doesn't seem to contain an email address. Is this a hint :)
  • qmshou

    To release a vertex buffer you have to call its Dispose method. Assign null and let the garbage collector do its work will not be enough because you don’t know when it will release the buffer. Finding the right buffer can be a little trickier. Do you use the mesh classes or only vertex buffer objects Do you use any other helper functions like the sprite or text system

    Anyway you should look out for create flags that contains default or dynamic. Additional you should look for Pool.Default in your code.



  • Todd Follansbee

    With this exception it is a Direct3D problem for sure.

    Please switch to the debug build of the Direct3D runtime and run your program with a debug monitor in the background. In the case of Direct3D exceptions the debug runtime should tell you what’s going wrong. It is much easier to find the problem this way.

    You can activate the debug runtime with the DirectX control panel.



  • Ryan Lowdermilk

    This probably won't be much help because it stops on the Application.Run(frm); line.

    static void Main()

    {

    using (Form1 frm = new Form1())

    {

    // Show our form and initialize our graphics engine

    frm.Show();

    if (!frm.InitializeGraphics())

    {

    MessageBox.Show("Your card does not support shaders. " +

    "This application will run in ref mode instead.");

    }

    Application.Run(frm);

    }

    }


  • Mikener

    When the user switches to another desktop (strg-ctrl-del brings you to a security desktop) you lost the device and MDX cannot recover it without a little help. You have to do this:

    Add Exception handling around your Present call:
    try

    {

    device.Present();

    }

    catch (DeviceLostException)

    {

    deviceLost = true;

    }

    Before you draw anything in a frame make sure that you can draw:
    bool CanRender()

    {

    if (deviceLost == false)

    return true;

    int Result;

    device.CheckCooperativeLevel(out Result);

    switch ((ResultCode)Result)

    {

    case ResultCode.Success:

    deviceLost = false;

    return true;

    case ResultCode.DeviceLost:

    return false;

    case ResultCode.DeviceNotReset:

    try

    {

    device.Reset(device.PresentationParameters);

    deviceLost = false;

    return true;

    }

    catch (DirectXException exception)

    {

    if ((ResultCode)exception.ErrorCode == ResultCode.DeviceLost)

    return false;

    throw exception;

    }

    default:

    DirectXException DXException = new DirectXException();

    DXException.ErrorCode = Result;

    throw DXException;

    }

    }

    If CanRender returns false you should not render the next frame. Instead you should wait for the next event or send the current thread to sleep for a little time. This depends on your general render loop.

    PS: if present throw an excpetion your last frame is lost. If you need this data you have to draw it again after the device is in a drawable state again.



  • Rajendran

    You are right that does not help much. Do you know what exception is throwing. Maybe this is not a Direct3D Problem at all.


    Have you try to run your code with the debug build of the Direct3D runtime Does it report any errors



  • adb444

    Sure. Take the email address from my profile. But I will need a day or two.



  • Titi des bois

    The exception is:

    An unhandled exception of type 'Microsoft.DirectX.Direct3D.InvalidCallException' occurred in microsoft.directx.direct3d.dll

    Additional information: Error in the application.

    The weird thing is that it seems to recover in that I can again paint and the screen is updated, but trying to resize the window after the recovery doesn't work.


  • vtortola

    Maybe you have forgotten to recreate a resource that is lost during the reset. Can you show me the line of code that the debugger shows you after the exception are thrown

    Anyway you should activate the debug runtime and use a debug monitor. Many times it give you good hints if something goes wrong. You can download a debug monitor over there: http://www.sysinternals.com/Utilities/DebugView.html



  • metro16327

    I downloaded the debug monitor you recommended and it had some interesting info:

    [3232] Direct3D9: (ERROR) :The following D3DPOOL_DEFAULT surfaces/buffers/textures still exist
    [3232]
    [3232] Direct3D9: (ERROR) : D3DRTYPE_VERTEXBUFFER
    [3232]
    [3232] Direct3D9: (ERROR) : Memory Address: 00905798 lAllocID=7726 dwSize=00000050, (pid=00000ca0)
    [3232]
    [3232] Direct3D9: (ERROR) : Stack Back Trace
    [3232]
    [3232] Direct3D9: (ERROR) : [0] : Address 045E6CE6
    [3232]
    [3232] Direct3D9: (ERROR) : [1] : Address 046BADD8
    [3232]
    [3232] Direct3D9: (ERROR) : [2] : Address 04635EAF
    [3232]
    [3232] Direct3D9: (ERROR) : [3] : Address 0462A054
    [3232]
    [3232] Direct3D9: (ERROR) : [4] : Address 0462CE85
    [3232]
    [3232] Direct3D9: (ERROR) : [5] : Address 04629D90
    [3232]
    [3232] Direct3D9: (ERROR) : Devil : Address 04629B90
    [3232]
    [3232] Direct3D9: (ERROR) : [7] : Address 04614692
    [3232]
    [3232] Direct3D9: (ERROR) : Music : Address 7925DE73
    [3232]
    [3232] Direct3D9: (ERROR) : [9] : Address 00AFA045
    [3232]
    [3232] Direct3D9: (ERROR) : [10] : Address 03487635
    [3232]
    [3232] Direct3D9: (ERROR) : [11] : Address 00AFAE7B
    [3232]
    [3232] Direct3D9: (ERROR) : [12] : Address 0348739A
    [3232]
    [3232] Direct3D9: (ERROR) : [13] : Address 0348531D
    [3232]
    [3232] Direct3D9: (ERROR) : [14] : Address 03484EC1
    [3232]
    [3232] Direct3D9: (ERROR) : [15] : Address 7B82F99D
    [3232]
    [3232] Direct3D9: (ERROR) :All user created D3DPOOL_DEFAULT surfaces must be freed before Reset can succeed. Reset Fails.
    [3232]
    [3232] Direct3D9: (ERROR) :Reset failed and Reset/TestCooperativeLevel/Release are the only legal APIs to be called subsequently
    [3232]

    It appears that I need to try and free some resources. I called the ReleaseGraphics on the addition render surfaces I created but how do I free the VertexBuffer it seems to be complaining about Thank


  • Lai F K

    Why do you call “ReleaseGraphics“ on this two surface If you are want to free them call Dispose.

    If you don’t handle resizing MDX will simply reset the device with the new window size as back buffer size. I do the same and have no problem.

    Is there is any reason that you store this vertex buffer in the default pool

    Excuse the question I am only want to be sure. The exception problem is still there



  • Luis E

    Ralf,

    Would it be possible for me to create a simple project that has the same problems I'm facing and send it to you Thanks


  • mike5432

    Ralf,

    Thanks again for taking to time to try and help me solve this problem. I am only using the Pool.Default flag 3 times, for 2 surfaces and for a simple vertex buffer. Here is the updated code snippit:

    case ResultCode.DeviceNotReset:

    try

    {

    outSurface0.ReleaseGraphics();

    outSurface1.ReleaseGraphics();

    vb.Dispose();

    device.Reset(this.presentParams);

    this.InitializeGraphics();

    deviceLost = false;

    return true;

    }

    catch (DirectXException exception)

    {

    if ((ResultCode)exception.ErrorCode == ResultCode.DeviceLost)

    return false;

    throw exception;

    }

    Where outSurface0 and outSurface1 are two surfaces I use for ping-ponging if my pixelshader uses more than 1 pass and vb is my vertex buffer. I'm not using any of the utility or helper classes from MS. Since the problem with being able to draw again after the device is lost seems fixed, could the problem solely be that I'm not handling resizing appropriately Thank again.


  • Device Lost Problem