how to recover from d3d device lost

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

how to recover from d3d device lost

Post by vitek »

When using render to texture, if the window is resized or whatever, a call to IDirect3DDevice9::Reset will not succeed until the render target texture is returned to the system.

I haven't really looked, but it appears that there is no notification being sent to anyone that the device was lost, so there is no way to know to release the render target. How are we supposed to know to release the render target texture?

I guess a simple way is to check the result of beginRender and assume failure means we need to deallocate the render target and try to re-create it again later? Or just unload the whole device and everything and try to start over...

Code: Select all

   // d3d8/9 drivers loop forever trying to reset device...
   irr::video::ITexture* rtt = driver->createRenderTargetTexture( irr::core::dimension2d<irr::s32>(512, 512) );
   while(Device->run() && Driver)
   {
      if (Device->isWindowActive())
      {
         driver->beginScene(true, true, video::SColor(255,50,50,50));

         driver->setRenderTarget(rtt, true, true, irr::video::SColor(120,50,50,50)); 
         smgr->drawAll();
         env ->drawAll();
         
         driver->setRenderTarget(0);
         smgr->drawAll();
         env ->drawAll();

         driver->endScene();
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

I have the same problem but no solution yet...

Regards - Xaron
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

Any news regarding this problem?

I still don't have a solution yet. :(

Thanks and regards - Xaron
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

Hmm... This seems to be a difficult topic. ;)

Come on. Does noone use the fullscreen? Have you ever tried to press Alt-Tab? :lol:

Regards - Xaron
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Currently there is no system for you to be notified that the device is lost. There are several ways that you could solve the problem.

You could just extend the hack that is SEvent and add a device lost event type. Your event receiver could respond to that and forward the message on to other systems that might need to know about the problem. You would need to modify the D3D drivers to send this notification.

You could add an method to the IVideoDriver that allows you to set a callback or register a device lost listener. The derived drivers would use the callback or listener when the device was lost. This is basically the same as above, but doesn't require extending the SEvent type list and is also a more correct solution imo. Of course you still need to modify the drivers to send the notification.

Of course you could write something outside Irrlicht that would periodically check the driver state [which can be accessed via getExposedVideoData().D3D9.D3DDev9->TestCooperativeLevel() and send a notification when the device state changes.
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

Thank you vitek! :) I think that should be integrated into Irrlicht, shouldn't it? ;)

Regards - Xaron
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Something should probably be done. It would be nice if Irrlicht just provided a single hook to know when the device is lost and when it is reset. That single hook could be used by us to do cleanup and reinitialization as necessary.

Travis
funcdoobiest
Posts: 48
Joined: Thu Jun 15, 2006 6:35 pm

Post by funcdoobiest »

Sorry to go slightly off topic but I had a couple of related questions one of you maybe able to answer? I was just looking in to resetting the device the other day and was wondering just how I make sure all neccesary resources (as it says in the docs, below) have been released in Irrlicht?
release any explicit render targets, depth stencil surfaces, additional swap chains, state blocks, and D3DPOOL_DEFAULT resources associated with the device.
and also how I would go about doing it, I know I could use the exposed video data and do it directly throught the device? However, I was looking at the reset() functioned defined in the DX9 driver class and it resets some things in the engine which i guess i would want to do. Plus I don't really like using the exposed data unless I really have to.

I had considered making a public reset() which will take present parameters , do some checking that the rendertargets ahve been released and also reset the Irrlicht stuff. (I just wasnt to be able to change the depth of the various buffers at runtime)

I agree with you Vitek on the device lost issue, it seems there is never any explicit notification that the device has been lost just the possibilty depending on the value retruned by beginScene(), it would be nice to know!
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

I think this is more an advanced topic and should be moved to the advanced forum?

@Devs: Any thoughts about that topic? How would you handle that? And could you please extend Irrlicht with that "feature"? ;)

Regards - Xaron
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Sorry, I don't know D3Dx that much, I cannot help here in any way. I couldn't even check a given patch. But if there's a working patch without side effects I guess this will make it into Irrlicht core.
So what is actually the problem--Irrlicht's ressource management or D3D's incorrect state changes?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

When you create a resource that is not managed by the device, it must be destroyed and recreated when the D3D device is lost. Irrlicht provides no real notification that the device is lost. Irrlicht does return false from beginScene() when something is wrong, but there is no way to tell what the problem was without writing D3D specific code.

What is needed is some sort of way to tell that the device reset is about to happen and when it is over. When this the pre-reset happens some resources would need to be released. After the reset has completed, the resources would need to be reallocated.

Unfortunately this is specific to D3D. There is no problem if the window size is fixed and not full screen. Obviously this is a way to work around the issue, but it is not a great solution.

The below test case will cause problems on a windows machine when you alt-tab out of the application.

Code: Select all

#include <irrlicht.h> 
#pragma comment(lib, "Irrlicht.lib") 

using namespace irr; 

int main() 
{
   // problem occurs when using a resource that is not managed by the device
   // and the resource is not released when the device is lost or reset. the
   // device is reset when you alt-tab out of full screen mode or when the
   // window is resized.
   IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D8, core::dimension2d<s32>(1024, 768), 16, true, false, false);
   if (device == 0) 
      return 1;

   // this is for the second issue mentioned below. change the createDevice
   // call above so that the window is not fullscreen and comment this in...
   //device->setResizeAble(true);

   video::IVideoDriver* driver = device->getVideoDriver(); 
   scene::ISceneManager* smgr = device->getSceneManager(); 

   driver->setAmbientLight(video::SColorf(.5f, .5f, .5f, 1.f)); 

   smgr->loadScene("../../media/example.irr");

   smgr->addCameraSceneNodeMaya();

   video::ITexture* rtt = 0;

   if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
      rtt = driver->createRenderTargetTexture( core::dimension2d<s32>(256, 256) );

   while(device->run()) 
   {
      if (device->isWindowActive()) 
      {
         if (driver->beginScene(true, true, video::SColor(255, 32, 32, 32)))
         {
            smgr->drawAll(); 

            driver->endScene(); 
         }
      }
   }

   if (rtt)
      rtt->drop();

   device->drop();

   return 0; 
}
There is another small, but related bug in here. In CD3D?Driver::reset(), the DeviceLost flag should get set when the pID3DDevice->Reset() call fails with D3DERR_DEVICELOST. If this is not set, I get a crash after resizing the Irrlicht window with the above test case.
Last edited by vitek on Sun Sep 10, 2006 10:31 am, edited 1 time in total.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Pertinent documenation is available here.

Travis
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I've added the reset handling fix to correctly update the DeviceLost variable. I'll consider the rest too much Win32 for me :wink:
Pr3t3nd3r
Posts: 186
Joined: Tue Feb 08, 2005 6:02 pm
Location: Romania
Contact:

Post by Pr3t3nd3r »

True! this is the problem. And not even that. I think is causing random game freeze when the device is temporary lost. ( not necesarly alt+tab )

Let me understand.
Any one found any solution(hack) for this ? ? ?
Galactic Dream Best RTS game
http://www.rageofwar.net
Engage in epic galactic warfare, guide your people through the galaxy! in the real time strategy game made with Irrlicht
http://www.evolutionvault.com
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

Post by xDan »

So is there a solution for this?

From what I read it seems I have to drop my render target textures *before* the game gets minimised? But I don't really understand how... It would seem when isWindowActive() returns false it is too late and the device thing has already been lost.

At the moment after alt+tabbing or minimising my game, restoring it causes a crash. I'm using Irrlicht 1.3. With direct3d8.

Note: I get errors in this order:
DIRECT3D8 device lost.
DIRECT3D8 end scene failed.

Help!
Post Reply