HRESULT hr = device->TestCooperativeLevel();
if ( hr == D3DERR_DEVICELOST )
{
while ( 1 )
{
hr = device->TestCooperativeLevel();
if ( hr == D3DERR_DEVICENOTRESET )
{
Reset();
break;
}
}
}
Device lost handling
Hello everyone,
I'm trying to handle the device lost situation, but i'm missing some few info:
first, the code for this should look like this, right?
if so, all what Reset() should do is release media, reset device then reload media, right?
which media should be released, other than meshes?
thanks in advance
-Hassan
Quote:Original post by HassanbasilNope - You shouldn't do a while() loop like that; you're not processing window messages so the device will never get out of the lost state.
Hello everyone,
I'm trying to handle the device lost situation, but i'm missing some few info:
first, the code for this should look like this, right?
*** Source Snippet Removed ***
Quote:Original post by HassanbasilAs soon as you get your first D3DERR_DEVICELOST, you should Release() all D3DPOOL_DEFAULT resources, and call OnLostDevice() for any D3DX classes you have.
if so, all what Reset() should do is release media, reset device then reload media, right?
which media should be released, other than meshes?
When you then get D3DERR_DEVICENOTRESET, you should Reset() the device and then re-create any resources you need to and call OnResetDevice() for any D3DX objects that require it. Also note that you may get a D3DERR_DEVICENOTRESET without a D3DERR_DEVICELOST error, in which case you should act as if you got a D3DERR_DEVICELOST error first (I.e. Release() all default pool objects, etc).
Thanks for the reply, so it should look like:
PreResetStuff() should release D3DPOOL_DEFAULT resources, and call OnDeviceLost for meshes/textues/sprites? what does OnDeviceLost() do? saves anything from the mesh? or i need the vertex/index buffers of the object before losing the device and re-create meshes using them?
also, are you saying that if i get the D3DERR_DEVICENOTRESET without D3DERR_DEVICELOST, i should do the same as getting a D3DERR_DEVICELOST?
HRESULT hr = device->TestCooperativeLevel();if ( hr == D3DERR_DEVICELOST ){ PreResetStuff(); while ( 1 ) { HandleMessages(); hr = device->TestCooperativeLevel(); if ( hr == D3DERR_DEVICENOTRESET ) { Reset(); break; } }}
PreResetStuff() should release D3DPOOL_DEFAULT resources, and call OnDeviceLost for meshes/textues/sprites? what does OnDeviceLost() do? saves anything from the mesh? or i need the vertex/index buffers of the object before losing the device and re-create meshes using them?
also, are you saying that if i get the D3DERR_DEVICENOTRESET without D3DERR_DEVICELOST, i should do the same as getting a D3DERR_DEVICELOST?
Quote:Original post by HassanbasilPretty much - that won't handle the case where you get a D3DERR_DEVICENOTRESET without a D3DERR_DEVICELOST error though. I'd do:
Thanks for the reply, so it should look like:
*** Source Snippet Removed ***
HRESULT hr = device->TestCooperativeLevel();if(hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET){ PreResetStuff(); while(hr == D3DERR_DEVICELOST) { HandleMessages(); hr = device->TestCooperativeLevel(); } Reset();}
Note that TestCooperativeLevel() can also return D3DERR_DRIVERINTERNALERROR, in which case you should probably just exit as quickly as possible (The docs says you could re-create the device, but that's a pretty major thing to do).
Quote:Original post by HassanbasilYou only need to call OnLostDevice() for D3DX classes that you have instances of that have that as a member function. The documentation says thats for ID3DXEffect, ID3DXFont, ID3DXLine, ID3DXRenderToEnvMap, ID3DXRenderToSurface, and ID3DXSprite). All that does is Release()s the objects internal data structures (E.g. the dynamic vertex buffer maintained by ID3DXSprite).
PreResetStuff() should release D3DPOOL_DEFAULT resources, and call OnDeviceLost for meshes/textues/sprites? what does OnDeviceLost() do? saves anything from the mesh? or i need the vertex/index buffers of the object before losing the device and re-create meshes using them?
Quote:Original post by HassanbasilSee my example above.
also, are you saying that if i get the D3DERR_DEVICENOTRESET without D3DERR_DEVICELOST, i should do the same as getting a D3DERR_DEVICELOST?
I do not open an extra thread for my question, because this is the same topic. On my DX11 engine I can switch between windowed and fullscreen just by pressing alt+return. It apears, that the switch has some problems to get the proper mode, but then all runs well.
I think, I still have to handle the device reset, even on DX11. But why can I switch between the modes without an exception? Is this a feature of SlimDX, of DX11 or maybe Win7? (Aero?)
On Dx9, there I get an exception, if I do not handle the switch correctly. ^^
I think, I still have to handle the device reset, even on DX11. But why can I switch between the modes without an exception? Is this a feature of SlimDX, of DX11 or maybe Win7? (Aero?)
On Dx9, there I get an exception, if I do not handle the switch correctly. ^^
sorry for bumping this, but i'm getting some problems that i didnt notice last time:
my current handling:
this works just fine if i alt+ctrl+delete and get back, but if i ALT-tab or press the start button on keyboard, i get an unhandled exception at TextSprite->OnLostDevice ( );, what's happening there?
P.S. i dont have anything that uses D3DPOOL_DEFAULT at the moment.
my current handling:
//render HRESULT hr = device->TestCooperativeLevel ( ); if ( hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET ) { if ( !HandleLostDevice ( ) ) { CheckErrors ( ); exit ( 0 ); return; } } else if ( hr == D3DERR_DRIVERINTERNALERROR ) { PostError ( "Fatal error: Driver cannot be reset due to a driver error", true ); return; }//HandleLostDevicebool hxCore::HandleLostDevice ( void ){ TextSprite->OnLostDevice ( ); for ( int i = 0; i < SpriteV.size(); i++ ) SpriteV->Sprite->OnLostDevice ( ); for ( int i = 0; i < FontV.size(); i++ ) FontV.font->OnLostDevice ( ); HRESULT hr = device->TestCooperativeLevel ( ); while ( hr == D3DERR_DEVICELOST ) { hr = device->TestCooperativeLevel ( ); if ( !Loop ( ) ) //window messages handling return false; else if ( hr == D3DERR_DRIVERINTERNALERROR ) { PostError ( "Fatal error: device cannot be reset due to a driver error", true ); return false; } } return Init ( windowWidth, windowHeight, windowDepth, windowMode, maxFps );}//Init PresentParameters->BackBufferWidth = Width; PresentParameters->BackBufferHeight = Height; if ( Depth == 32 ) PresentParameters->AutoDepthStencilFormat = D3DFMT_D24S8; else if ( Depth == 16 ) PresentParameters->AutoDepthStencilFormat = D3DFMT_D16; PresentParameters->Windowed = windowed; HRESULT hr = device->Reset ( PresentParameters ); if ( FAILED ( hr ) ) { char Err[200]; switch ( hr ) { case D3DERR_DEVICELOST: if ( !HandleLostDevice ( ) ) { CheckErrors ( ); exit ( 0 ); return false; } break; case D3DERR_DEVICEREMOVED: sprintf_s ( Err, 200, "Failed to create the device\nDevice removed" ); break; case D3DERR_DRIVERINTERNALERROR: sprintf_s ( Err, 200, "Failed to create the device\nInternal error" ); break; case D3DERR_OUTOFVIDEOMEMORY : sprintf_s ( Err, 200, "Failed to create the device\nOut of memory" ); break; default : sprintf_s ( Err, 200, "Failed to create the device\nError code: %d", (int)hr ); break; } PostError ( this, Err, true ); return false; } device->SetSamplerState ( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); device->SetSamplerState ( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); device->SetSamplerState ( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); device->SetRenderState ( D3DRS_AMBIENT, D3DCOLOR_XRGB ( 100, 100, 100 ) ); // set blending factors so that alpha component determines transparency device->SetRenderState ( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); device->SetRenderState ( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); if ( FAILED ( D3DXCreateSprite ( device, &TextSprite ) ) ) { PostError ( this, "Unable to initiallize text", true ); return false; } for ( int i = 0; i < SpriteV.size(); i++ ) if ( SpriteV->vaild ) SpriteV->Create ( SpriteV->texture.fileName ); hFONT font; font.ID = 0; D3DXCreateFont ( device, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT ( "Arial" ), &font.font ); FontV.push_back ( font );
this works just fine if i alt+ctrl+delete and get back, but if i ALT-tab or press the start button on keyboard, i get an unhandled exception at TextSprite->OnLostDevice ( );, what's happening there?
P.S. i dont have anything that uses D3DPOOL_DEFAULT at the moment.
Quote:Original post by HassanbasilWhat is the exact error you're getting? It sounds like you've already Release()d the sprite, not initialised it, or already called OnLostDevice() on it (Although I would have thought the last would work).
this works just fine if i alt+ctrl+delete and get back, but if i ALT-tab or press the start button on keyboard, i get an unhandled exception at TextSprite->OnLostDevice ( );, what's happening there?
Quote:What is the exact error you're getting? It sounds like you've already Release()d the sprite, not initialised it, or already called OnLostDevice() on it (Although I would have thought the last would work).
ahh you're a jenious, it seems i've already released it ( yeah, it's hard to debug in full screen mode.. )
so anyway, here's what's happening:
1- i detect a device lost situation, and thus call HandleLostDevice ( mentioned above )
2- it calls Init when it's ready to reset
3- in the init function, i have this:
if ( !specFlag ) { TextSprite->Release ( ); for ( int i = 0; i < SpriteV.size(); i++ ) if ( SpriteV->vaild ) { SpriteV->Sprite->Release ( ); SpriteV->texture.tex->Release ( ); } for ( int i = 0; i < FontV.size(); i++ ) FontV.font->Release ( ); } PresentParameters->BackBufferWidth = Width; PresentParameters->BackBufferHeight = Height; if ( Depth == 32 ) PresentParameters->AutoDepthStencilFormat = D3DFMT_D24S8; else if ( Depth == 16 ) PresentParameters->AutoDepthStencilFormat = D3DFMT_D16; PresentParameters->Windowed = windowed; HRESULT hr = device->Reset ( PresentParameters ); if ( FAILED ( hr ) ) { char Err[200]; switch ( hr ) { case D3DERR_DEVICELOST: if ( !HandleLostDevice ( ) ) { CheckErrors ( ); exit ( 0 ); return false; } break; case D3DERR_DEVICEREMOVED: sprintf_s ( Err, 200, "Failed to create the device\nDevice removed" ); break; case D3DERR_DRIVERINTERNALERROR: sprintf_s ( Err, 200, "Failed to create the device\nInternal error" ); break; case D3DERR_OUTOFVIDEOMEMORY : sprintf_s ( Err, 200, "Failed to create the device\nOut of memory" ); break; default : sprintf_s ( Err, 200, "Failed to create the device\nError code: %d", (int)hr ); break; } PostError ( this, Err, true ); return false; }
--specFlag is false over there--
IDirect3DDevice9::Reset() returns D3DERR_DEVICELOST, so i re-call HandleLostDevice there, while the stuff are already released, and there goes the problem, why am i getting D3DERR_DEVICELOST there, when i already knew that i can recover the device from HandleLostDevice at the first place?
When you get D3DERR_DEVICELOST, that means "The device is lost and you can't currently reset it". In your code, you try to call Reset() anyway, even though it's lost (E.g. another app has focus).
If you get D3DERR_DEVICELOST, you need to wait until you get D3DERR_DEVICENOTRESET before you can attempt to reset it.
If you get D3DERR_DEVICELOST, you need to wait until you get D3DERR_DEVICENOTRESET before you can attempt to reset it.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement