help~~how to recreate direct3d device in dx11 like dx9

Started by
3 comments, last by jdyyx1984 8 years, 11 months ago

our game uses cryengine3 , we found some of our users reveived unexpected device_removed error in dx11/ device_lost in dx9 , we force recreated d3d device in dx9 and it worked fine for those users,but this engine can't recover itself from device_removed error in dx11,so i tried to add this process ,i met a problem: the return value of SwapChain::Present is alwasys DXGI_ERROR_DEVICE_REMOVED after the new d3d device is created,i can't find the reason

here is my steps

1. flush all rendering command

2. release device resources created with the old d3d device,such as all textures ,buffers,queries,render stats

3. release the old swapchain and d3d device , create new one

4, recreate all resources released in step2

5 resume rendering

the return value of present in step5 was DXGI_ERROR_DEVICE_REMOVED , but any other return values from D3D API before present was S_OK

i also tried to simplify the rendering pipeline, i removed all d3d api calls except a present, after recreating a new device, the render thread stalled in present, it even did not return. here is the stack info from visual studio

ntdll.dll!_ZwWaitForSingleObject@12()
ntdll.dll!_ZwWaitForSingleObject@12()
d3d11.dll!CUseCountedObjectRootEx<class NOutermost::CDevice>::InternalAddRef(void)
d3d11.dll!CUseCountedObject<class NOutermost::CDeviceChild>::AddRef(void)
d3d11.dll!CLayeredObjectWithCLS<class CDepthStencilState>::CContainedObject::AddRef(void)
d3d11.dll!ATL::AtlInternalQueryInterface(void *,struct ATL::_ATL_INTMAP_ENTRY const *,struct _GUID const &,void * *)
d3d11.dll!CLayeredObjectWithCLS<class CTexture2D>::_InternalQueryInterface(struct _GUID const &,void * *,struct ATL::_ATL_INTMAP_ENTRY const *)
d3d11.dll!CLayeredObjectWithCLS<class CTexture2D>::QueryInterface(struct _GUID const &,void * *)
d3d11.dll!ATL::CComObjectRootBase::_Delegate(void *,struct _GUID const &,void * *,unsigned long)
0cac7f00()
[???????????/???]
d3d11.dll!CUseCountedObjectRootEx<class NOutermost::CDevice>::InternalAddRef(void) ??
d3d11.dll!CUseCountedObject<class NOutermost::CDeviceChild>::AddRef(void) ??
d3d11.dll!CLayeredObjectWithCLS<class CDepthStencilState>::CContainedObject::AddRef(void) ??
d3d11.dll!ATL::AtlInternalQueryInterface(void *,struct ATL::_ATL_INTMAP_ENTRY const *,struct _GUID const &,void * *) ??
d3d11.dll!CLayeredObjectWithCLS<class CTexture2D>::_InternalQueryInterface(struct _GUID const &,void * *,struct ATL::_ATL_INTMAP_ENTRY const *) ??
00000001() ??
d3d11.dll!CLayeredObjectWithCLS<class CDepthStencilState>::CContainedObject::AddRef(void) ??
d3d11.dll!ATL::AtlInternalQueryInterface(void *,struct ATL::_ATL_INTMAP_ENTRY const *,struct _GUID const &,void * *) ??
d3d11.dll!CLayeredObjectWithCLS<class CTexture2D>::_InternalQueryInterface(struct _GUID const &,void * *,struct ATL::_ATL_INTMAP_ENTRY const *) ??
d3d11.dll!CLayeredObjectWithCLS<class CTexture2D>::QueryInterface(struct _GUID const &,void * *) ??
d3d11.dll!ATL::CComObjectRootBase::_Delegate(void *,struct _GUID const &,void * *,unsigned long) ??
d3d11.dll!ATL::AtlInternalQueryInterface(void *,struct ATL::_ATL_INTMAP_ENTRY const *,struct _GUID const &,void * *) ??
d3d11.dll!CLayeredObjectWithCLS<class CTexture2D>::_InternalQueryInterface(struct _GUID const &,void * *,struct ATL::_ATL_INTMAP_ENTRY const *) ??
d3d11.dll!CLayeredObject<class NDXGI::CResource>::QueryInterface(struct _GUID const &,void * *) ??
d3d11.dll!ATL::CComObjectRootBase::_Delegate(void *,struct _GUID const &,void * *,unsigned long) ??
d3d11.dll!TComObject<class NOutermost::CDevice>::AddRef(void) ??
d3d11.dll!CBridgeImpl<struct IUseCounted,struct ID3D11LayeredUseCounted,class CLayeredObjectWithCLS<class CTexture1D> >::UCEstablishCyclicReferences(void) ??
d3d11.dll!CBridgeImpl<struct IUseCounted,struct ID3D11LayeredUseCounted,class CLayeredObject<class NDXGI::CResource> >::UCEstablishCyclicReferences(void) ??
d3d11.dll!NOutermost::CDeviceChild::UCEstablishCyclicReferences(void) ??
d3d11.dll!CUseCountedObject<class NOutermost::CDeviceChild>::CProtectFinalConstruct::~CProtectFinalConstruct(void) ??
ntdll.dll!_RtlAllocateHeap@12() ??
d3d11.dll!ATL::AtlInternalQueryInterface(void *,struct ATL::_ATL_INTMAP_ENTRY const *,struct _GUID const &,void * *) ??
KernelBase.dll!_ReleaseSemaphore@12() ??

does any one know any clue about my problem?unsure.png thanks!!!!

Advertisement

Have you read the documentation?

Device removal in D3D11 is more serious (and should be less common) than loss of the device in D3D9. You basically need to recreate everything, including re-initializing the device itself.

That said, if you get this error frequently that suggests a more serious problem. You should only get that message under normal circumstances when the device is physically removed (or if the drivers updated). You can try calling GetDeviceRemovedReason to find out what's up. Bad drivers or a bad card may be involved.

In my experience, the #1 cause of a device removed is the driver crashing or hanging. You can get a hang pretty easily by running a shader on the GPU that executes for too long, which causes a WDDM timeout to occur.

To what has been said, because this error is often caused by a driver hang, driver crash, or GPU taking too long (and sometimes, faulty hardware); this problem often goes away by asking the user to update their GPU drivers.

thanks for your replies!

so i think i should show some warning message to users then abort the process

This topic is closed to new replies.

Advertisement