Sign in to follow this  
JClayton

Alt-Tab Device Issues

Recommended Posts

JClayton    133
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"?

Share this post


Link to post
Share on other sites
Jiia    592
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?

Share this post


Link to post
Share on other sites
Dave Hunt    4872
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.

Share this post


Link to post
Share on other sites
JClayton    133
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!

Share this post


Link to post
Share on other sites
Jiia    592
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this