// Copyright 2017-2021 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

include::{generated}/meta/{refprefix}VK_EXT_debug_utils.txt[]

=== Other Extension Metadata

*Last Modified Date*::
    2020-04-03
*Revision*::
    2
*IP Status*::
    No known IP claims.
*Dependencies*::
  - This extension is written against version 1.0 of the Vulkan API.
  - Requires elink:VkObjectType
*Contributors*::
  - Mark Young, LunarG
  - Baldur Karlsson
  - Ian Elliott, Google
  - Courtney Goeltzenleuchter, Google
  - Karl Schultz, LunarG
  - Mark Lobodzinski, LunarG
  - Mike Schuchardt, LunarG
  - Jaakko Konttinen, AMD
  - Dan Ginsburg, Valve Software
  - Rolando Olivares, Epic Games
  - Dan Baker, Oxide Games
  - Kyle Spagnoli, NVIDIA
  - Jon Ashburn, LunarG
  - Piers Daniell, NVIDIA

=== Description

Due to the nature of the Vulkan interface, there is very little error
information available to the developer and application.
By using the `VK_EXT_debug_utils` extension, developers can: obtain more
information.
When combined with validation layers, even more detailed feedback on the
application's use of Vulkan will be provided.

This extension provides the following capabilities:

  - The ability to create a debug messenger which will pass along debug
    messages to an application supplied callback.
  - The ability to identify specific Vulkan objects using a name or tag to
    improve tracking.
  - The ability to identify specific sections within a sname:VkQueue or
    sname:VkCommandBuffer using labels to aid organization and offline
    analysis in external tools.

The main difference between this extension and `apiext:VK_EXT_debug_report`
and `apiext:VK_EXT_debug_marker` is that those extensions use
elink:VkDebugReportObjectTypeEXT to identify objects.
This extension uses the core elink:VkObjectType in place of
elink:VkDebugReportObjectTypeEXT.
The primary reason for this move is that no future object type handle
enumeration values will be added to elink:VkDebugReportObjectTypeEXT since
the creation of elink:VkObjectType.

In addition, this extension combines the functionality of both
`apiext:VK_EXT_debug_report` and `apiext:VK_EXT_debug_marker` by allowing
object name and debug markers (now called labels) to be returned to the
application's callback function.
This should assist in clarifying the details of a debug message including:
what objects are involved and potentially which location within a
slink:VkQueue or slink:VkCommandBuffer the message occurred.

include::{generated}/interfaces/VK_EXT_debug_utils.txt[]

=== Examples

*Example 1*

`VK_EXT_debug_utils` 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.
An application can: register callbacks even when no validation layers are
enabled, but they will only be called for loader and, if implemented, driver
events.

To capture events that occur while creating or destroying an instance an
application can: link a slink:VkDebugUtilsMessengerCreateInfoEXT structure
to the pname:pNext element of the slink:VkInstanceCreateInfo structure given
to flink:vkCreateInstance.

Example uses: Create three callback objects.
One will log errors and warnings to the debug console using Windows
code:OutputDebugString.
The second will cause the debugger to break at that callback when an error
happens and the third will log warnings to stdout.
[source,c++]
------------------------------------------------------------------------------
    extern VkInstance instance;
    VkResult res;
    VkDebugUtilsMessengerEXT cb1, cb2, cb3;

    // Must call extension functions through a function pointer:
    PFN_vkCreateDebugUtilsMessengerEXT pfnCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
    PFN_vkDestroyDebugUtilsMessengerEXT pfnDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");

    VkDebugUtilsMessengerCreateInfoEXT callback1 = {
            VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,  // sType
            NULL,                                                     // pNext
            0,                                                        // flags
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |           // messageSeverity
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |             // messageType
            VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
            myOutputDebugString,                                      // pfnUserCallback
            NULL                                                      // pUserData
    };
    res = pfnCreateDebugUtilsMessengerEXT(instance, &callback1, NULL, &cb1);
    if (res != VK_SUCCESS) {
       // Do error handling for VK_ERROR_OUT_OF_MEMORY
    }

    callback1.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
    callback1.pfnUserCallback = myDebugBreak;
    callback1.pUserData = NULL;
    res = pfnCreateDebugUtilsMessengerEXT(instance, &callback1, NULL, &cb2);
    if (res != VK_SUCCESS) {
       // Do error handling for VK_ERROR_OUT_OF_MEMORY
    }

    VkDebugUtilsMessengerCreateInfoEXT callback3 = {
            VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,  // sType
            NULL,                                                     // pNext
            0,                                                        // flags
            VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,          // messageSeverity
            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |             // messageType
            VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
            mystdOutLogger,                                           // pfnUserCallback
            NULL                                                      // pUserData
    };
    res = pfnCreateDebugUtilsMessengerEXT(instance, &callback3, NULL, &cb3);
    if (res != VK_SUCCESS) {
       // Do error handling for VK_ERROR_OUT_OF_MEMORY
    }

    ...

    // Remove callbacks when cleaning up
    pfnDestroyDebugUtilsMessengerEXT(instance, cb1, NULL);
    pfnDestroyDebugUtilsMessengerEXT(instance, cb2, NULL);
    pfnDestroyDebugUtilsMessengerEXT(instance, cb3, NULL);
------------------------------------------------------------------------------

*Example 2*

Associate a name with an image, for easier debugging in external tools or
with validation layers that can print a friendly name when referring to
objects in error messages.

[source,c++]
----------------------------------------
    extern VkInstance instance;
    extern VkDevice device;
    extern VkImage image;

    // Must call extension functions through a function pointer:
    PFN_vkSetDebugUtilsObjectNameEXT pfnSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT");

    // Set a name on the image
    const VkDebugUtilsObjectNameInfoEXT imageNameInfo =
    {
        VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, // sType
        NULL,                                               // pNext
        VK_OBJECT_TYPE_IMAGE,                               // objectType
        (uint64_t)image,                                    // objectHandle
        "Brick Diffuse Texture",                            // pObjectName
    };

    pfnSetDebugUtilsObjectNameEXT(device, &imageNameInfo);

    // A subsequent error might print:
    //   Image 'Brick Diffuse Texture' (0xc0dec0dedeadbeef) is used in a
    //   command buffer with no memory bound to it.
----------------------------------------

*Example 3*

Annotating regions of a workload with naming information so that offline
analysis tools can display a more usable visualization of the commands
submitted.

[source,c++]
----------------------------------------
    extern VkInstance instance;
    extern VkCommandBuffer commandBuffer;

    // Must call extension functions through a function pointer:
    PFN_vkQueueBeginDebugUtilsLabelEXT pfnQueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkQueueBeginDebugUtilsLabelEXT");
    PFN_vkQueueEndDebugUtilsLabelEXT pfnQueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkQueueEndDebugUtilsLabelEXT");
    PFN_vkCmdBeginDebugUtilsLabelEXT pfnCmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkCmdBeginDebugUtilsLabelEXT");
    PFN_vkCmdEndDebugUtilsLabelEXT pfnCmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkCmdEndDebugUtilsLabelEXT");
    PFN_vkCmdInsertDebugUtilsLabelEXT pfnCmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance, "vkCmdInsertDebugUtilsLabelEXT");

    // Describe the area being rendered
    const VkDebugUtilsLabelEXT houseLabel =
    {
        VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, // sType
        NULL,                                    // pNext
        "Brick House",                           // pLabelName
        { 1.0f, 0.0f, 0.0f, 1.0f },              // color
    };

    // Start an annotated group of calls under the 'Brick House' name
    pfnCmdBeginDebugUtilsLabelEXT(commandBuffer, &houseLabel);
    {
        // A mutable structure for each part being rendered
        VkDebugUtilsLabelEXT housePartLabel =
        {
            VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, // sType
            NULL,                                    // pNext
            NULL,                                    // pLabelName
            { 0.0f, 0.0f, 0.0f, 0.0f },              // color
        };

        // Set the name and insert the marker
        housePartLabel.pLabelName = "Walls";
        pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel);

        // Insert the drawcall for the walls
        vkCmdDrawIndexed(commandBuffer, 1000, 1, 0, 0, 0);

        // Insert a recursive region for two sets of windows
        housePartLabel.pLabelName = "Windows";
        pfnCmdBeginDebugUtilsLabelEXT(commandBuffer, &housePartLabel);
        {
            vkCmdDrawIndexed(commandBuffer, 75, 6, 1000, 0, 0);
            vkCmdDrawIndexed(commandBuffer, 100, 2, 1450, 0, 0);
        }
        pfnCmdEndDebugUtilsLabelEXT(commandBuffer);

        housePartLabel.pLabelName = "Front Door";
        pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel);

        vkCmdDrawIndexed(commandBuffer, 350, 1, 1650, 0, 0);

        housePartLabel.pLabelName = "Roof";
        pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel);

        vkCmdDrawIndexed(commandBuffer, 500, 1, 2000, 0, 0);
    }
    // End the house annotation started above
    pfnCmdEndDebugUtilsLabelEXT(commandBuffer);

    // Do other work

    vkEndCommandBuffer(commandBuffer);

    // Describe the queue being used
    const VkDebugUtilsLabelEXT queueLabel =
    {
        VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, // sType
        NULL,                                    // pNext
        "Main Render Work",                      // pLabelName
        { 0.0f, 1.0f, 0.0f, 1.0f },              // color
    };

    // Identify the queue label region
    pfnQueueBeginDebugUtilsLabelEXT(queue, &queueLabel);

    // Submit the work for the main render thread
    const VkCommandBuffer cmd_bufs[] = {commandBuffer};
    VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                .pNext = NULL,
                                .waitSemaphoreCount = 0,
                                .pWaitSemaphores = NULL,
                                .pWaitDstStageMask = NULL,
                                .commandBufferCount = 1,
                                .pCommandBuffers = cmd_bufs,
                                .signalSemaphoreCount = 0,
                                .pSignalSemaphores = NULL};
    vkQueueSubmit(queue, 1, &submit_info, fence);

    // End the queue label region
    pfnQueueEndDebugUtilsLabelEXT(queue);

----------------------------------------

=== Issues

1) Should we just name this extension `VK_EXT_debug_report2`

*RESOLVED*: No.
There is enough additional changes to the structures to break backwards
compatibility.
So, a new name was decided that would not indicate any interaction with the
previous extension.

2) Will validation layers immediately support all the new features.

*RESOLVED*: Not immediately.
As one can imagine, there is a lot of work involved with converting the
validation layer logging over to the new functionality.
Basic logging, as seen in the origin `apiext:VK_EXT_debug_report` extension
will be made available immediately.
However, adding the labels and object names will take time.
Since the priority for Khronos at this time is to continue focusing on Valid
Usage statements, it may take a while before the new functionality is fully
exposed.

3) If the validation layers will not expose the new functionality
immediately, then what is the point of this extension?

*RESOLVED*: We needed a replacement for `apiext:VK_EXT_debug_report` because
the elink:VkDebugReportObjectTypeEXT enumeration will no longer be updated
and any new objects will need to be debugged using the new functionality
provided by this extension.

4) Should this extension be split into two separate parts (1 extension that
is an instance extension providing the callback functionality, and another
device extension providing the general debug marker and annotation
functionality)?

*RESOLVED*: No, the functionality for this extension is too closely related.
If we did split up the extension, where would the structures and enums live,
and how would you define that the device behavior in the instance extension
is really only valid if the device extension is enabled, and the
functionality is passed in.
It is cleaner to just define this all as an instance extension, plus it
allows the application to enable all debug functionality provided with one
enable string during flink:vkCreateInstance.

=== Version History

 * Revision 1, 2017-09-14 (Mark Young and all listed Contributors)
 ** Initial draft, based on `apiext:VK_EXT_debug_report` and
    `apiext:VK_EXT_debug_marker` in addition to previous feedback supplied
    from various companies including Valve, Epic, and Oxide games.
 * Revision 2, 2020-04-03 (Mark Young and Piers Daniell)
 ** Updated to allow either `NULL` or an empty string to be passed in for
    pname:pObjectName in sname:VkDebugUtilsObjectNameInfoEXT, because the
    loader and various drivers support `NULL` already.
