简体   繁体   中英

D3D device invalidated or destroyed prematurely

At least one user of my software has encountered a very strange crash after a Windows 10 update. This crash always happens in the same place, and it appears as if the IDirect3DDevice9 has been destroyed or invalidated in some way during a previous call.

There is nothing else in the program that would release or destroy this device prematurely, and there are no other threads that could possibly interfere. The user has said updating their video drivers did not fix the problem, and their graphics card is an Nvidia GTX 1060 6GB, so a little older but by no means a potato.

IDirect3DSurface9 *s;
HRESULT hr = m_d3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&s);
if(FAILED(hr)) {
    ...
    return;
}

// crash happens here, when pushing m_d3dDevice to the stack before the call
m_d3dDevice->SetRenderTarget(0,s);

The above code crashes before calilng SetRenderTarget . The m_d3dDevice value is read successfully from this , but when the pointer is dereferenced again to get the vftable, the program crashes. Here's the disassembly:

mov     eax, [edi+1Ch]      ; read m_d3dDevice
push    [ebp+var_E0]        ; push s
push    0                   ; push 0
mov     ecx, [eax]          ; load vftable; crashes here
push    eax                 ; push m_d3dDevice (this)
call    dword ptr [ecx+94h] ; call SetRenderTarget

The call to GetBackBuffer() completes successfully just before this point. Without a successful completion, it would bail out of the function. Nothing else in my code could possibly be destroying the device, or the object this code belongs to, during this time.

Also, I should mention that this code is in a final presentation routine, which is usually only called after other rendering steps have been done. (After SetRenderTarget(), a temporary surface that was used for all the drawing is rendered to the back buffer using a special shader for upscaling, before Present() is called.) Just prior to this code being called, the device has been confirmed to still be active via TestCooperativeLevel(), so this code will not be reached if the device is not ready to do any of this.

As far as I know this crash does not happen to every user, only to some (one confirmed, possibly two). Is it possible, even perhaps likely, that some other program on their system is the issue? I don't know why it would appear out of the blue even if so, but I have no idea why the device is destroyed/invalid when the second call happens yet perfectly valid during the first.

Update to this issue: The user who reported this was using MSI Afterburner, which apparently was the cause of this. After shutting down Afterburner, the application ran correctly. I was correct that an outside program was interfering, although it still isn't clear why the Windows 10 update impacted it. This suggests Afterburner does some DirectX hooks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM