Alt-Tab Device Issues

Started by
4 comments, last by Jiia 19 years ago
I posted earlier with regards to my program and its problem with resetting the device. I am unsure of where to reset the device if it is lost... I wrote my render function like this:
bool cVideo::RenderFrame()
{
  m_device->Clear(0, NULL, D3DCLEAR_TARGET, SYS_ColorBlack, 1.0f, 0);
  
  if(SUCCEEDED(m_device->BeginScene()))
  {
    // Render stuff...
    ExecuteCallback(CALLBACK_RENDER);
      
    m_device->EndScene();
  }
  
  HRESULT result;
  if(FAILED(result = m_device->Present(NULL, NULL, NULL, NULL)))
  {
    if(result == D3DERR_DEVICELOST)
    {     
      if(SUCCEEDED(m_device->Reset(&m_present)))
        ExecuteCallback(CALLBACK_RESET); // Reload all pooled resources
    }
  }

  return true;
}

However the device fails to reset because of an invalid parameter. How does everyone else normally do it? Do you check when the program regains focus to reset like this:
case WM_ACTIVATE:
  if(LOWORD(wParam) == WA_ACTIVE)
    Windows::Instance().SetFocus(true);
  else if(LOWORD(wParam) == WA_INACTIVE)
    Windows::Instance().SetFocus(false);
Or do you let the render function handle it for you as in the example above? Which is more "correct"?
Advertisement
Your code looks absolutely correct. But before you call reset, you have to free all video memory resources. Textures, meshes, shaders, etc. Then reset, then load them all back in. I don't use managed resources, but maybe something you're using is not managed?
Even when no resources are loaded the device reset fails...
When the device is lost you should release any resources and then call TestCooperativeLevel each frame until it returns D3DERR_DEVICENOTRESET. D3DERR_DEVICELOST means the device was lost and cannot be reset at this time. Also, make sure your m_present structure is filled out correctly.
Thanks alot. The code has been re-written to this:

bool cVideo::RenderFrame(){  static bool deviceLost = false;  HRESULT     result;    if(deviceLost == false)  {    m_device->Clear(0, NULL, D3DCLEAR_TARGET, SYS_ColorBlack, 1.0f, 0);      if(SUCCEEDED(m_device->BeginScene()))    {      // Render stuff...      ExecuteCallback(CALLBACK_RENDER);              m_device->EndScene();    }        // Flip the back buffer to the front    result = m_device->Present(NULL, NULL, NULL, NULL);    if(result == D3DERR_DEVICELOST)    {           deviceLost = true;      ExecuteCallback(CALLBACK_DEVICELOST);    }  }  else  {    result = m_device->TestCooperativeLevel();    if(result == D3DERR_DEVICENOTRESET)    {      if(SUCCEEDED(m_device->Reset(&m_present)))      {        ExecuteCallback(CALLBACK_RESET);        deviceLost = false;      }    }  }    return true;}


And it works like a charm!
Oops, sorry about missing that one.

The proper way to do this is to make your app sleep when it's not focused. If done correctly, you won't need to check to see when it can be reset. It might not seem like much of a difference, but sleeping will also fix problems simular to this one in all routines, such as input and audio. Plus your program isn't eating up processor time when it's not actually using it.

Use the WM_ACTIVATEAPP message to toggle focus. Then use WaitMessage() when you get deactivated. Windows will make your program sleep until you get another message.

This topic is closed to new replies.

Advertisement