protonscr

apitrace's d3dretrace.exe crashes at d3d11.dll when trying to take a snapshot most of the time

dxvkclosed
doitsujin/dxvk#1511 · opened 2020-03-15 by tanty · updated 2020-03-18 · 11 comments · github
Ttanty 2020-03-15 github

Replaying a captured D3D11 apitrace works well but, when trying to take a snapshot, wine crashes with a "exception 0xc0000005" most of the times (not always).

Software information

WickedEngine Tests for x64:
https://wickedengine.net/downloads/

System information

  • Intel Kabylake, and AMD Radeon (POLARIS10)
  • anv and radv
  • Reproduced with 4.0-2, 4.2-2 (development), 5.0.0~buster (stable), and 5.3-buster (staging). All in Debian Buster.
  • Reproduced with all the versions from 1.4.6 to 1.5.5 and master.

Apitrace file(s)

Log files

Wine debug log

Ddoitsujin maintainer 2020-03-15 github

What exactly do you mean by "snapshot"?

Ttanty 2020-03-15 github

The equivalent to "apitrace dump-images". Creating a capture from a frame call.

Ttanty 2020-03-15 github

I should have placed the command line call directly in the description. It is in the "wine-debug.log" file:

$ wine d3dretrace -S 368720 -s wicked-engine-Tests.trace- wicked-engine-Tests.trace

Ddoitsujin maintainer 2020-03-15 github

This appears to be a reference counting bug. Unfortunately, the last time I tried to fix that, it broke a very large number of games, despite passing most wine tests, so I'm not sure if this can be fixed without a rewrite.

Why is this important anyway? There are way better debuggers out there than apitrace. I'm really not keen on changing anything in the D3D11 implementation anymore to avoid regressions, even if that means that this will stay broken forever.

Ttanty 2020-03-15 github

Just checking it for Mesa's CI in order to do pre-merge trace checking.

If I cannot use apitrace I may try to use renderdoc.

In the worst case I can just replay with apitrace and capture with LunarG's screenshot Vulkan Layer. I've checked and it seems to work, although it often skips the last frame :man_shrugging:

Anyway, just checking if the bug was really in DXVK and was easily fixable to ponder the alternatives.

Ddoitsujin maintainer 2020-03-15 github

Hm, I see. I guess it would be nice if that worked indeed.

I can try to give it another go at some point, but the problem is that D3D reference counting is completely undocumented, so the only thing I can work with is wine tests, and those don't necessarily tell the whole story.

Ttanty 2020-03-15 github

I understand. Any improvement would be great, even if it is just preventing the crash (which I don't know if can be done without actually fixing the bug).

I'll keep checking my options while this is not fixed. Thanks a lot!

Wwerman 2020-03-16 github

I've got the following back trace:

#0  0x000000006a357577 in dxvk::D3D11DeviceContext::BindSampler(unsigned int, dxvk::D3D11SamplerState*) ()
#1  0x000000006a362dca in dxvk::D3D11DeviceContext::RestoreState() ()
#2  0x000000006a369a83 in dxvk::D3D11ImmediateContext::SwapDeviceContextState(ID3DDeviceContextState*, ID3DDeviceContextState**) ()
#3  0x000000000047f997 in d3dstate::getRenderTargetImage (pSwapChain=0x2310760) at apitrace/retrace/dxgistate.cpp:401
#4  0x0000000000627449 in d3dretrace::D3DDumper<IDXGISwapChain>::getSnapshot (this=0x860620 <dxgiDumper>, n=0) at apitrace/retrace/d3dretrace.hpp:63
#5  0x0000000000502c02 in retrace::takeSnapshot (call_no=241, mrt=0, snapshot_no=0) at apitrace/retrace/retrace_main.cpp:195
#6  0x0000000000502fe9 in retrace::takeSnapshot (call_no=241) at apitrace/retrace/retrace_main.cpp:267
#7  0x0000000000502b57 in retrace::frameComplete (call=...) at apitrace/retrace/retrace_main.cpp:141
#8  0x00000000004b2727 in retrace_IDXGISwapChain__Present (call=...) at apitrace/build-win-dbg/retrace/d3dretrace_dxgi.cpp:1956
#9  0x0000000000502939 in retrace::Retracer::retrace (this=0x860800 <retracer>, call=...) at apitrace/retrace/retrace.cpp:157
[#10](/issue/doitsujin/dxvk/10) 0x0000000000503030 in retrace::retraceCall (call=0x48709d0) at apitrace/retrace/retrace_main.cpp:284
[#11](/issue/doitsujin/dxvk/11) 0x0000000000631c4c in retrace::RelayRunner::runLeg (this=0x226fcf0, call=0x48709d0) at apitrace/retrace/retrace_main.cpp:435
[#12](/issue/doitsujin/dxvk/12) 0x0000000000631dd9 in retrace::RelayRunner::runRace (this=0x226fcf0) at apitrace/retrace/retrace_main.cpp:413
[#13](/issue/doitsujin/dxvk/13) 0x0000000000503395 in retrace::RelayRace::run (this=0x32f8b0) at apitrace/retrace/retrace_main.cpp:553
[#14](/issue/doitsujin/dxvk/14) 0x0000000000503571 in retrace::mainLoop () at apitrace/retrace/retrace_main.cpp:614
[#15](/issue/doitsujin/dxvk/15) 0x0000000000504a96 in main (argc=4, argv=0x2211c90) at apitrace/retrace/retrace_main.cpp:1234
[#16](/issue/doitsujin/dxvk/16) 0x00000000004013a5 in __tmainCRTStartup () at /home/scarlet/Projects/mingw-w64-builds/pkg/mingw-w64-crt/src/mingw-w64-v6.0.0/mingw-w64-crt/crt/crtexe.c:339
[#17](/issue/doitsujin/dxvk/17) 0x000000000040150b in mainCRTStartup () at /home/scarlet/Projects/mingw-w64-builds/pkg/mingw-w64-crt/src/mingw-w64-v6.0.0/mingw-w64-crt/crt/crtexe.c:223
[#18](/issue/doitsujin/dxvk/18) 0x000000007b4599e6 in ?? ()

The relevant apitrace code https://github.com/apitrace/apitrace/blob/ffe58eee216a5ccadb314502e5595e0db2222da7/retrace/dxgistate.cpp#L355-L410 .

And the meat of the issue is:

com_ptr<ID3DDeviceContextState> pState;
hr = pD3D11Device1->CreateDeviceContextState(Flags, &FeatureLevel, 1, D3D11_SDK_VERSION, IID_ID3D11Device1, NULL, &pState);
if (SUCCEEDED(hr)) {
    com_ptr<ID3DDeviceContextState> pPreviousState;
    pD3D11DeviceContext->SwapDeviceContextState(pState, &pPreviousState);

    image = getSubResourceImage(pD3D11DeviceContext, pD3D11Resource, Format, 0, 0);

    pD3D11DeviceContext->SwapDeviceContextState(pPreviousState, NULL);

    return image;
}

New state is created, swapped with old one, image is requested, and the old state is returned.

In DXVK SwapDeviceContextState calls RestoreState which uses the state which was created by CreateDeviceContextState. However looking at d3d11_state_object.cpp shows that the state isn't initialized by default.

Ddoitsujin maintainer 2020-03-16 github

I pushed an alternative version of that fix with bf480ce6593aae769412dec8958e8ce936d3f51e, but note that this isn't where it was crashing for me when I tested. I was however able to work around the crash by not deleting any of the D3D objects.

Wwerman 2020-03-16 github

bf480ce fixes the crash for me. On release and debug apitrace and on release and debug DXVK.

Ttanty 2020-03-18 github

bf480ce is also fixing this crash for me.

Thanks a lot!

Error codes