Vulkan Logo

43. Debugging

To aid developers in tracking down errors in the application’s use of Vulkan, particularly in combination with an external debugger or profiler, debugging extensions may be available.

The VkObjectType enumeration defines values, each of which corresponds to a specific Vulkan handle type. These values can be used to associate debug information with a particular type of object through one or more extensions.

// Provided by VK_VERSION_1_0
typedef enum VkObjectType {
    VK_OBJECT_TYPE_UNKNOWN = 0,
    VK_OBJECT_TYPE_INSTANCE = 1,
    VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
    VK_OBJECT_TYPE_DEVICE = 3,
    VK_OBJECT_TYPE_QUEUE = 4,
    VK_OBJECT_TYPE_SEMAPHORE = 5,
    VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
    VK_OBJECT_TYPE_FENCE = 7,
    VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
    VK_OBJECT_TYPE_BUFFER = 9,
    VK_OBJECT_TYPE_IMAGE = 10,
    VK_OBJECT_TYPE_EVENT = 11,
    VK_OBJECT_TYPE_QUERY_POOL = 12,
    VK_OBJECT_TYPE_BUFFER_VIEW = 13,
    VK_OBJECT_TYPE_IMAGE_VIEW = 14,
    VK_OBJECT_TYPE_SHADER_MODULE = 15,
    VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
    VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
    VK_OBJECT_TYPE_RENDER_PASS = 18,
    VK_OBJECT_TYPE_PIPELINE = 19,
    VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
    VK_OBJECT_TYPE_SAMPLER = 21,
    VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
    VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
    VK_OBJECT_TYPE_FRAMEBUFFER = 24,
    VK_OBJECT_TYPE_COMMAND_POOL = 25,
  // Provided by VK_VERSION_1_1
    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000,
  // Provided by VK_VERSION_1_1
    VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000,
  // Provided by VK_VERSION_1_3
    VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000,
  // Provided by VK_KHR_surface
    VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
  // Provided by VK_KHR_swapchain
    VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
  // Provided by VK_KHR_display
    VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
  // Provided by VK_KHR_display
    VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
  // Provided by VK_KHR_video_queue
    VK_OBJECT_TYPE_VIDEO_SESSION_KHR = 1000023000,
  // Provided by VK_KHR_video_queue
    VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR = 1000023001,
  // Provided by VK_KHR_acceleration_structure
    VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000,
  // Provided by VK_KHR_deferred_host_operations
    VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000,
  // Provided by VK_EXT_opacity_micromap
    VK_OBJECT_TYPE_MICROMAP_EXT = 1000396000,
  // Provided by VK_EXT_shader_object
    VK_OBJECT_TYPE_SHADER_EXT = 1000482000,
  // Provided by VK_KHR_descriptor_update_template
    VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
  // Provided by VK_KHR_sampler_ycbcr_conversion
    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
} VkObjectType;
Table 81. VkObjectType and Vulkan Handle Relationship
VkObjectType Vulkan Handle Type

VK_OBJECT_TYPE_UNKNOWN

Unknown/Undefined Handle

VK_OBJECT_TYPE_INSTANCE

VkInstance

VK_OBJECT_TYPE_PHYSICAL_DEVICE

VkPhysicalDevice

VK_OBJECT_TYPE_DEVICE

VkDevice

VK_OBJECT_TYPE_QUEUE

VkQueue

VK_OBJECT_TYPE_SEMAPHORE

VkSemaphore

VK_OBJECT_TYPE_COMMAND_BUFFER

VkCommandBuffer

VK_OBJECT_TYPE_FENCE

VkFence

VK_OBJECT_TYPE_DEVICE_MEMORY

VkDeviceMemory

VK_OBJECT_TYPE_BUFFER

VkBuffer

VK_OBJECT_TYPE_IMAGE

VkImage

VK_OBJECT_TYPE_EVENT

VkEvent

VK_OBJECT_TYPE_QUERY_POOL

VkQueryPool

VK_OBJECT_TYPE_BUFFER_VIEW

VkBufferView

VK_OBJECT_TYPE_IMAGE_VIEW

VkImageView

VK_OBJECT_TYPE_SHADER_MODULE

VkShaderModule

VK_OBJECT_TYPE_PIPELINE_CACHE

VkPipelineCache

VK_OBJECT_TYPE_PIPELINE_LAYOUT

VkPipelineLayout

VK_OBJECT_TYPE_RENDER_PASS

VkRenderPass

VK_OBJECT_TYPE_PIPELINE

VkPipeline

VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT

VkDescriptorSetLayout

VK_OBJECT_TYPE_SAMPLER

VkSampler

VK_OBJECT_TYPE_DESCRIPTOR_POOL

VkDescriptorPool

VK_OBJECT_TYPE_DESCRIPTOR_SET

VkDescriptorSet

VK_OBJECT_TYPE_FRAMEBUFFER

VkFramebuffer

VK_OBJECT_TYPE_COMMAND_POOL

VkCommandPool

VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION

VkSamplerYcbcrConversion

VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE

VkDescriptorUpdateTemplate

VK_OBJECT_TYPE_PRIVATE_DATA_SLOT

VkPrivateDataSlot

VK_OBJECT_TYPE_SURFACE_KHR

VkSurfaceKHR

VK_OBJECT_TYPE_SWAPCHAIN_KHR

VkSwapchainKHR

VK_OBJECT_TYPE_DISPLAY_KHR

VkDisplayKHR

VK_OBJECT_TYPE_DISPLAY_MODE_KHR

VkDisplayModeKHR

VK_OBJECT_TYPE_VIDEO_SESSION_KHR

VkVideoSessionKHR

VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR

VkVideoSessionParametersKHR

VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR

VkAccelerationStructureKHR

VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR

VkDeferredOperationKHR

VK_OBJECT_TYPE_MICROMAP_EXT

VkMicromapEXT

VK_OBJECT_TYPE_SHADER_EXT

VkShaderEXT

If this Specification was generated with any such extensions included, they will be described in the remainder of this chapter.

43.1. Active Tooling Information

Information about tools providing debugging, profiling, or similar services, active for a given physical device, can be obtained by calling:

// Provided by VK_VERSION_1_3
VkResult vkGetPhysicalDeviceToolProperties(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pToolCount,
    VkPhysicalDeviceToolProperties*             pToolProperties);
  • physicalDevice is the handle to the physical device to query for active tools.

  • pToolCount is a pointer to an integer describing the number of tools active on physicalDevice.

  • pToolProperties is either NULL or a pointer to an array of VkPhysicalDeviceToolProperties structures.

If pToolProperties is NULL, then the number of tools currently active on physicalDevice is returned in pToolCount. Otherwise, pToolCount must point to a variable set by the user to the number of elements in the pToolProperties array, and on return the variable is overwritten with the number of structures actually written to pToolProperties. If pToolCount is less than the number of currently active tools, at most pToolCount structures will be written.

The count and properties of active tools may change in response to events outside the scope of the specification. An application should assume these properties might change at any given time.

Valid Usage (Implicit)
  • VUID-vkGetPhysicalDeviceToolProperties-physicalDevice-parameter
    physicalDevice must be a valid VkPhysicalDevice handle

  • VUID-vkGetPhysicalDeviceToolProperties-pToolCount-parameter
    pToolCount must be a valid pointer to a uint32_t value

  • VUID-vkGetPhysicalDeviceToolProperties-pToolProperties-parameter
    If the value referenced by pToolCount is not 0, and pToolProperties is not NULL, pToolProperties must be a valid pointer to an array of pToolCount VkPhysicalDeviceToolProperties structures

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

The VkPhysicalDeviceToolProperties structure is defined as:

// Provided by VK_VERSION_1_3
typedef struct VkPhysicalDeviceToolProperties {
    VkStructureType       sType;
    void*                 pNext;
    char                  name[VK_MAX_EXTENSION_NAME_SIZE];
    char                  version[VK_MAX_EXTENSION_NAME_SIZE];
    VkToolPurposeFlags    purposes;
    char                  description[VK_MAX_DESCRIPTION_SIZE];
    char                  layer[VK_MAX_EXTENSION_NAME_SIZE];
} VkPhysicalDeviceToolProperties;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • name is a null-terminated UTF-8 string containing the name of the tool.

  • version is a null-terminated UTF-8 string containing the version of the tool.

  • purposes is a bitmask of VkToolPurposeFlagBits which is populated with purposes supported by the tool.

  • description is a null-terminated UTF-8 string containing a description of the tool.

  • layer is a null-terminated UTF-8 string containing the name of the layer implementing the tool, if the tool is implemented in a layer - otherwise it may be an empty string.

Valid Usage (Implicit)
  • VUID-VkPhysicalDeviceToolProperties-sType-sType
    sType must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES

  • VUID-VkPhysicalDeviceToolProperties-pNext-pNext
    pNext must be NULL

Bits which can be set in VkPhysicalDeviceToolProperties::purposes, specifying the purposes of an active tool, are:

// Provided by VK_VERSION_1_3
typedef enum VkToolPurposeFlagBits {
    VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001,
    VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002,
    VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004,
    VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008,
    VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010,
    VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT,
    VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT,
    VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT,
    VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT,
    VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT,
} VkToolPurposeFlagBits;
  • VK_TOOL_PURPOSE_VALIDATION_BIT specifies that the tool provides validation of API usage.

  • VK_TOOL_PURPOSE_PROFILING_BIT specifies that the tool provides profiling of API usage.

  • VK_TOOL_PURPOSE_TRACING_BIT specifies that the tool is capturing data about the application’s API usage, including anything from simple logging to capturing data for later replay.

  • VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT specifies that the tool provides additional API features/extensions on top of the underlying implementation.

  • VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT specifies that the tool modifies the API features/limits/extensions presented to the application.

// Provided by VK_VERSION_1_3
typedef VkFlags VkToolPurposeFlags;

VkToolPurposeFlags is a bitmask type for setting a mask of zero or more VkToolPurposeFlagBits.

43.2. Frame Boundary

The VkFrameBoundaryEXT structure is defined as:

// Provided by VK_EXT_frame_boundary
typedef struct VkFrameBoundaryEXT {
    VkStructureType            sType;
    const void*                pNext;
    VkFrameBoundaryFlagsEXT    flags;
    uint64_t                   frameID;
    uint32_t                   imageCount;
    const VkImage*             pImages;
    uint32_t                   bufferCount;
    const VkBuffer*            pBuffers;
    uint64_t                   tagName;
    size_t                     tagSize;
    const void*                pTag;
} VkFrameBoundaryEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • flags is a bitmask of VkFrameBoundaryFlagBitsEXT that can flag the last submission of a frame identifier.

  • frameID is the frame identifier.

  • imageCount is the number of images that store frame results.

  • pImages is a pointer to an array of VkImage objects with imageCount entries.

  • bufferCount is the number of buffers the store the frame results.

  • pBuffers is a pointer to an array of VkBuffer objects with bufferCount entries.

  • tagName is a numerical identifier for tag data.

  • tagSize is the number of bytes of tag data.

  • pTag is a pointer to an array of tagSize bytes containing tag data.

The application can associate frame boundary information to a queue submission call by adding a VkFrameBoundaryEXT structure to the pNext chain of queue submission, VkPresentInfoKHR, or VkBindSparseInfo.

The frame identifier is used to associate one or more queue submission to a frame, it is thus meant to be unique within a frame lifetime, i.e. it is possible (but not recommended) to reuse frame identifiers, as long as any two frames with any chance of having overlapping queue submissions (as in the example above) use two different frame identifiers.

Note

Since the concept of frame is application-dependent, there is no way to validate the use of frame identifier. It is good practice to use a monotonically increasing counter as the frame identifier and not reuse identifiers between frames.

The pImages and pBuffers arrays contain a list of images and buffers which store the "end result" of the frame. As the concept of frame is application-dependent, not all frames may produce their results in images or buffers, yet this is a sufficiently common case to be handled by VkFrameBoundaryEXT. Note that no extra information, such as image layout is being provided, since the images are meant to be used by tools which would already be tracking this required information. Having the possibility of passing a list of end-result images makes VkFrameBoundaryEXT as expressive as vkQueuePresentKHR, which is often the default frame boundary delimiter.

The application can also associate arbitrary extra information via tag data using tagName, tagSize and pTag. This extra information is typically tool-specific.

Valid Usage (Implicit)
  • VUID-VkFrameBoundaryEXT-sType-sType
    sType must be VK_STRUCTURE_TYPE_FRAME_BOUNDARY_EXT

  • VUID-VkFrameBoundaryEXT-flags-parameter
    flags must be a valid combination of VkFrameBoundaryFlagBitsEXT values

  • VUID-VkFrameBoundaryEXT-pImages-parameter
    If imageCount is not 0, and pImages is not NULL, pImages must be a valid pointer to an array of imageCount valid VkImage handles

  • VUID-VkFrameBoundaryEXT-pBuffers-parameter
    If bufferCount is not 0, and pBuffers is not NULL, pBuffers must be a valid pointer to an array of bufferCount valid VkBuffer handles

  • VUID-VkFrameBoundaryEXT-pTag-parameter
    If tagSize is not 0, and pTag is not NULL, pTag must be a valid pointer to an array of tagSize bytes

  • VUID-VkFrameBoundaryEXT-commonparent
    Both of the elements of pBuffers, and the elements of pImages that are valid handles of non-ignored parameters must have been created, allocated, or retrieved from the same VkDevice

The bit which can be set in VkFrameBoundaryEXT::flags is:

// Provided by VK_EXT_frame_boundary
typedef enum VkFrameBoundaryFlagBitsEXT {
    VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT = 0x00000001,
} VkFrameBoundaryFlagBitsEXT;
  • VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT specifies that this queue submission is the last one for this frame, i.e. once this queue submission has terminated, then the work for this frame is completed.

Note that in the presence of timeline semaphores, the last queue submission might not be the last one to be submitted, as timeline semaphores allow for wait-before-signal submissions. In the context of frame boundary, the queue submission that should be done flagged as the last one is the one that is meant to be executed last, even if it may not be the last one to be submitted.

// Provided by VK_EXT_frame_boundary
typedef VkFlags VkFrameBoundaryFlagsEXT;

VkFrameBoundaryFlagsEXT is a bitmask type for setting a mask of zero or more VkFrameBoundaryFlagBitsEXT.