1include::meta/VK_EXT_debug_utils.txt[] 2 3*Last Modified Date*:: 4 2017-09-14 5*Revision*:: 6 1 7*IP Status*:: 8 No known IP claims. 9*Dependencies*:: 10 - This extension is written against version 1.0 of the Vulkan API. 11 - Requires elink:VkObjectType 12*Contributors*:: 13 - Mark Young, LunarG 14 - Baldur Karlsson 15 - Ian Elliott, Google 16 - Courtney Goeltzenleuchter, Google 17 - Karl Schultz, LunarG 18 - Mark Lobodzinski, LunarG 19 - Mike Schuchardt, LunarG 20 - Jaakko Konttinen, AMD 21 - Dan Ginsburg, Valve Software 22 - Rolando Olivares, Epic Games 23 - Dan Baker, Oxide Games 24 - Kyle Spagnoli, NVIDIA 25 - Jon Ashburn, LunarG 26 27Due to the nature of the Vulkan interface, there is very little error 28information available to the developer and application. 29By using the `VK_EXT_debug_utils` extension, developers can: obtain more 30information. 31When combined with validation layers, even more detailed feedback on the 32application's use of Vulkan will be provided. 33 34This extension provides the following capabilities: 35 36 - The ability to create a debug messenger which will pass along debug 37 messages to an application supplied callback. 38 - The ability to identify specific Vulkan objects using a name or tag to 39 improve tracking. 40 - The ability to identify specific sections within a sname:VkQueue or 41 sname:VkCommandBuffer using labels to aid organization and offline 42 analysis in external tools. 43 44The main difference between this extension and `<<VK_EXT_debug_report>>` and 45`<<VK_EXT_debug_marker>>` is that those extensions use 46elink:VkDebugReportObjectTypeEXT to identify objects. 47This extension uses the core elink:VkObjectType in place of 48ename:VkDebugReportObjectTypeEXT. 49The primary reason for this move is that no future object type handle 50enumeration values will be added to ename:VkDebugReportObjectTypeEXT since 51the creation of ename:VkObjectType. 52 53In addition, this extension combines the functionality of both 54`<<VK_EXT_debug_report>>` and `<<VK_EXT_debug_marker>>` by allowing object 55name and debug markers (now called labels) to be returned to the 56application's callback function. 57This should assist in clarifying the details of a debug message including: 58what objects are involved and potentially which location within a VkQueue or 59VkCommandBuffer the message occurred. 60 61 62=== New Object Types 63 64 * slink:VkDebugUtilsMessengerEXT 65 66=== New Enum Constants 67 68 * Extending elink:VkStructureType: 69 ** ename:VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT 70 ** ename:VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT 71 ** ename:VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT 72 ** ename:VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT 73 ** ename:VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT 74 * Extending elink:VkResult: 75 ** ename:VK_ERROR_VALIDATION_FAILED_EXT 76 77=== New Enums 78 79 * elink:VkDebugUtilsMessageSeverityFlagBitsEXT 80 * elink:VkDebugUtilsMessageTypeFlagBitsEXT 81 82=== New Structures 83 84 * slink:VkDebugUtilsObjectNameInfoEXT 85 * slink:VkDebugUtilsObjectTagInfoEXT 86 * slink:VkDebugUtilsLabelEXT 87 * slink:VkDebugUtilsMessengerCallbackDataEXT 88 * slink:VkDebugUtilsMessengerCreateInfoEXT 89 90=== New Functions 91 92 * flink:vkSetDebugUtilsObjectNameEXT 93 * flink:vkSetDebugUtilsObjectTagEXT 94 * flink:vkQueueBeginDebugUtilsLabelEXT 95 * flink:vkQueueEndDebugUtilsLabelEXT 96 * flink:vkQueueInsertDebugUtilsLabelEXT 97 * flink:vkCmdBeginDebugUtilsLabelEXT 98 * flink:vkCmdEndDebugUtilsLabelEXT 99 * flink:vkCmdInsertDebugUtilsLabelEXT 100 * flink:vkCreateDebugUtilsMessengerEXT 101 * flink:vkDestroyDebugUtilsMessengerEXT 102 * flink:vkSubmitDebugUtilsMessageEXT 103 104=== New Function Pointers 105 106 * tlink:PFN_vkDebugUtilsMessengerCallbackEXT 107 108=== Examples 109 110**Example 1** 111 112`VK_EXT_debug_utils` allows an application to register multiple callbacks 113with any Vulkan component wishing to report debug information. 114Some callbacks may log the information to a file, others may cause a debug 115break point or other application defined behavior. 116An application can: register callbacks even when no validation layers are 117enabled, but they will only be called for loader and, if implemented, driver 118events. 119 120To capture events that occur while creating or destroying an instance an 121application can: link a slink:VkDebugUtilsMessengerCreateInfoEXT structure 122to the pname:pNext element of the slink:VkInstanceCreateInfo structure given 123to flink:vkCreateInstance. 124This callback is only valid for the duration of the flink:vkCreateInstance 125and the flink:vkDestroyInstance call. 126Use flink:vkCreateDebugUtilsMessengerEXT to create persistent callback 127objects. 128 129Example uses: Create three callback objects. 130One will log errors and warnings to the debug console using Windows 131code:OutputDebugString. 132The second will cause the debugger to break at that callback when an error 133happens and the third will log warnings to stdout. 134[source,c++] 135------------------------------------------------------------------------------ 136 extern VkInstance instance; 137 VkResult res; 138 VkDebugUtilsMessengerEXT cb1, cb2, cb3; 139 140 // Must call extension functions through a function pointer: 141 PFN_vkCreateDebugUtilsMessengerEXT pfnCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetDeviceProcAddr(device, "vkCreateDebugUtilsMessengerEXT"); 142 PFN_vkDestroyDebugUtilsMessengerEXT pfnDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetDeviceProcAddr(device, "vkDestroyDebugUtilsMessengerEXT"); 143 144 VkDebugUtilsMessengeCreateInfoEXT callback1 = { 145 VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, // sType 146 NULL, // pNext 147 0, // flags 148 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | // messageSeverity 149 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, 150 VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | // messageType 151 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, 152 myOutputDebugString, // pfnUserCallback 153 NULL // pUserData 154 }; 155 res = pfnCreateDebugUtilsMessengerEXT(instance, &callback1, &cb1); 156 if (res != VK_SUCCESS) { 157 // Do error handling for VK_ERROR_OUT_OF_MEMORY 158 } 159 160 callback1.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; 161 callback1.pfnCallback = myDebugBreak; 162 callback1.pUserData = NULL; 163 res = pfnCreateDebugUtilsMessengerEXT(instance, &callback1, &cb2); 164 if (res != VK_SUCCESS) { 165 // Do error handling for VK_ERROR_OUT_OF_MEMORY 166 } 167 168 VkDebugUtilsMessengerCreateInfoEXT callback3 = { 169 VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, // sType 170 NULL, // pNext 171 0, // flags 172 VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, // messageSeverity 173 VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | // messageType 174 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, 175 mystdOutLogger, // pfnUserCallback 176 NULL // pUserData 177 }; 178 res = pfnCreateDebugUtilsMessengerEXT(instance, &callback3, &cb3); 179 if (res != VK_SUCCESS) { 180 // Do error handling for VK_ERROR_OUT_OF_MEMORY 181 } 182 183 ... 184 185 // Remove callbacks when cleaning up 186 pfnDestroyDebugUtilsMessengerEXT(instance, cb1); 187 pfnDestroyDebugUtilsMessengerEXT(instance, cb2); 188 pfnDestroyDebugUtilsMessengerEXT(instance, cb3); 189------------------------------------------------------------------------------ 190 191**Example 2** 192 193Associate a name with an image, for easier debugging in external tools or 194with validation layers that can print a friendly name when referring to 195objects in error messages. 196 197[source,c++] 198---------------------------------------- 199 extern VkDevice device; 200 extern VkImage image; 201 202 // Must call extension functions through a function pointer: 203 PFN_vkSetDebugUtilsObjectNameEXT pfnSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr(device, "vkSetDebugUtilsObjectNameEXT"); 204 205 // Set a name on the image 206 const VkDebugUtilsObjectNameInfoEXT imageNameInfo = 207 { 208 VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, // sType 209 NULL, // pNext 210 VK_OBJECT_TYPE_IMAGE, // objectType 211 (uint64_t)image, // object 212 "Brick Diffuse Texture", // pObjectName 213 }; 214 215 pfnSetDebugUtilsObjectNameEXT(device, &imageNameInfo); 216 217 // A subsequent error might print: 218 // Image 'Brick Diffuse Texture' (0xc0dec0dedeadbeef) is used in a 219 // command buffer with no memory bound to it. 220---------------------------------------- 221 222**Example 3** 223 224Annotating regions of a workload with naming information so that offline 225analysis tools can display a more usable visualization of the commands 226submitted. 227 228[source,c++] 229---------------------------------------- 230 extern VkDevice device; 231 extern VkCommandBuffer commandBuffer; 232 233 // Must call extension functions through a function pointer: 234 PFN_vkQueueBeginDebugUtilsLabelEXT pfnQueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkQueueBeginDebugUtilsLabelEXT"); 235 PFN_vkQueueEndDebugUtilsLabelEXT pfnQueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkQueueEndDebugUtilsLabelEXT"); 236 PFN_vkCmdBeginDebugUtilsLabelEXT pfnCmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdBeginDebugUtilsLabelEXT"); 237 PFN_vkCmdEndDebugUtilsLabelEXT pfnCmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdEndDebugUtilsLabelEXT"); 238 PFN_vkCmdInsertDebugUtilsLabelEXT pfnCmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)vkGetDeviceProcAddr(device, "vkCmdInsertDebugUtilsLabelEXT"); 239 240 // Describe the area being rendered 241 const VkDebugUtilsLabelEXT houseLabel = 242 { 243 VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, // sType 244 NULL, // pNext 245 "Brick House", // pLabelName 246 { 1.0f, 0.0f, 0.0f, 1.0f }, // color 247 }; 248 249 // Start an annotated group of calls under the 'Brick House' name 250 pfnCmdBeginDebugUtilsLabelEXT(commandBuffer, &houseLabel); 251 { 252 // A mutable structure for each part being rendered 253 VkDebugUtilsLabelEXT housePartLabel = 254 { 255 VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, // sType 256 NULL, // pNext 257 NULL, // pLabelName 258 { 0.0f, 0.0f, 0.0f, 0.0f }, // color 259 }; 260 261 // Set the name and insert the marker 262 housePartLabel.pLabelName = "Walls"; 263 pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel); 264 265 // Insert the drawcall for the walls 266 vkCmdDrawIndexed(commandBuffer, 1000, 1, 0, 0, 0); 267 268 // Insert a recursive region for two sets of windows 269 housePartLabel.pLabelName = "Windows"; 270 pfnCmdBeginDebugUtilsLabelEXT(commandBuffer, &housePartLabel); 271 { 272 vkCmdDrawIndexed(commandBuffer, 75, 6, 1000, 0, 0); 273 vkCmdDrawIndexed(commandBuffer, 100, 2, 1450, 0, 0); 274 } 275 pfnCmdEndDebugUtilsLabelEXT(commandBuffer); 276 277 housePartLabel.pLabelName = "Front Door"; 278 pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel); 279 280 vkCmdDrawIndexed(commandBuffer, 350, 1, 1650, 0, 0); 281 282 housePartLabel.pLabelName = "Roof"; 283 pfnCmdInsertDebugUtilsLabelEXT(commandBuffer, &housePartLabel); 284 285 vkCmdDrawIndexed(commandBuffer, 500, 1, 2000, 0, 0); 286 } 287 // End the house annotation started above 288 pfnCmdEndDebugUtilsLabelEXT(commandBuffer); 289 290 // Do other work 291 292 vkEndCommandBuffer(commandBuffer); 293 294 // Describe the queue being used 295 const VkDebugUtilsLabelEXT queueLabel = 296 { 297 VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, // sType 298 NULL, // pNext 299 "Main Render Work", // pLabelName 300 { 0.0f, 1.0f, 0.0f, 1.0f }, // color 301 }; 302 303 // Identify the queue label region 304 pfnQueueBeginDebugUtilsLabelEXT(queue, &queueLabel); 305 306 // Submit the work for the main render thread 307 const VkCommandBuffer cmd_bufs[] = {commandBuffer}; 308 VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 309 .pNext = NULL, 310 .waitSemaphoreCount = 0, 311 .pWaitSemaphores = NULL, 312 .pWaitDstStageMask = NULL, 313 .commandBufferCount = 1, 314 .pCommandBuffers = cmd_bufs, 315 .signalSemaphoreCount = 0, 316 .pSignalSemaphores = NULL}; 317 vkQueueSubmit(queue, 1, &submit_info, fence); 318 319 // End the queue label region 320 pfnQueueEndDebugUtilsLabelEXT(queue); 321 322---------------------------------------- 323 324=== Issues 325 3261) Should we just name this extension `VK_EXT_debug_report2` 327 328**RESOLVED**: No. 329There is enough additional changes to the structures to break backwards 330compatibility. 331So, a new name was decided that would not indicate any interaction with the 332previous extension. 333 3342) Will validation layers immediately support all the new features. 335 336**RESOLVED**: Not immediately. 337As one can imagine, there is a lot of work involved with converting the 338validation layer logging over to the new functionality. 339Basic logging, as seen in the origin 340<<VK_EXT_debug_report,VK_EXT_debug_report>> extension will be made available 341immediately. 342However, adding the labels and object names will take time. 343Since the priority for Khronos at this time is to continue focusing on Valid 344Usage statements, it may take a while before the new functionality is fully 345exposed. 346 3473) If the validation layers won't expose the new functionality immediately, 348then what's the point of this extension? 349 350**RESOLVED**: We needed a replacement for 351<<VK_EXT_debug_report,VK_EXT_debug_report>> because the 352elink:VkDebugReportObjectTypeEXT enumeration will no longer be updated and 353any new objects will need to be debugged using the new functionality 354provided by this extension. 355 3564) Should this extension be split into two separate parts (1 extension that 357is an instance extension providing the callback functionality, and another 358device extension providing the general debug marker and annotation 359functionality)? 360 361**RESOLVED**: No, the functionality for this extension is too closely 362related. 363If we did split up the extension, where would the structures and enums live, 364and how would you define that the device behavior in the instance extension 365is really only valid if the device extension is enabled, and the 366functionality is passed in. 367It's cleaner to just define this all as an instance extension, plus it 368allows the application to enable all debug functionality provided with one 369enable string during flink:vkCreateInstance. 370 371=== Version History 372 373 * Revision 1, 2017-09-14 (Mark Young and all listed Contributors) 374 ** Initial draft, based on <<VK_EXT_debug_report,VK_EXT_debug_report>> and 375 <<VK_EXT_debug_marker,VK_EXT_debug_marker>> in addition to previous 376 feedback supplied from various companies including Valve, Epic, and 377 Oxide games. 378