主要参考VulkanでShaderからprintfする方法
在shader中开启GL_EXT_debug_printf拓展可以很方便的在shader中使用print。用法为:
在shader开头开启GL_EXT_debug_printf拓展:
1
| #extension GL_EXT_debug_printf : enable
|
在shader中用和printf同样的方法调用debugPrintfEXT
1 2 3 4 5 6
| void main() { ... debugPrintfEXT("from mesh thread group %d %d %d\n",gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, gl_GlobalInvocationID.z); ... }
|
接着需要在vulkan configurator中添加对这个拓展的支持。
在validation settings 中标红线处的选项改为Debug Printf Present

在vulkan创建instance的过程中需要初始化VkValidationFeaturesEXT
并将其加入VkInstanceCreateInfo
的pNext
链表中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| std::vector<VkValidationFeatureEnableEXT> m_validationFeatureEnabled; m_validationFeatureEnabled.push_back(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT); ...
VkInstanceCreateInfo inst_create{}; ... VkValidationFeaturesEXT validation_features{};
validation_features.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT; validation_features.enabledValidationFeatureCount = m_validationFeatureEnabled.size(); validation_features.pEnabledValidationFeatures = m_validationFeatureEnabled.data(); ...
validation_features.pNext = inst_create.pNext; inst_create.pNext = &validation_features;
|
由于打印的消息会在VK_DEBUG_REPORT_INFORMATION_BIT_EXT
层,而默认是不会输出INFORMATION信息的,因此,我们需要创建自定义的VkDebugReportCallbackEXT
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT , uint64_t , size_t , int32_t , const char* layer_prefix, const char* message, void* ) { if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { printf("%s: %s\n", layer_prefix, message); } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { printf("%s: %s\n", layer_prefix, message); } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { printf("%s: %s\n", layer_prefix, message); } else { printf("%s: %s\n", layer_prefix, message); } return VK_FALSE; } ... int m_debugReportFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT; VkDebugReportCallbackEXT m_debugCallback = NULL; ... VkInstanceCreateInfo inst_create{}; ... VkDebugReportCallbackCreateInfoEXT debugReportCI{};
debugReportCI.pfnCallback = debug_callback; debugReportCI.flags = m_debugReportFlags; debugReportCI.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debugReportCI.pNext = inst_create.pNext; inst_create.pNext = &debugReportCI; ... vkCreateDebugReportCallbackEXT(m_VkInstance, &debugReportCI, NULL, &m_debugCallback);
|
设定好后便可在stdout中看到打印的信息:

对我这种编程苦手,这一特性在debug compute shader, mesh shader以及rt shader中相当有用。
注意 每帧最好只打印少量信息(例如:对compute shader只打印某个特定的线程),一次性打印太多信息会报message truncated。对于pixel shader最好还是通过输出颜色调试。

后记 这个特性搭配renderdoc使用非常丝滑,renderdoc除了能截取打印的所有字符串,还能得到compute shader对应线程组编号。