Just in time for GDC, here's the latest RenderDoc release! The main focus in this release has been greatly improved support for linux and GL, but there's hopefully something here for everyone.
At the same time, I've made public a new homepage for RenderDoc with an easy to find link to the latest version, as well as news and any articles I write that might be interesting. If you're looking to link to RenderDoc, then that's the URL to use - https://renderdoc.org/
Binaries for this release are up on the downloads page for Windows and x64 linux as a binary tarball.
The Qt UI on linux is missing python support as I'm planning to design & document a proper python API for interop with renderdoc, but otherwise everything should pretty much be working. There's an issue on github tracking remaining polish tasks and things like that.
Work will continue on the Qt UI to get this polish complete so that it's at the same level of quality as the windows UI, and once it's at that level then the Qt UI will be rolled out across all platforms.
Also on the GL front, RenderDoc no longer requires hardware GL 4.3 support and EXT_direct_state_access/ARB_buffer_storage to replay (although that does mean some features will be disabled if they rely on functionality that isn't available). Instead it requires just 3.2 and a handful of extensions:
Largely these don't require actual hardware support, and any decent GL implementation will support them in software regardless of the hardware. This means you can use RenderDoc on the software mesa implementation without requiring the latest drivers:
- The Linux Qt UI is now comparable to the windows UI in feature set, and stable enough for everyday use.
- As mentioned above the GL support will now work correctly on any recent mesa (I tested against ~10.5 or 10.6). This means both fixing bugs in RenderDoc that mesa caught, as well as significantly lowering the requirements from 4.3 + EXT_direct_state_access + ARB_buffer_storage to 3.2 + a few non-hw extensions.
- Added support for VK_NV_external_memory* and VK_NV_dedicated_allocation Vulkan extensions, which are needed for VR rendering.
- New GPU counters are available on D3D11, D3D12 and GL - Primitives processed, shader invocations, rasterizer invocations. These counters are not currently exposed in the API but can be queried through the python shell. Thanks to @victor-moya for these.
- Add drawcall timings for copy/resolve/blit type operations in vulkan.
- When shader debugging add functions to run to the next texture operation, or run to the next floating point exception (instruction that generates a NaN/Inf). Thanks to @michaelkvance for this.
- Include the duration column when exporting data from the event browser.
- Add a warning for python if the libraries aren't loaded (only relevant for dev builds).
- When self-hosting RenderDoc (capturing it with itself) some new tool menu items appear in the UI to start/stop captures. There are also now some marker regions added during replay.
- Add some verification for GL buffers being bound, so that invalid buffer names won't crash immediately.
- Add support for the Vulkan extension VK_AMD_negative_viewport_height
- Add support for Vulkan extensions released in 1.0.39: VK_KHR_get_physical_device_properties2, VK_KHR_maintenance1, VK_EXT_direct_mode_display, VK_EXT_acquire_xlib_display, VK_EXT_display_surface_counter, VK_EXT_shader_subgroup_ballot, VK_EXT_shader_subgroup_vote, VK_EXT_swapchain_colorspace, and VK_KHR_shader_draw_parameters.
- When the global hook is active, prevent closing the program to avoid leaving a stale hook active.
- Add Map() buffer overwrite handling for OpenGL, using tinyfiledialogs for cross-platform messageboxes.
- When shader debugging, don't replay the capture commands at all. This means that when the shader debug happens it contains the same data as was visible in the capture before debugging, which can be different if there's non-deterministic behaviour like append/consume or atomics.
- Added a new option to hide any marker regions which only contain "API Calls" placeholders and not real drawcalls, for example if there are only queries inside the marker region.
- In the capture connection window, you can rename the label on captures.
- When a GL buffer contains padding, the struct definition reflected out will include dummy padding elements.
- When replaying D3D12 upload heap buffers, allocate them on a default heap instead if they're large. This prevents extreme slowdown when copying data to them as it must be memcpy'd instead of uploaded to the GPU and copied there.
- Added multi-instance picking, so if you are rendering multiple instances at once you can pick a vertex from any of them and the corresponding instance will be activated.
- Support for yet another new marker format for D3D, this time PIX3 for D3D12 only. Thanks to @tiago-rodrigues.
- Eliminate a performance cliff that could happen if a vulkan resource with a large number of subresources (e.g. a cubemap array with lots of mips) was split apart for the purposes of processing barriers, and then never recombined again during replay producing a lot of redundant barriers.
- When copy-pasting a quoted path into the capture dialog, the quotes are removed.
- Callstack entries that don't have any matching symbols will now be something like
$ORIGIN/../lib/to rpath for renderdoccmd and qrenderdoc, and similar change to setting
LD_LIBRARY_PATHwhen capturing, so that the file structure in linux tarballs will work as-is.
- If we see
SwapBuffers()being called a lot with no context active, add a log message about the problem.
- Added support for depth & stencil overlays on cubemap, array and renderbuffer targets.
- Add handling for InstanceStepRate values above 1 in vertex debugging.
- Fix a bug that would cause an instant crash loading any D3D12 capture on nvidia, due to an API requirement that's undocumented, unexplained and not mentioned by validation checking.
- Fixed a long-standing edge-case refcounting bug that could lead to pure virtual function calls or other funkiness while binding resources due to D3D hazard tracking. The explanation for this bug and the fix is kind of interesting but too long, so you can read more details in the first commit that revealed the bug and the second commit that actually fixed it.
- Work around an nvidia driver bug where D3D11_USAGE_IMMUTABLE buffers wouldn't apply an offset properly when calling CopySubresourceRegion. This could manifest a few ways, most often by incorrect values fetched for shader debugging, but also in the buffer viewer if a byte/row offset was specified.
- Fix hooking child processes when
CreateProcesswas imported from an API set. This could affect functions like
execvewhich did that internally.
- Fixed a case where you had a 64-bit RenderDoc that ran a 32-bit process which then launched a 64-bit process (e.g a 32-bit launcher for a 64-bit game). Only going from higher bitness to lower bitness was supported previously.
- Added a fallback case for if D3D12 versioned root signature functions aren't available, which can depend on your OS build version even if you have D3D12.
- Implement missing QueryInterface for
- Fix capture on DirectComposition swapchains, by forcing a fake HWND value.
- Handle non-NULL terminated strings in D3D11's SetPrivateData.
- Implement a workaround for executing programs on apple where environ can't be modified, search
PATHmanually and call
- Support re-compilation and re-linking of programs in GL during capture.
- Correct the value used for base vertex when fetching post-VS data on GL.
- Mark a couple of GL draws as instanced that weren't properly flagged.
- Ensure that GL persistent maps are always intercepted, and don't make GL maps persistent on replay.
- Check that programs exist in a GL capture when setting uniforms.
- Fix sRGB calculation when applying 'fake' gamma curve to texture data.
- glVertexArrayElementBuffer behaves weirdly with respect to GL_ELEMENT_ARRAY_BUFFER_BINDING, so we always emulate it with a non-DSA version
- Fix GLSL shader patching with comments on a preprocessor line.
- Fix a crash with Vulkan descriptors referring to deleted buffers with invalid IDs.
- Fix GL texture overlays rendering with multisampled textures.
- When copying attrib bindings between GL programs, re-link the program afterwards.
- Fix a crash trying to render the quad overdraw overlay on a 1x1 texture.
- Fix a crash with the options in the context menu on the pixel context panel when no capture is loaded.
- Prevent some crashes with the buffer viewer if it was closed while background work was happening, or if it was initialised too early and got some inconsistent state.
- Fix a D3D12 crash if a capture is empty enough to have no initial states.
- Fix a crash when a texture overlay is enabled and a subpass boundary is selected.
- Stop counting drawcall timings twice if there's a
SetMarkertype marker immediately before the draw.
- Fix a D3D12 crash if
RTsSingleHandleToDescriptorRangeis used to set 0 render targets.
- Fix timers in D3D12 re-using the same allocator for multiple recording command lists.
- Ignore any calls in D3D12 to set a root constant with a GPU virtual address of 0. This probably isn't valid but it seems to work so it may be legal but undocumented behaviour.
- Mark buffers as dirty when they are cleared before a frame capture, instead of leaving uninitialised data.
- Fix handling of bitwise shift operations in shader debugging, which can either be scalar (all components in the source vector shifted by one value) or component-wise.
- Don't try to initialise Vulkan features that aren't supported by the device, including creating MS <-> Array copy shaders.
- Fixed an edge case with the pixel history that would fail if only one event could possibly have written to the target, but it included some overdraw that required multiple results.
- When displaying pixel values in the texture viewer, apply the type hint (ie. if a typeless texture is being viewed as UINT).
- Fix editing compute shaders on Vulkan to create the correct pipeline type.
- Remove VK_LAYER_LUNARG_monitor during replay as it's quite buggy and will try to modify the title of any window presented to, which can lead to thread deadlocks if presentation doesn't happen on the UI thread.
- When creating a dummy GL context on linux use a pbuffer, as we must have some drawable to make a context current.
- Fix D3D12 crash if a 0 GPU virtual address is bound to a vertex buffer. I don't know if this is legal or not, but it seems to work so I allow it.
- Fix mesh picking not working with reverse-perspective cameras.
- Fix a case if the environment data is malformed and a line doesn't have an '=' character.
- Fix saving BGRA textures to HDR or EXR missing an endian swap.
- Fix a case in the pixel history where running a history on a D16 or D32 texture would fail.
- When creating direct-display surfaces in Vulkan, give them a fake window handle so that they can be captured properly.
- In shader editing, do a case-insensitive search for include files.
- Fix a very stupid bug where decoding hex digits from a string accidentally dropped the top bit.
- Fixed a crash when trying to replay a vkCmdExecuteCommands call alone.
- Addressed a potential problem with vulkan captures that would fail to replay due to memory requirements changing between capture and replay with added usage flags.
- Add some missing locking around GL context activation/creation/deletion functions.
- Store KHR_debug object labels internally rather than relying on the driver which may not work correctly.
- Fix a crash if a non-zero number of rects was passed to
ID3D11DeviceContext::ClearViewdue to the wrong count being used on replay.
- Fix a problem on linux where Qt widgets wouldn't paint properly due to a call to glXCreateWindow.
- Fix a potential crash on linux where a mapped pointer returned null after using
- Fixed a pixel shader debugging issue where re-generated inputs would be repacked by the compiler and so no longer match the vertex shader.
- Fixed drawcall timings and some overlays handling with GL's multidraw functions.
- Fix incorrect shader debug values returned from ld_raw / ld_structured due to component clamping being applied wrongly.
- A very hacky fix for internal D3D runtime code calling into a function using the wrong interface, when the interface is not available via QueryInterface.
- On D3D12 we need to add some descriptors of our own to descriptor heaps, because the API is limited and only allows binding one heap. Any time we need to patch a pipeline state object to use our own descriptors during replay we have to reserve our own descriptors in the heaps the application is using. Unfortunately if the app requests a heap of maximum size, reserving more will fail creation, so we have to clamp and just hope that our descriptors won't stomp over the application's.