optick
optick copied to clipboard
FrameID-labeled Present/Vsync Queue, Vulkan fixes, plus other improvements
I have been meaning to post these changes for a while, but am finally getting around to it now. They were developed for use in RBDoom3BFG and run on all platforms: Windows, Linux, and macOS. They are a combination of bug fixes and feature enhancements as follows:
- Clear threadTLS on thread exit to improve runtime stability and to avoid memory leaks
- Use Vulkan events and floating point doubles to improve Vulkan GPU clock sync for reduced offset errors and drift.
- Eliminate Vulkan validation errors (#124) by using
vkResetQueryPool()vs.vkCmdResetQueryPool()when resolving timestamps. Note this requires instance initialization using Vulkan 1.2 and enabling thehostQueryResetfeature, or alternatively for non-1.2 applications, enabling theVK_EXT_host_query_resetextension. - Use Monotonic clock on macOS to match other platforms and be compatible with returned timing info from the
VK_GOOGLE_display_timing_extension. - Capture and resolve delayed GPU timestamps before dumping data on stop capture - these were previously lost. Also protect data dump with mutex lock to prevent random failures on stop capture.
- Add support for Vulkan Present/Vsync queue with frameID labeling via the
VK_GOOGLE_display_timing_extension. The feature is non-platform specific, but the extension is currently supported only on macOS/MoltenVK as far as I can tell. If other platforms were to implement the extension, the feature would work there as well. - Add support for labeling the DX12 Present/Vsync queue with frameID information. This is useful for determining CPU to GPU to Present frame latency.
- Add typeless prototype for
OPTICK_GPU_CONTEXT/GPUContextScope()which allows runtime selection of the graphics API for Optick (i.e. DX12 or Vulkan) without recompilation or reconfiguration. - Add support for: a) disabling static Vulkan functions via a config setting, and b) configuring dynamic Vulkan functions at runtime by providing only the
vkGetInstanceProcAddr()function pointer. Now discovers and assigns dynamic Vulkan functions separately for each device/node vs. assigning them globally. Static and manually assigned Vulkan functions remain global across devices/nodes. - Made changes to existing infrastructure to enable reporting of runtime errors with text descriptions both in debugger and to console stderr across all platforms.
- Fixed clang warnings for
vsprintf()deprecation, as well asunsigned longvsuint32_tandintvs.size_ttype mismatches. - Add support for data tags on custom storage events:
OPTICK_STORAGE_TAG(STORAGE, CPU_TIMESTAMP, NAME, ...)
Note: To implement these improvements I had to make a small number of Optick API changes. I tried to limit these to as few as possible to preserve some portability. Specifically, I had to add arguments to OPTICK_GPU_INIT_VULKAN() and OPTICK_GPU_FLIP(), plus add new Vulkan function pointers to VulkanFunctions . Please be aware that if you adopt this PR into an existing Optick implementation you may need to make a few changes.