35. 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.

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,
    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000,
    VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000,
    VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
    VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
    VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
    VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
    VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000,
    VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000,
    VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001,
    VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000,
    VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
    VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX = 1000165000,
    VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
    VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
} VkObjectType;
Table 75. 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_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_DEBUG_REPORT_CALLBACK_EXT

VkDebugReportCallbackEXT

VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE

VkDescriptorUpdateTemplate

VK_OBJECT_TYPE_OBJECT_TABLE_NVX

VkObjectTableNVX

VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX

VkIndirectCommandsLayoutNVX

VK_OBJECT_TYPE_VALIDATION_CACHE_EXT

VkValidationCacheEXT

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

35.1. Debug Utilities

Vulkan provides flexible debugging utilities for debugging an application.

The Object Debug Annotation section describes how to associate either a name or binary data with a specific Vulkan object.

The Queue Labels section describes how to annotate and group the work submitted to a queue.

The Command Buffer Labels section describes how to associate logical elements of the scene with commands in a VkCommandBuffer.

The Debug Messengers section describes how to create debug messenger objects associated with an application supplied callback to capture debug messages from a variety of Vulkan components.

35.1.1. Object Debug Annotation

It can be useful for an application to provide its own content relative to a specific Vulkan object. The following commands allow application developers to associate user-defined information with Vulkan objects.

Object Naming

An object can be provided a user-defined name by calling vkSetDebugUtilsObjectNameEXT as defined below.

VkResult vkSetDebugUtilsObjectNameEXT(
    VkDevice                                    device,
    const VkDebugUtilsObjectNameInfoEXT*        pNameInfo);
  • device is the device that created the object.

  • pNameInfo is a pointer to an instance of the VkDebugUtilsObjectNameInfoEXT structure specifying the parameters of the name to set on the object.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pNameInfo must be a valid pointer to a valid VkDebugUtilsObjectNameInfoEXT structure

Host Synchronization
  • Host access to pNameInfo.objectHandle must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugUtilsObjectNameInfoEXT structure is defined as:

typedef struct VkDebugUtilsObjectNameInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    VkObjectType       objectType;
    uint64_t           objectHandle;
    const char*        pObjectName;
} VkDebugUtilsObjectNameInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • objectType is a VkObjectType specifying the type of the object to be named.

  • objectHandle is the object to be named.

  • pObjectName is a null-terminated UTF-8 string specifying the name to apply to objectHandle.

Applications may change the name associated with an object simply by calling vkSetDebugUtilsObjectNameEXT again with a new string. If pObjectName is an empty string, then any previously set name is removed.

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT

  • pNext must be NULL

  • objectType must be a valid VkObjectType value

  • If pObjectName is not NULL, pObjectName must be a null-terminated UTF-8 string

Object Data Association

In addition to setting a name for an object, debugging and validation layers may have uses for additional binary data on a per-object basis that have no other place in the Vulkan API.

For example, a VkShaderModule could have additional debugging data attached to it to aid in offline shader tracing.

Additional data can be attached to an object by calling vkSetDebugUtilsObjectTagEXT as defined below.

VkResult vkSetDebugUtilsObjectTagEXT(
    VkDevice                                    device,
    const VkDebugUtilsObjectTagInfoEXT*         pTagInfo);
  • device is the device that created the object.

  • pTagInfo is a pointer to an instance of the VkDebugUtilsObjectTagInfoEXT structure specifying the parameters of the tag to attach to the object.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pTagInfo must be a valid pointer to a valid VkDebugUtilsObjectTagInfoEXT structure

Host Synchronization
  • Host access to pTagInfo.objectHandle must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugUtilsObjectTagInfoEXT structure is defined as:

typedef struct VkDebugUtilsObjectTagInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    VkObjectType       objectType;
    uint64_t           objectHandle;
    uint64_t           tagName;
    size_t             tagSize;
    const void*        pTag;
} VkDebugUtilsObjectTagInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • objectType is a VkObjectType specifying the type of the object to be named.

  • objectHandle is the object to be tagged.

  • tagName is a numerical identifier of the tag.

  • tagSize is the number of bytes of data to attach to the object.

  • pTag is an array of tagSize bytes containing the data to be associated with the object.

The tagName parameter gives a name or identifier to the type of data being tagged. This can be used by debugging layers to easily filter for only data that can be used by that implementation.

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT

  • pNext must be NULL

  • objectType must be a valid VkObjectType value

  • pTag must be a valid pointer to an array of tagSize bytes

  • tagSize must be greater than 0

35.1.2. Queue Labels

All Vulkan work must be submitted using queues. It is possible for an application to use multiple queues, each containing multiple command buffers, when performing work. It can be useful to identify which queue, or even where in a queue, something has occurred.

To begin identifying a region using a debug label inside a queue, you may use the vkQueueBeginDebugUtilsLabelEXT command.

Then, when the region of interest has passed, you may end the label region using vkQueueEndDebugUtilsLabelEXT.

Additionally, a single debug label may be inserted at any time using vkQueueInsertDebugUtilsLabelEXT.

A queue debug label region is opened by calling:

void vkQueueBeginDebugUtilsLabelEXT(
    VkQueue                                     queue,
    const VkDebugUtilsLabelEXT*                 pLabelInfo);
  • queue is the queue in which to start a debug label region.

  • pLabelInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the parameters of the label region to open.

Valid Usage (Implicit)
  • queue must be a valid VkQueue handle

  • pLabelInfo must be a valid pointer to a valid VkDebugUtilsLabelEXT structure

The VkDebugUtilsLabelEXT structure is defined as:

typedef struct VkDebugUtilsLabelEXT {
    VkStructureType    sType;
    const void*        pNext;
    const char*        pLabelName;
    float              color[4];
} VkDebugUtilsLabelEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • pLabelName is a pointer to a null-terminated UTF-8 string that contains the name of the label.

  • color is an optional RGBA color value that can be associated with the label. A particular implementation may choose to ignore this color value. The values contain RGBA values in order, in the range 0.0 to 1.0. If all elements in color are set to 0.0 then it is ignored.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT

  • pNext must be NULL

  • pLabelName must be a null-terminated UTF-8 string

A queue debug label region is closed by calling:

void vkQueueEndDebugUtilsLabelEXT(
    VkQueue                                     queue);
  • queue is the queue in which a debug label region should be closed.

The calls to vkQueueBeginDebugUtilsLabelEXT and vkQueueEndDebugUtilsLabelEXT must be matched and balanced.

Valid Usage
  • There must be an outstanding vkQueueBeginDebugUtilsLabelEXT command prior to the vkQueueEndDebugUtilsLabelEXT on the queue

Valid Usage (Implicit)
  • queue must be a valid VkQueue handle

A single label can be inserted into a queue by calling:

void vkQueueInsertDebugUtilsLabelEXT(
    VkQueue                                     queue,
    const VkDebugUtilsLabelEXT*                 pLabelInfo);
  • queue is the queue into which a debug label will be inserted.

  • pLabelInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the parameters of the label to insert.

Valid Usage (Implicit)
  • queue must be a valid VkQueue handle

  • pLabelInfo must be a valid pointer to a valid VkDebugUtilsLabelEXT structure

35.1.3. Command Buffer Labels

Typical Vulkan applications will submit many command buffers in each frame, with each command buffer containing a large number of individual commands. Being able to logically annotate regions of command buffers that belong together as well as hierarchically subdivide the frame is important to a developer’s ability to navigate the commands viewed holistically.

To identify the beginning of a debug label region in a command buffer, vkCmdBeginDebugUtilsLabelEXT can be used as defined below.

To indicate the end of a debug label region in a command buffer, vkCmdEndDebugUtilsLabelEXT can be used.

To insert a single command buffer debug label inside of a command buffer, vkCmdInsertDebugUtilsLabelEXT can be used as defined below.

A command buffer debug label region can be opened by calling:

void vkCmdBeginDebugUtilsLabelEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugUtilsLabelEXT*                 pLabelInfo);
  • commandBuffer is the command buffer into which the command is recorded.

  • pLabelInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the parameters of the label region to open.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pLabelInfo must be a valid pointer to a valid VkDebugUtilsLabelEXT structure

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics
Compute

A command buffer label region can be closed by calling:

void vkCmdEndDebugUtilsLabelEXT(
    VkCommandBuffer                             commandBuffer);
  • commandBuffer is the command buffer into which the command is recorded.

An application may open a debug label region in one command buffer and close it in another, or otherwise split debug label regions across multiple command buffers or multiple queue submissions. When viewed from the linear series of submissions to a single queue, the calls to vkCmdBeginDebugUtilsLabelEXT and vkCmdEndDebugUtilsLabelEXT must be matched and balanced.

Valid Usage
  • There must be an outstanding vkCmdBeginDebugUtilsLabelEXT command prior to the vkCmdEndDebugUtilsLabelEXT on the queue that commandBuffer is submitted to

  • If commandBuffer is a secondary command buffer, there must be an outstanding vkCmdBeginDebugUtilsLabelEXT command recorded to commandBuffer that has not previously been ended by a call to vkCmdEndDebugUtilsLabelEXT.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics
Compute

A single debug label can be inserted into a command buffer by calling:

void vkCmdInsertDebugUtilsLabelEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugUtilsLabelEXT*                 pLabelInfo);
  • commandBuffer is the command buffer into which the command is recorded.

  • pInfo is a pointer to an instance of the VkDebugUtilsLabelEXT structure specifying the parameters of the label to insert.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pLabelInfo must be a valid pointer to a valid VkDebugUtilsLabelEXT structure

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics
Compute

35.1.4. Debug Messengers

Vulkan allows an application to register multiple callbacks with any Vulkan component wishing to report debug information. Some callbacks may log the information to a file, others may cause a debug break point or other application defined behavior. A primary producer of callback messages are the validation layers. An application can register callbacks even when no validation layers are enabled, but they will only be called for the Vulkan loader and, if implemented, other layer and driver events.

A VkDebugUtilsMessengerEXT is a messenger object which handles passing along debug messages to a provided debug callback.

VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT)

The debug messenger will provide detailed feedback on the application’s use of Vulkan when events of interest occur. When an event of interest does occur, the debug messenger will submit a debug message to the debug callback that was provided during its creation. Additionally, the debug messenger is responsible with filtering out debug messages that the callback is not interested in and will only provide desired debug messages.

A debug messenger triggers a debug callback with a debug message when an event of interest occurs. To create a debug messenger which will trigger a debug callback, call:

VkResult vkCreateDebugUtilsMessengerEXT(
    VkInstance                                  instance,
    const VkDebugUtilsMessengerCreateInfoEXT*   pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkDebugUtilsMessengerEXT*                   pMessenger);
  • instance the instance the messenger will be used with.

  • pCreateInfo points to a VkDebugUtilsMessengerCreateInfoEXT structure which contains the callback pointer as well as defines the conditions under which this messenger will trigger the callback.

  • pAllocator controls host memory allocation as described in the Memory Allocation chapter.

  • pMessenger is a pointer to record the VkDebugUtilsMessengerEXT object created.

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • pCreateInfo must be a valid pointer to a valid VkDebugUtilsMessengerCreateInfoEXT structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • pMessenger must be a valid pointer to a VkDebugUtilsMessengerEXT handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

The definition of VkDebugUtilsMessengerCreateInfoEXT is:

typedef struct VkDebugUtilsMessengerCreateInfoEXT {
    VkStructureType                         sType;
    const void*                             pNext;
    VkDebugUtilsMessengerCreateFlagsEXT     flags;
    VkDebugUtilsMessageSeverityFlagsEXT     messageSeverity;
    VkDebugUtilsMessageTypeFlagsEXT         messageType;
    PFN_vkDebugUtilsMessengerCallbackEXT    pfnUserCallback;
    void*                                   pUserData;
} VkDebugUtilsMessengerCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • flags is 0 and reserved for future use.

  • messageSeverity is a bitmask of VkDebugUtilsMessageSeverityFlagBitsEXT specifying which severity of event(s) will cause this callback to be called.

  • messageTypes is a bitmask of VkDebugUtilsMessageTypeFlagBitsEXT specifying which type of event(s) will cause this callback to be called.

  • pfnUserCallback is the application callback function to call.

  • pUserData is user data to be passed to the callback.

For each VkDebugUtilsMessengerEXT that is created the VkDebugUtilsMessengerCreateInfoEXT::messageSeverity and VkDebugUtilsMessengerCreateInfoEXT::messageTypes determine when that VkDebugUtilsMessengerCreateInfoEXT::pfnUserCallback is called. The process to determine if the user’s pfnUserCallback is triggered when an event occurs is as follows:

  1. The implementation will perform a bitwise AND of the event’s VkDebugUtilsMessageSeverityFlagBitsEXT with the messageSeverity provided during creation of the VkDebugUtilsMessengerEXT object.

    1. If the value is 0, the message is skipped.

  2. The implementation will perform bitwise AND of the event’s VkDebugUtilsMessageTypeFlagBitsEXT with the messageType provided during the creation of the VkDebugUtilsMessengerEXT object.

    1. If the value is 0, the message is skipped.

  3. The callback will trigger a debug message for the current event

The callback will come directly from the component that detected the event, unless some other layer intercepts the calls for its own purposes (filter them in a different way, log to a system error log, etc.).

An application can receive multiple callbacks if multiple VkDebugUtilsMessengerEXT objects are created. A callback will always be executed in the same thread as the originating Vulkan call.

A callback can be called from multiple threads simultaneously (if the application is making Vulkan calls from multiple threads).

Valid Usage
Valid Usage (Implicit)

Bits which can be set in VkDebugUtilsMessengerCreateInfoEXT::messageSeverity, specifying event severities which cause a debug messenger to call the callback, are:

typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT {
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001,
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010,
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100,
    VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000,
} VkDebugUtilsMessageSeverityFlagBitsEXT;
  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT specifies the most verbose output indicating all diagnostic messages from the Vulkan loader, layers, and drivers should be captured.

  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT specifies an informational message such as resource details that may be handy when debugging an application.

  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT specifies use of Vulkan that may expose an app bug. Such cases may not be immediately harmful, such as a fragment shader outputting to a location with no attachment. Other cases may point to behavior that is almost certainly bad when unintended such as using an image whose memory has not been filled. In general if you see a warning but you know that the behavior is intended/desired, then simply ignore the warning.

  • VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT specifies that an error that may cause undefined results, including an application crash.

Note

The values of VkDebugUtilsMessageSeverityFlagBitsEXT are sorted based on severity. The higher the flag value, the more severe the message. This allows for simple boolean operation comparisons when looking at VkDebugUtilsMessageSeverityFlagBitsEXT values.

For example:

    if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
        // Do something for warnings and errors
    }

In addition, space has been left between the enums to allow for later addition of new severities in between the existing values.

Bits which can be set in VkDebugUtilsMessengerCreateInfoEXT::messageTypes, specifying event types which cause a debug messenger to call the callback, are:

typedef enum VkDebugUtilsMessageTypeFlagBitsEXT {
    VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001,
    VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002,
    VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004,
} VkDebugUtilsMessageTypeFlagBitsEXT;
  • VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT specifies that some general event has occurred. This is typically a non-specification, non-performance event.

  • VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT specifies that something has occurred during validation against the Vulkan specification that may indicate invalid behavior.

  • VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT specifies a potentially non-optimal use of Vulkan, e.g. using vkCmdClearColorImage when setting VkAttachmentDescription::loadOp to VK_ATTACHMENT_LOAD_OP_CLEAR would have worked.

The prototype for the VkDebugUtilsMessengerCreateInfoEXT::pfnUserCallback function implemented by the application is:

typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)(
    VkDebugUtilsMessageSeverityFlagBitsEXT           messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT                  messageType,
    const VkDebugUtilsMessengerCallbackDataEXT*      pCallbackData,
    void*                                            pUserData);

The callback must not call vkDestroyDebugUtilsMessengerEXT.

The callback returns a VkBool32, which is interpreted in a layer-specified manner. The application should always return VK_FALSE. The VK_TRUE value is reserved for use in layer development.

The definition of VkDebugUtilsMessengerCallbackDataEXT is:

typedef struct VkDebugUtilsMessengerCallbackDataEXT {
    VkStructureType                              sType;
    const void*                                  pNext;
    VkDebugUtilsMessengerCallbackDataFlagsEXT    flags;
    const char*                                  pMessageIdName;
    int32_t                                      messageIdNumber;
    const char*                                  pMessage;
    uint32_t                                     queueLabelCount;
    VkDebugUtilsLabelEXT*                        pQueueLabels;
    uint32_t                                     cmdBufLabelCount;
    VkDebugUtilsLabelEXT*                        pCmdBufLabels;
    uint32_t                                     objectCount;
    VkDebugUtilsObjectNameInfoEXT*               pObjects;
} VkDebugUtilsMessengerCallbackDataEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • flags is 0 and reserved for future use.

  • pMessageIdName is a null-terminated string that identifies the particular message ID that is associated with the provided message. If the message corresponds to a validation layer message, then this string may contain the portion of the Vulkan specification that is believed to have been violated.

  • messageIdNumber is the ID number of the triggering message. If the message corresponds to a validation layer message, then this number is related to the internal number associated with the message being triggered.

  • pMessage is a null-terminated string detailing the trigger conditions.

  • queueLabelCount is a count of items contained in the pQueueLabels array.

  • pQueueLabels is NULL or a pointer to an array of VkDebugUtilsLabelEXT active in the current VkQueue at the time the callback was triggered. Refer to Queue Labels for more information.

  • cmdBufLabelCount is a count of items contained in the pCmdBufLabels array.

  • pCmdBufLabels is NULL or a pointer to an array of VkDebugUtilsLabelEXT active in the current VkCommandBuffer at the time the callback was triggered. Refer to Command Buffer Labels for more information.

  • objectCount is a count of items contained in the pObjects array.

  • pObjects is a pointer to an array of VkDebugUtilsObjectNameInfoEXT objects related to the detected issue. The array is roughly in order or importance, but the 0th element is always guaranteed to be the most important object for this message.

Note

This structure should only be considered valid during the lifetime of the triggered callback.

Since adding queue and command buffer labels behaves like pushing and popping onto a stack, the order of both pQueueLabels and pCmdBufLabels is based on the order the labels were defined. The result is that the first label in either pQueueLabels or pCmdBufLabels will be the first defined (and therefore the oldest) while the last label in each list will be the most recent.

Note

pQueueLabels will only be non-NULL if one of the objects in pObjects can be related directly to a defined VkQueue which has had one or more labels associated with it.

Likewise, pCmdBufLabels will only be non-NULL if one of the objects in pObjects can be related directly to a defined VkCommandBuffer which has had one or more labels associated with it. Additionally, while command buffer labels allow for beginning and ending across different command buffers, the debug messaging framework cannot guarantee that labels in pCmdBufLables will contain those defined outside of the associated command buffer. This is partially due to the fact that the association of one command buffer with another may not have been defined at the time the debug message is triggered.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT

  • pNext must be NULL

  • flags must be 0

  • If pMessageIdName is not NULL, pMessageIdName must be a null-terminated UTF-8 string

  • pMessage must be a null-terminated UTF-8 string

  • objectCount must be greater than 0

There may be times that a user wishes to intentionally submit a debug message. To do this, call:

void vkSubmitDebugUtilsMessageEXT(
    VkInstance                                  instance,
    VkDebugUtilsMessageSeverityFlagBitsEXT      messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT             messageTypes,
    const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData);

The call will propagate through the layers and generate callback(s) as indicated by the message’s flags. The parameters are passed on to the callback in addition to the pUserData value that was defined at the time the messenger was registered.

Valid Usage (Implicit)

To destroy a VkDebugUtilsMessengerEXT object, call:

void vkDestroyDebugUtilsMessengerEXT(
    VkInstance                                  instance,
    VkDebugUtilsMessengerEXT                    messenger,
    const VkAllocationCallbacks*                pAllocator);
  • instance the instance where the callback was created.

  • messenger the VkDebugUtilsMessengerEXT object to destroy. messenger is an externally synchronized object and must not be used on more than one thread at a time. This means that vkDestroyDebugUtilsMessengerEXT must not be called when a callback is active.

  • pAllocator controls host memory allocation as described in the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when messenger was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when messenger was created, pAllocator must be NULL

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • messenger must be a valid VkDebugUtilsMessengerEXT handle

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • messenger must have been created, allocated, or retrieved from instance

Host Synchronization
  • Host access to messenger must be externally synchronized

35.2. Debug Markers

Debug markers provide a flexible way for debugging and validation layers to receive annotation and debug information.

The Object Annotation section describes how to associate a name or binary data with a Vulkan object.

The Command Buffer Markers section describes how to associate logical elements of the scene with commands in the command buffer.

35.2.1. Object Annotation

The commands in this section allow application developers to associate user-defined information with Vulkan objects at will.

An object can be given a user-friendly name by calling:

VkResult vkDebugMarkerSetObjectNameEXT(
    VkDevice                                    device,
    const VkDebugMarkerObjectNameInfoEXT*       pNameInfo);
  • device is the device that created the object.

  • pNameInfo is a pointer to an instance of the VkDebugMarkerObjectNameInfoEXT structure specifying the parameters of the name to set on the object.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pNameInfo must be a valid pointer to a valid VkDebugMarkerObjectNameInfoEXT structure

Host Synchronization
  • Host access to pNameInfo.object must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugMarkerObjectNameInfoEXT structure is defined as:

typedef struct VkDebugMarkerObjectNameInfoEXT {
    VkStructureType               sType;
    const void*                   pNext;
    VkDebugReportObjectTypeEXT    objectType;
    uint64_t                      object;
    const char*                   pObjectName;
} VkDebugMarkerObjectNameInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • objectType is a VkDebugReportObjectTypeEXT specifying the type of the object to be named.

  • object is the object to be named.

  • pObjectName is a null-terminated UTF-8 string specifying the name to apply to object.

Applications may change the name associated with an object simply by calling vkDebugMarkerSetObjectNameEXT again with a new string. To remove a previously set name, pObjectName should be set to an empty string.

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT

  • pNext must be NULL

  • objectType must be a valid VkDebugReportObjectTypeEXT value

  • pObjectName must be a null-terminated UTF-8 string

In addition to setting a name for an object, debugging and validation layers may have uses for additional binary data on a per-object basis that has no other place in the Vulkan API. For example, a VkShaderModule could have additional debugging data attached to it to aid in offline shader tracing. To attach data to an object, call:

VkResult vkDebugMarkerSetObjectTagEXT(
    VkDevice                                    device,
    const VkDebugMarkerObjectTagInfoEXT*        pTagInfo);
  • device is the device that created the object.

  • pTagInfo is a pointer to an instance of the VkDebugMarkerObjectTagInfoEXT structure specifying the parameters of the tag to attach to the object.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pTagInfo must be a valid pointer to a valid VkDebugMarkerObjectTagInfoEXT structure

Host Synchronization
  • Host access to pTagInfo.object must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

The VkDebugMarkerObjectTagInfoEXT structure is defined as:

typedef struct VkDebugMarkerObjectTagInfoEXT {
    VkStructureType               sType;
    const void*                   pNext;
    VkDebugReportObjectTypeEXT    objectType;
    uint64_t                      object;
    uint64_t                      tagName;
    size_t                        tagSize;
    const void*                   pTag;
} VkDebugMarkerObjectTagInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • objectType is a VkDebugReportObjectTypeEXT specifying the type of the object to be named.

  • object is the object to be tagged.

  • tagName is a numerical identifier of the tag.

  • tagSize is the number of bytes of data to attach to the object.

  • pTag is an array of tagSize bytes containing the data to be associated with the object.

The tagName parameter gives a name or identifier to the type of data being tagged. This can be used by debugging layers to easily filter for only data that can be used by that implementation.

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT

  • pNext must be NULL

  • objectType must be a valid VkDebugReportObjectTypeEXT value

  • pTag must be a valid pointer to an array of tagSize bytes

  • tagSize must be greater than 0

35.2.2. Command Buffer Markers

Typical Vulkan applications will submit many command buffers in each frame, with each command buffer containing a large number of individual commands. Being able to logically annotate regions of command buffers that belong together as well as hierarchically subdivide the frame is important to a developer’s ability to navigate the commands viewed holistically.

The marker commands vkCmdDebugMarkerBeginEXT and vkCmdDebugMarkerEndEXT define regions of a series of commands that are grouped together, and they can be nested to create a hierarchy. The vkCmdDebugMarkerInsertEXT command allows insertion of a single label within a command buffer.

A marker region can be opened by calling:

void vkCmdDebugMarkerBeginEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugMarkerMarkerInfoEXT*           pMarkerInfo);
  • commandBuffer is the command buffer into which the command is recorded.

  • pMarkerInfo is a pointer to an instance of the VkDebugMarkerMarkerInfoEXT structure specifying the parameters of the marker region to open.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pMarkerInfo must be a valid pointer to a valid VkDebugMarkerMarkerInfoEXT structure

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics
Compute

The VkDebugMarkerMarkerInfoEXT structure is defined as:

typedef struct VkDebugMarkerMarkerInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    const char*        pMarkerName;
    float              color[4];
} VkDebugMarkerMarkerInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • pMarkerName is a pointer to a null-terminated UTF-8 string that contains the name of the marker.

  • color is an optional RGBA color value that can be associated with the marker. A particular implementation may choose to ignore this color value. The values contain RGBA values in order, in the range 0.0 to 1.0. If all elements in color are set to 0.0 then it is ignored.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT

  • pNext must be NULL

  • pMarkerName must be a null-terminated UTF-8 string

A marker region can be closed by calling:

void vkCmdDebugMarkerEndEXT(
    VkCommandBuffer                             commandBuffer);
  • commandBuffer is the command buffer into which the command is recorded.

An application may open a marker region in one command buffer and close it in another, or otherwise split marker regions across multiple command buffers or multiple queue submissions. When viewed from the linear series of submissions to a single queue, the calls to vkCmdDebugMarkerBeginEXT and vkCmdDebugMarkerEndEXT must be matched and balanced.

Valid Usage
  • There must be an outstanding vkCmdDebugMarkerBeginEXT command prior to the vkCmdDebugMarkerEndEXT on the queue that commandBuffer is submitted to

  • If commandBuffer is a secondary command buffer, there must be an outstanding vkCmdDebugMarkerBeginEXT command recorded to commandBuffer that has not previously been ended by a call to vkCmdDebugMarkerEndEXT.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics
Compute

A single marker label can be inserted into a command buffer by calling:

void vkCmdDebugMarkerInsertEXT(
    VkCommandBuffer                             commandBuffer,
    const VkDebugMarkerMarkerInfoEXT*           pMarkerInfo);
  • commandBuffer is the command buffer into which the command is recorded.

  • pMarkerInfo is a pointer to an instance of the VkDebugMarkerMarkerInfoEXT structure specifying the parameters of the marker to insert.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pMarkerInfo must be a valid pointer to a valid VkDebugMarkerMarkerInfoEXT structure

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics
Compute

35.3. Debug Report Callbacks

Debug report callbacks are represented by VkDebugReportCallbackEXT handles:

VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)

Debug report callbacks give more detailed feedback on the application’s use of Vulkan when events of interest occur.

To register a debug report callback, an application uses vkCreateDebugReportCallbackEXT.

VkResult vkCreateDebugReportCallbackEXT(
    VkInstance                                  instance,
    const VkDebugReportCallbackCreateInfoEXT*   pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkDebugReportCallbackEXT*                   pCallback);
  • instance the instance the callback will be logged on.

  • pCreateInfo points to a VkDebugReportCallbackCreateInfoEXT structure which defines the conditions under which this callback will be called.

  • pAllocator controls host memory allocation as described in the Memory Allocation chapter.

  • pCallback is a pointer to record the VkDebugReportCallbackEXT object created.

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • pCreateInfo must be a valid pointer to a valid VkDebugReportCallbackCreateInfoEXT structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • pCallback must be a valid pointer to a VkDebugReportCallbackEXT handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

The definition of VkDebugReportCallbackCreateInfoEXT is:

typedef struct VkDebugReportCallbackCreateInfoEXT {
    VkStructureType                 sType;
    const void*                     pNext;
    VkDebugReportFlagsEXT           flags;
    PFN_vkDebugReportCallbackEXT    pfnCallback;
    void*                           pUserData;
} VkDebugReportCallbackCreateInfoEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • flags is a bitmask of VkDebugReportFlagBitsEXT specifying which event(s) will cause this callback to be called.

  • pfnCallback is the application callback function to call.

  • pUserData is user data to be passed to the callback.

For each VkDebugReportCallbackEXT that is created the VkDebugReportCallbackCreateInfoEXT::flags determine when that VkDebugReportCallbackCreateInfoEXT::pfnCallback is called. When an event happens, the implementation will do a bitwise AND of the event’s VkDebugReportFlagBitsEXT flags to each VkDebugReportCallbackEXT object’s flags. For each non-zero result the corresponding callback will be called. The callback will come directly from the component that detected the event, unless some other layer intercepts the calls for its own purposes (filter them in a different way, log to a system error log, etc.).

An application may receive multiple callbacks if multiple VkDebugReportCallbackEXT objects were created. A callback will always be executed in the same thread as the originating Vulkan call.

A callback may be called from multiple threads simultaneously (if the application is making Vulkan calls from multiple threads).

Valid Usage
Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT

  • flags must be a valid combination of VkDebugReportFlagBitsEXT values

Bits which can be set in VkDebugReportCallbackCreateInfoEXT::flags, specifying events which cause a debug report, are:

typedef enum VkDebugReportFlagBitsEXT {
    VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001,
    VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002,
    VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004,
    VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008,
    VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010,
} VkDebugReportFlagBitsEXT;
  • VK_DEBUG_REPORT_ERROR_BIT_EXT specifies that an error that may cause undefined results, including an application crash.

  • VK_DEBUG_REPORT_WARNING_BIT_EXT specifies use of Vulkan that may expose an app bug. Such cases may not be immediately harmful, such as a fragment shader outputting to a location with no attachment. Other cases may point to behavior that is almost certainly bad when unintended such as using an image whose memory has not been filled. In general if you see a warning but you know that the behavior is intended/desired, then simply ignore the warning.

  • VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT specifies a potentially non-optimal use of Vulkan, e.g. using vkCmdClearColorImage when setting VkAttachmentDescription::loadOp to VK_ATTACHMENT_LOAD_OP_CLEAR would have worked.

  • VK_DEBUG_REPORT_INFORMATION_BIT_EXT specifies an informational message such as resource details that may be handy when debugging an application.

  • VK_DEBUG_REPORT_DEBUG_BIT_EXT specifies diagnostic information from the implementation and layers.

typedef VkFlags VkDebugReportFlagsEXT;

VkDebugReportFlagsEXT is a bitmask type for setting a mask of zero or more VkDebugReportFlagBitsEXT.

The prototype for the VkDebugReportCallbackCreateInfoEXT::pfnCallback function implemented by the application is:

typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)(
    VkDebugReportFlagsEXT                       flags,
    VkDebugReportObjectTypeEXT                  objectType,
    uint64_t                                    object,
    size_t                                      location,
    int32_t                                     messageCode,
    const char*                                 pLayerPrefix,
    const char*                                 pMessage,
    void*                                       pUserData);
  • flags specifies the VkDebugReportFlagBitsEXT that triggered this callback.

  • objectType is a VkDebugReportObjectTypeEXT value specifying the type of object being used or created at the time the event was triggered.

  • object is the object where the issue was detected. If objectType is VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, object is undefined.

  • location is a component (layer, driver, loader) defined value that specifies the location of the trigger. This is an optional value.

  • messageCode is a layer-defined value indicating what test triggered this callback.

  • pLayerPrefix is a null-terminated string that is an abbreviation of the name of the component making the callback. pLayerPrefix is only valid for the duration of the callback.

  • pMessage is a null-terminated string detailing the trigger conditions. pMessage is only valid for the duration of the callback.

  • pUserData is the user data given when the VkDebugReportCallbackEXT was created.

The callback must not call vkDestroyDebugReportCallbackEXT.

The callback returns a VkBool32, which is interpreted in a layer-specified manner. The application should always return VK_FALSE. The VK_TRUE value is reserved for use in layer development.

object must be a Vulkan object or VK_NULL_HANDLE. If objectType is not VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT and object is not VK_NULL_HANDLE, object must be a Vulkan object of the corresponding type associated with objectType as defined in VkDebugReportObjectTypeEXT and Vulkan Handle Relationship.

Possible values passed to the objectType parameter of the callback function specified by VkDebugReportCallbackCreateInfoEXT::pfnCallback, specifying the type of object handle being reported, are:

typedef enum VkDebugReportObjectTypeEXT {
    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0,
    VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1,
    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2,
    VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3,
    VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4,
    VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5,
    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6,
    VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7,
    VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8,
    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9,
    VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10,
    VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11,
    VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12,
    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13,
    VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14,
    VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15,
    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16,
    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17,
    VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18,
    VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20,
    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23,
    VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24,
    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25,
    VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26,
    VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27,
    VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28,
    VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29,
    VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30,
    VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31,
    VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32,
    VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33,
    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000,
    VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX_EXT = 1000165000,
    VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,
    VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,
    VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT,
} VkDebugReportObjectTypeEXT;
Table 76. VkDebugReportObjectTypeEXT and Vulkan Handle Relationship
VkDebugReportObjectTypeEXT Vulkan Handle Type

VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT

Unknown/Undefined Handle

VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT

VkInstance

VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT

VkPhysicalDevice

VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT

VkDevice

VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT

VkQueue

VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT

VkSemaphore

VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT

VkCommandBuffer

VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT

VkFence

VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT

VkDeviceMemory

VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT

VkBuffer

VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT

VkImage

VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT

VkEvent

VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT

VkQueryPool

VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT

VkBufferView

VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT

VkImageView

VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT

VkShaderModule

VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT

VkPipelineCache

VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT

VkPipelineLayout

VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT

VkRenderPass

VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT

VkPipeline

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT

VkDescriptorSetLayout

VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT

VkSampler

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT

VkDescriptorPool

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT

VkDescriptorSet

VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT

VkFramebuffer

VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT

VkCommandPool

VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT

VkSurfaceKHR

VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT

VkSwapchainKHR

VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT

VkDebugReportCallbackEXT

VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT

VkDisplayKHR

VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT

VkDisplayModeKHR

VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT

VkObjectTableNVX

VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT

VkIndirectCommandsLayoutNVX

VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT

VkDescriptorUpdateTemplate

Note

The primary expected use of VK_ERROR_VALIDATION_FAILED_EXT is for validation layer testing. It is not expected that an application would see this error code during normal use of the validation layers.

To inject its own messages into the debug stream, call:

void vkDebugReportMessageEXT(
    VkInstance                                  instance,
    VkDebugReportFlagsEXT                       flags,
    VkDebugReportObjectTypeEXT                  objectType,
    uint64_t                                    object,
    size_t                                      location,
    int32_t                                     messageCode,
    const char*                                 pLayerPrefix,
    const char*                                 pMessage);
  • instance is the debug stream’s VkInstance.

  • flags specifies the VkDebugReportFlagBitsEXT classification of this event/message.

  • objectType is a VkDebugReportObjectTypeEXT specifying the type of object being used or created at the time the event was triggered.

  • object this is the object where the issue was detected. object can be VK_NULL_HANDLE if there is no object associated with the event.

  • location is an application defined value.

  • messageCode is an application defined value.

  • pLayerPrefix is the abbreviation of the component making this event/message.

  • pMessage is a null-terminated string detailing the trigger conditions.

The call will propagate through the layers and generate callback(s) as indicated by the message’s flags. The parameters are passed on to the callback in addition to the pUserData value that was defined at the time the callback was registered.

Valid Usage
  • object must be a Vulkan object or VK_NULL_HANDLE

  • If objectType is not VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT and object is not VK_NULL_HANDLE, object must be a Vulkan object of the corresponding type associated with objectType as defined in VkDebugReportObjectTypeEXT and Vulkan Handle Relationship.

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • flags must be a valid combination of VkDebugReportFlagBitsEXT values

  • flags must not be 0

  • objectType must be a valid VkDebugReportObjectTypeEXT value

  • pLayerPrefix must be a null-terminated UTF-8 string

  • pMessage must be a null-terminated UTF-8 string

To destroy a VkDebugReportCallbackEXT object, call:

void vkDestroyDebugReportCallbackEXT(
    VkInstance                                  instance,
    VkDebugReportCallbackEXT                    callback,
    const VkAllocationCallbacks*                pAllocator);
  • instance the instance where the callback was created.

  • callback the VkDebugReportCallbackEXT object to destroy. callback is an externally synchronized object and must not be used on more than one thread at a time. This means that vkDestroyDebugReportCallbackEXT must not be called when a callback is active.

  • pAllocator controls host memory allocation as described in the Memory Allocation chapter.

Valid Usage
  • If VkAllocationCallbacks were provided when callback was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when callback was created, pAllocator must be NULL

Valid Usage (Implicit)
  • instance must be a valid VkInstance handle

  • callback must be a valid VkDebugReportCallbackEXT handle

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • callback must have been created, allocated, or retrieved from instance

Host Synchronization
  • Host access to callback must be externally synchronized

35.4. Device Loss Debugging

35.4.1. Device Diagnostic Checkpoints

Device execution progress can be tracked for the purposes of debugging a device loss by annotating the command stream with application-defined diagnostic checkpoints.

Each diagnostic checkpoint command is executed at two pipeline stages: VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, and VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT. If the device is lost, the application can call vkGetQueueCheckpointDataNV to retrieve checkpoint data associated with both pipeline stages, indicating the range of diagnostic checkpoints that are currently in the execution pipeline on the device.

Device diagnostic checkpoints are inserted into the command stream by calling vkCmdSetCheckpointNV.

void vkCmdSetCheckpointNV(
    VkCommandBuffer                             commandBuffer,
    const void*                                 pCheckpointMarker);
  • commandBuffer is the command buffer that will receive the marker

  • pCheckpointMarker is an opaque application-provided value that will be associated with the checkpoint.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support graphics, compute, or transfer operations

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics
Compute
Transfer

Note that pCheckpointMarker is treated as an opaque value. It does not need to be a valid pointer and will not be dereferenced by the implementation.

If the device encounters an error during execution, the implementation will return a VK_ERROR_DEVICE_LOST error to the application at a certain point during host execution. When this happens, the application can call vkGetQueueCheckpointDataNV to retrieve information on the most recent diagnostic checkpoints that were executed by the device.

void vkGetQueueCheckpointDataNV(
    VkQueue                                     queue,
    uint32_t*                                   pCheckpointDataCount,
    VkCheckpointDataNV*                         pCheckpointData);
  • queue is the VkQueue object the caller would like to retrieve checkpoint data for

  • pCheckpointDataCount is a pointer to an integer related to the number of checkpoint markers available or queried, as described below.

  • pCheckpointData is either NULL or a pointer to an array of VkCheckpointDataNV structures.

If pCheckpointData is NULL, then the number of checkpoint markers available is returned in pCheckpointDataCount.

Otherwise, pCheckpointDataCount must point to a variable set by the user to the number of elements in the pCheckpointData array, and on return the variable is overwritten with the number of structures actually written to pCheckpointData.

If pCheckpointDataCount is less than the number of checkpoint markers available, at most pCheckpointDataCount structures will be written.

Valid Usage
  • The device that queue belongs to must be in the lost state

Valid Usage (Implicit)
  • queue must be a valid VkQueue handle

  • pCheckpointDataCount must be a valid pointer to a uint32_t value

  • If the value referenced by pCheckpointDataCount is not 0, and pCheckpointData is not NULL, pCheckpointData must be a valid pointer to an array of pCheckpointDataCount VkCheckpointDataNV structures

The VkCheckpointDataNV structure is defined as:

typedef struct VkCheckpointDataNV {
    VkStructureType            sType;
    void*                      pNext;
    VkPipelineStageFlagBits    stage;
    void*                      pCheckpointMarker;
} VkCheckpointDataNV;
  • sType is the type of this structure

  • pNext is NULL or a pointer to an extension-specific structure.

  • stage indicates which pipeline stage the checkpoint marker data refers to.

  • pCheckpointMarker contains the value of the last checkpoint marker executed in the stage that stage refers to.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV

  • pNext must be NULL

Note that the stages at which a checkpoint marker can be executed are implementation-defined and can be queried by calling vkGetPhysicalDeviceQueueFamilyProperties2.