calling CreateVertexBuffer/CreateTexture when the device is lost

Started by
3 comments, last by musawirali 14 years, 2 months ago
I'm trying to create a simple game with Direct3D, and I'm not sure how I should handle the creation of resources. I know CreateDevice can fail in some situations (e.g. when UAC pops up), so if CreateDevice returns DEVICELOST I just create a Windows timer that will try to create the device every second or so. This seems to work. Now I want to create vertex buffers and textures. According to the documentation:
Quote:If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY
Now I'm wondering, what will happen if I call this function when the device is lost? And what should I do if the call fails? Should I show an error message and close the program, or try to create the vertex buffer/texture later?
Advertisement
You should not even be worrying about this. You should only be checking for a lost device during the frame rendering.

If the device is lost its obvisouly not going to work, but you should be loading your textures a certain intervals in the games where you know the device is not lost.
you don't need a timer. Before you start rendering your frame (or using your D3D vidmem resources), call TestCoooperativeLevel() on your device and check if it needs to be reset. If it does, reset the device and recreate your resources, and then continue rendering.
Thanks for replying, but I think I found the answer:
Quote:
Resources can consume video memory. Because a lost device is disconnected from the video memory owned by the adapter, it is not possible to guarantee allocation of video memory when the device is lost. As a result, all resource creation methods are implemented to succeed by returning D3D_OK, but do in fact allocate only dummy system memory. Because any video-memory resource must be destroyed before the device is resized, there is no issue of over-allocating video memory. These dummy surfaces allow lock and copy operations to appear to function normally until the application calls IDirect3DDevice9::Present and discovers that the device has been lost.

[...]

Internally, Direct3D does enough work to ensure that a lock operation will succeed after a device is lost. However, it is not guaranteed that the video-memory resource's data will be accurate during the lock operation. It is guaranteed that no error code will be returned. This allows applications to be written without concern for device loss during a lock operation.

[...]

Direct3D allows applications to validate texture and render states against single pass rendering by the hardware using IDirect3DDevice9::ValidateDevice. This method, which is typically invoked during initialization of the application, will return D3DERR_DEVICELOST if the device has been lost.

Direct3D also allows applications to copy generated or previously written images from video-memory resources to nonvolatile system-memory resources. Because the source images of such transfers might be lost at any time, Direct3D allows such copy operations to fail when the device is lost.

Regarding asynchronous queries, IDirect3DQuery9::GetData returns D3DERR_DEVICELOST if the FLUSH flag is specified, in order to indicate to the application that IDirect3DQuery9::GetData will never return S_OK.

The copy operation, IDirect3DDevice9::GetFrontBufferData, can fail with D3DERR_DEVICELOST since there is no primary surface when the device is lost. IDirect3DDevice9::CreateAdditionalSwapChain can also fail with D3DERR_DEVICELOST because a back buffer can't be created when the device is lost. Note that these cases are the only instance of D3DERR_DEVICELOST outside of the IDirect3DDevice9::Present, IDirect3DDevice9::TestCooperativeLevel, and IDirect3DDevice9::Reset methods.

i.e. creating resources will succeed, but the data will be written to system memory instead of video memory. If the resource is managed Direct3D will write it to video memory after you reset the device. If the resource is not managed you have to destroy it anyway when resetting the device, so it doesn't really matter.

Quote:Original post by musawirali
you don't need a timer. Before you start rendering your frame (or using your D3D vidmem resources), call TestCoooperativeLevel() on your device and check if it needs to be reset. If it does, reset the device and recreate your resources, and then continue rendering.


I'm not rendering all the time: when the game is paused or when a dialog is shown, rendering 30/60 times per second would be a waste of time. If the device is lost I have to create a timer, otherwise the window will remain black as long as nothing is rendered. After the device is reset the draw function is called again.

[Edited by - Maarten Baert on February 11, 2010 3:23:11 PM]
hence the reference to "D3D vidmem resources". If you are using managed or sysmem resources then you shouldn't be having problems with dangling resource memory anyway, so we assumed that you are talking about vidmem.

This topic is closed to new replies.

Advertisement