baldurk / renderdoc

RenderDoc is a stand-alone graphics debugging tool.
https://renderdoc.org
MIT License
8.85k stars 1.33k forks source link

RenderDoc fails on injection if D3DCompiler is not available on the system #153

Closed meng-hui closed 9 years ago

meng-hui commented 9 years ago

I am unable to get any captures when there are at least 2 display devices connected to the same graphics card. It works well when I have one display device only.

baldurk commented 9 years ago

Can you give more information or a repro case? I've used renderdoc on multi-head displays countless times - my main development machine has two displays connected to each of two devices.

meng-hui commented 9 years ago

From the diagnostic log, the problem seems to be that it cannot detect or get the "Used API" after remote handshake. It works on one machine and not the other running the same hardware and application. My application is a Unity3D application using D3D11, GTX 980, driver 355.60. Is there anything I need installed?

baldurk commented 9 years ago

No you won't need anything else installed. I'm not sure what you mean about not being able to detect or get the "Used API" - can you attach the full diagnostic log?

What exactly goes wrong - do you get the RenderDoc overlay in the application? does it appear, but you can't capture?

meng-hui commented 9 years ago
RENDERDOC:  [17:49:37]             core.cpp( 240) - Log     - RenderDoc v0.25 x64 (8df2e86805658ecdd2ffc70edf19fb0828a7d902-official) loaded in replay application
RENDERDOC:  [17:49:37]             core.cpp( 240) - Log     - RenderDoc v0.25 x64 (8df2e86805658ecdd2ffc70edf19fb0828a7d902-official) loaded in replay application
RENDERDOC:  [17:49:51]    win32_process.cpp( 288) - Log     - Injecting renderdoc into process 8608
RENDERDOC:  [17:49:53]    remote_access.cpp( 387) - Log     - Got remote handshake: App () [8608]
RENDERDOC:  [17:49:54]    remote_access.cpp( 598) - Log     - Used API: D3D11

When it does not work, I do not see the last line "Used API" in the log, I do not see the RenderDoc overlay and I cannot capture using F12 or by clicking capture within RenderDoc. Also to clarify, it is not affected by number of display devices. Is there any way to provide more info?

baldurk commented 9 years ago

Ah I see what you mean with the Used API - I didn't realise that you meant it was missing when you have the problem.

I know this sounds obvious, but have you checked that when it isn't working that you are definitely using D3D11? e.g. maybe D3D9 is being used instead, which RenderDoc doesn't support. In Unity you can check SystemInfo.graphicsDeviceType to see which device is being used, so try to log that out and check.

There will also be a diagnostic log written for the injected process (in your temp folder %TEMP% there will be a RenderDocreplay.....log and RenderDocapp......log. Can you attach the app log? it might have more information.

meng-hui commented 9 years ago

In both cases, Unity reports that SystemInfo.graphicsDeviceType is D3D11. The hardware is identical in both cases.

In the case that it does not work the log is

RENDERDOC:  [18:47:33]             core.cpp( 243) - Log     - RenderDoc v0.25 x64 (8df2e86805658ecdd2ffc70edf19fb0828a7d902-official) capturing application
RENDERDOC:  [18:47:35]   win32_libentry.cpp(  70) - Log     - Loading into C:\***\App.exe
RENDERDOC:  [18:47:35]            hooks.cpp(  49) - Log     - Loaded and hooked into kernel32.dll, PID 2888
RENDERDOC:  [18:47:35]      d3d11_hooks.cpp(  45) - Error   - Failed to load d3dcompiler_??.dll - not inserting D3D11 hooks.
RENDERDOC:  [18:47:35]            hooks.cpp(  53) - Warning - Couldn't hook into d3d11.dll
RENDERDOC:  [18:47:35]            hooks.cpp(  49) - Log     - Loaded and hooked into d3d9.dll, PID 2888
RENDERDOC:  [18:47:35]            hooks.cpp(  49) - Log     - Loaded and hooked into dxgi.dll, PID 2888
RENDERDOC:  [18:47:35]            hooks.cpp(  49) - Log     - Loaded and hooked into opengl32.dll, PID 2888
RENDERDOC:  [18:47:35]     entry_points.cpp( 372) - Log     - Using logfile C:\***\App_2015.09.14_18.47.33.rdc
RENDERDOC:  [18:47:35]     entry_points.cpp( 379) - Log     - Setting capture options
RENDERDOC:  [18:47:35]     dxgi_wrapped.cpp( 548) - Warning - Querying IDXGIObject for interface: GUID {7abb6563-02bc-47c4-8ef9-acc4795edbcf}
RENDERDOC:  [18:47:51]     dxgi_wrapped.cpp( 130) - Error   - Creating swap chain with non-hooked device!

In the case that it works the log looks like

RENDERDOC:  [18:44:23]             core.cpp( 243) - Log     - RenderDoc v0.25 x64 (8df2e86805658ecdd2ffc70edf19fb0828a7d902-official) capturing application
RENDERDOC:  [18:44:23]   win32_libentry.cpp(  70) - Log     - Loading into C:\***\App.exe
RENDERDOC:  [18:44:23]            hooks.cpp(  49) - Log     - Loaded and hooked into kernel32.dll, PID 3600
RENDERDOC:  [18:44:23]            hooks.cpp(  49) - Log     - Loaded and hooked into d3d11.dll, PID 3600
RENDERDOC:  [18:44:23]            hooks.cpp(  49) - Log     - Loaded and hooked into d3d9.dll, PID 3600
RENDERDOC:  [18:44:23]            hooks.cpp(  49) - Log     - Loaded and hooked into dxgi.dll, PID 3600
RENDERDOC:  [18:44:23]            hooks.cpp(  49) - Log     - Loaded and hooked into opengl32.dll, PID 3600
RENDERDOC:  [18:44:23]     entry_points.cpp( 372) - Log     - Using logfile C:\***\App_2015.09.14_18.44.23.rdc
RENDERDOC:  [18:44:23]     entry_points.cpp( 379) - Log     - Setting capture options
RENDERDOC:  [18:44:23]     dxgi_wrapped.cpp( 548) - Warning - Querying IDXGIObject for interface: GUID {7abb6563-02bc-47c4-8ef9-acc4795edbcf}
baldurk commented 9 years ago

So the problem is that error in d3d11_hooks.cpp. If it fails to open d3dcompiler, it won't insert renderdoc's d3d11 hooks and the d3d11 device will go straight to the real implementation without renderdoc's interception.

So the problem is why there isn't any d3dcompiler dll found on that machine. I try to be fairly aggressive in searching, so I look for the dlls in this order:

        "d3dcompiler_47.dll",
        "d3dcompiler_46.dll",
        "d3dcompiler_45.dll",
        "d3dcompiler_44.dll",
        "d3dcompiler_43.dll",

First I try to find a module already loaded (so I don't load a second version into the process). Unity does all its shader compilation in the editor, so this won't find anything. Then I try to load them from the default system library path, in that order.

So it sounds like this machine maybe doesn't have any recent D3D11 redistributable installed on it? I think Windows 8 and above actually ship with d3dcompiler in the system dirs, and windows 7 just needs any redistributable past the June 2010 (which was version 43). Can you check to see what DLLs are available on your system?

I can probably improve renderdoc's handling of this - the LoadLibrary path will only include the system directories and the application's directory. I do ship that latest version of d3dcompiler with renderdoc, so I can load it from there if all else fails - but this might break somewhere else, so I'd recommend installing D3D11 properly on the machine.

meng-hui commented 9 years ago

Yup, it was a Windows 7 machine without any d3dcompiler.dll in the system directory. Managed to resolve it by installing Microsoft DirectX End-User Runtimes (June 2010)

Thanks!

baldurk commented 9 years ago

Closing immediately as I don't expect anyone to test this, but I moved all of my d3dcompiler.dlls out of the windows paths (so that they'd fail LoadLibrary), repro'd the bug, and this worked for me.