调试
为了帮助开发人员跟踪应用程序中使用 Vulkan 时的错误,尤其是在结合外部调试器或性能分析器时,可以使用调试扩展。
VkObjectType 枚举定义了一些值,每个值对应一个特定的 Vulkan 句柄类型。这些值可以用于通过一个或多个扩展将调试信息与特定类型的对象关联起来。
// Provided by VK_VERSION_1_0
typedef enum VkObjectType {
VK_OBJECT_TYPE_UNKNOWN = 0,
VK_OBJECT_TYPE_INSTANCE = 1,
VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
VK_OBJECT_TYPE_DEVICE = 3,
VK_OBJECT_TYPE_QUEUE = 4,
VK_OBJECT_TYPE_SEMAPHORE = 5,
VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
VK_OBJECT_TYPE_FENCE = 7,
VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
VK_OBJECT_TYPE_BUFFER = 9,
VK_OBJECT_TYPE_IMAGE = 10,
VK_OBJECT_TYPE_EVENT = 11,
VK_OBJECT_TYPE_QUERY_POOL = 12,
VK_OBJECT_TYPE_BUFFER_VIEW = 13,
VK_OBJECT_TYPE_IMAGE_VIEW = 14,
VK_OBJECT_TYPE_SHADER_MODULE = 15,
VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
VK_OBJECT_TYPE_RENDER_PASS = 18,
VK_OBJECT_TYPE_PIPELINE = 19,
VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
VK_OBJECT_TYPE_SAMPLER = 21,
VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
VK_OBJECT_TYPE_FRAMEBUFFER = 24,
VK_OBJECT_TYPE_COMMAND_POOL = 25,
// Provided by VK_VERSION_1_1
VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000,
// Provided by VK_VERSION_1_1
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000,
// Provided by VK_VERSION_1_3
VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000,
// Provided by VK_KHR_surface
VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
// Provided by VK_KHR_swapchain
VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
// Provided by VK_KHR_display
VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
// Provided by VK_KHR_display
VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
// Provided by VK_EXT_debug_report
VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000,
// Provided by VK_KHR_video_queue
VK_OBJECT_TYPE_VIDEO_SESSION_KHR = 1000023000,
// Provided by VK_KHR_video_queue
VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR = 1000023001,
// Provided by VK_NVX_binary_import
VK_OBJECT_TYPE_CU_MODULE_NVX = 1000029000,
// Provided by VK_NVX_binary_import
VK_OBJECT_TYPE_CU_FUNCTION_NVX = 1000029001,
// Provided by VK_EXT_debug_utils
VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000,
// Provided by VK_KHR_acceleration_structure
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000,
// Provided by VK_EXT_validation_cache
VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
// Provided by VK_NV_ray_tracing
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
// Provided by VK_INTEL_performance_query
VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000,
// Provided by VK_KHR_deferred_host_operations
VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000,
// Provided by VK_NV_device_generated_commands
VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000,
// Provided by VK_NV_cuda_kernel_launch
VK_OBJECT_TYPE_CUDA_MODULE_NV = 1000307000,
// Provided by VK_NV_cuda_kernel_launch
VK_OBJECT_TYPE_CUDA_FUNCTION_NV = 1000307001,
// Provided by VK_FUCHSIA_buffer_collection
VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000,
// Provided by VK_EXT_opacity_micromap
VK_OBJECT_TYPE_MICROMAP_EXT = 1000396000,
// Provided by VK_NV_optical_flow
VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV = 1000464000,
// Provided by VK_EXT_shader_object
VK_OBJECT_TYPE_SHADER_EXT = 1000482000,
// Provided by VK_KHR_pipeline_binary
VK_OBJECT_TYPE_PIPELINE_BINARY_KHR = 1000483000,
// Provided by VK_EXT_device_generated_commands
VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_EXT = 1000572000,
// Provided by VK_EXT_device_generated_commands
VK_OBJECT_TYPE_INDIRECT_EXECUTION_SET_EXT = 1000572001,
// Provided by VK_KHR_descriptor_update_template
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
// Provided by VK_KHR_sampler_ycbcr_conversion
VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
// Provided by VK_EXT_private_data
VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT,
} VkObjectType;
VkObjectType | Vulkan 句柄类型 |
---|---|
|
未知/未定义的句柄 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果本规范是在包含任何此类扩展的情况下生成的,它们将在本章的其余部分进行描述。
调试实用程序
Vulkan 提供了灵活的调试实用程序来调试应用程序。
对象调试注释部分描述了如何将名称或二进制数据与特定的 Vulkan 对象关联起来。
队列标签部分描述了如何注释和分组提交到队列的工作。
命令缓冲区标签部分描述了如何将场景的逻辑元素与 VkCommandBuffer 中的命令关联起来。
调试信使部分描述了如何创建与应用程序提供的回调关联的调试信使对象,以捕获来自各种 Vulkan 组件的调试消息。
对象调试注释
对于应用程序来说,提供其自己的内容相对于特定的 Vulkan 对象可能很有用。
以下命令允许应用程序开发人员将应用程序定义的信息与 Vulkan 对象关联。这些命令是设备级别的命令,但它们可能引用实例级别的对象(例如 VkInstance)和物理设备级别的对象(例如 VkPhysicalDevice),但有一些限制:* 对应对象的数据在销毁用于设置该数据的相应 API 调用中的 VkDevice 之后可能仍然可用,但不能保证可以访问此数据,应避免访问。* 在多个 VkDevice
对象之间多次调用以更改同一对象的数据,可能会导致所有 VkDevice
对象的数据更改为最新版本,而不仅仅是最近 API 调用中使用的 VkDevice
。
对象命名
可以通过调用以下函数为对象指定应用程序定义的名称
// Provided by VK_EXT_debug_utils
VkResult vkSetDebugUtilsObjectNameEXT(
VkDevice device,
const VkDebugUtilsObjectNameInfoEXT* pNameInfo);
-
device
是与通过objectHandle
传递的命名对象关联的设备。 -
pNameInfo
是指向 VkDebugUtilsObjectNameInfoEXT 结构的指针,该结构指定要在对象上设置的名称的参数。
VkDebugUtilsObjectNameInfoEXT
结构定义如下
// Provided by VK_EXT_debug_utils
typedef struct VkDebugUtilsObjectNameInfoEXT {
VkStructureType sType;
const void* pNext;
VkObjectType objectType;
uint64_t objectHandle;
const char* pObjectName;
} VkDebugUtilsObjectNameInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
objectType
是一个 VkObjectType,用于指定要命名的对象的类型。 -
objectHandle
是要命名的对象。 -
pObjectName
是NULL
或以 null 结尾的 UTF-8 字符串,用于指定要应用于objectHandle
的名称。
应用程序可以通过再次调用 vkSetDebugUtilsObjectNameEXT
并使用新字符串来更改与对象关联的名称。如果 pObjectName
为 NULL
或空字符串,则会删除任何先前设置的名称。
graphicsPipelineLibrary
功能允许在不事先创建 VkShaderModule 对象的情况下指定管线。为了继续允许独立命名这些着色器,VkPipelineShaderStageCreateInfo 的 pNext
链中可以包含 VkDebugUtilsObjectNameInfoEXT
,它将静态名称与该特定着色器相关联。
对象数据关联
除了为对象设置名称之外,调试和验证层可能还会使用每个对象的其他二进制数据,这些数据在 Vulkan API 中没有其他位置。
例如,VkShaderModule
可以附加额外的调试数据,以帮助进行脱机着色器跟踪。
可以通过调用如下定义的 vkSetDebugUtilsObjectTagEXT
将其他数据附加到对象。
// Provided by VK_EXT_debug_utils
VkResult vkSetDebugUtilsObjectTagEXT(
VkDevice device,
const VkDebugUtilsObjectTagInfoEXT* pTagInfo);
-
device
是创建该对象的设备。 -
pTagInfo
是指向 VkDebugUtilsObjectTagInfoEXT 结构的指针,该结构指定要附加到对象的标签的参数。
VkDebugUtilsObjectTagInfoEXT
结构的定义如下:
// Provided by VK_EXT_debug_utils
typedef struct VkDebugUtilsObjectTagInfoEXT {
VkStructureType sType;
const void* pNext;
VkObjectType objectType;
uint64_t objectHandle;
uint64_t tagName;
size_t tagSize;
const void* pTag;
} VkDebugUtilsObjectTagInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
objectType
是一个 VkObjectType,用于指定要命名的对象的类型。 -
objectHandle
是要标记的对象。 -
tagName
是标签的数字标识符。 -
tagSize
是附加到对象的字节数据数。 -
pTag
是指向包含要与对象关联的数据的tagSize
字节数组的指针。
tagName
参数为要标记的数据类型提供名称或标识符。调试层可以使用它来轻松过滤出仅可由该实现使用的数据。
队列标签
所有 Vulkan 工作都使用队列提交。应用程序可以在执行工作时使用多个队列,每个队列包含多个命令缓冲区。识别发生事情的队列,甚至是队列中的位置可能很有用。
要开始在队列内使用调试标签识别区域,可以使用 vkQueueBeginDebugUtilsLabelEXT 命令。
然后,当感兴趣的区域通过后,可以使用 vkQueueEndDebugUtilsLabelEXT 结束标签区域。
此外,可以使用 vkQueueInsertDebugUtilsLabelEXT 随时插入单个调试标签。
通过调用以下命令打开队列调试标签区域:
// Provided by VK_EXT_debug_utils
void vkQueueBeginDebugUtilsLabelEXT(
VkQueue queue,
const VkDebugUtilsLabelEXT* pLabelInfo);
-
queue
是在其中启动调试标签区域的队列。 -
pLabelInfo
是指向 VkDebugUtilsLabelEXT 结构的指针,该结构指定要打开的标签区域的参数。
VkDebugUtilsLabelEXT
结构的定义如下:
// Provided by VK_EXT_debug_utils
typedef struct VkDebugUtilsLabelEXT {
VkStructureType sType;
const void* pNext;
const char* pLabelName;
float color[4];
} VkDebugUtilsLabelEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
pLabelName
是指向包含标签名称的空终止 UTF-8 字符串的指针。 -
color
是一个可选的 RGBA 颜色值,可以与标签关联。特定的实现可以选择忽略此颜色值。这些值按顺序包含 0.0 到 1.0 范围内的 RGBA 值。如果color
中的所有元素均为 0.0,则将其忽略。
通过调用以下命令关闭队列调试标签区域:
// Provided by VK_EXT_debug_utils
void vkQueueEndDebugUtilsLabelEXT(
VkQueue queue);
-
queue
是应该关闭调试标签区域的队列。
对 vkQueueBeginDebugUtilsLabelEXT 和 vkQueueEndDebugUtilsLabelEXT 的调用必须匹配并平衡。
通过调用以下命令可以将单个标签插入队列中:
// Provided by VK_EXT_debug_utils
void vkQueueInsertDebugUtilsLabelEXT(
VkQueue queue,
const VkDebugUtilsLabelEXT* pLabelInfo);
-
queue
是将插入调试标签的队列。 -
pLabelInfo
是指向 VkDebugUtilsLabelEXT 结构的指针,该结构指定要插入的标签的参数。
命令缓冲区标签
典型的 Vulkan 应用程序将在每一帧中提交许多命令缓冲区,每个命令缓冲区包含大量单独的命令。能够以逻辑方式注释属于一起的命令缓冲区区域以及按层次结构细分帧对于开发人员整体查看命令的能力非常重要。
要标识命令缓冲区中调试标签区域的开始,可以使用如下定义的 vkCmdBeginDebugUtilsLabelEXT。
要指示命令缓冲区中调试标签区域的结束,可以使用 vkCmdEndDebugUtilsLabelEXT。
要在命令缓冲区内插入单个命令缓冲区调试标签,可以使用如下定义的 vkCmdInsertDebugUtilsLabelEXT。
可以通过调用以下命令打开命令缓冲区调试标签区域:
// Provided by VK_EXT_debug_utils
void vkCmdBeginDebugUtilsLabelEXT(
VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT* pLabelInfo);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
pLabelInfo
是指向 VkDebugUtilsLabelEXT 结构的指针,该结构指定要打开的标签区域的参数。
可以通过调用来关闭命令缓冲区标签区域
// Provided by VK_EXT_debug_utils
void vkCmdEndDebugUtilsLabelEXT(
VkCommandBuffer commandBuffer);
-
commandBuffer
是将命令记录到的命令缓冲区。
应用程序可以在一个命令缓冲区中打开调试标签区域,并在另一个命令缓冲区中关闭它,或者以其他方式将调试标签区域分割到多个命令缓冲区或多个队列提交中。从提交到单个队列的线性序列来看,对 vkCmdBeginDebugUtilsLabelEXT 和 vkCmdEndDebugUtilsLabelEXT 的调用必须匹配和平衡。
在记录过程中报告命令缓冲区调试标签可能存在问题,因为命令缓冲区的记录顺序可能与最终的执行顺序不一致。由于记录顺序可能不同,单独的命令缓冲区本身可能对调试标签区域的视图不一致。因此,如果在记录命令缓冲区时发生问题,并且环境需要返回调试标签,则实现可能只返回它知道的标签。即使实现仅知道正在积极记录的命令缓冲区内的调试标签,也是如此。
可以通过调用将单个调试标签插入到命令缓冲区中
// Provided by VK_EXT_debug_utils
void vkCmdInsertDebugUtilsLabelEXT(
VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT* pLabelInfo);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
pInfo
是指向 VkDebugUtilsLabelEXT 结构的指针,该结构指定要插入的标签的参数。
调试消息器
Vulkan 允许应用程序向任何希望报告调试信息的 Vulkan 组件注册多个回调。某些回调可能会将信息记录到文件中,而其他回调可能会导致调试断点或其他应用程序定义的行为。回调消息的主要生产者是验证层。即使未启用任何验证层,应用程序可以注册回调,但它们只会为 Vulkan 加载器以及(如果已实现)其他层和驱动程序事件调用。
VkDebugUtilsMessengerEXT
是一个消息器对象,它处理将调试消息传递给提供的调试回调。
// Provided by VK_EXT_debug_utils
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT)
当发生感兴趣的事件时,调试消息器将提供有关应用程序使用 Vulkan 的详细反馈。当发生感兴趣的事件时,调试消息器会将调试消息提交给在创建期间提供的调试回调。此外,调试消息器还负责过滤掉回调不感兴趣的调试消息,并且只提供所需的调试消息。
当发生感兴趣的事件时,调试消息器会使用调试消息触发调试回调。要创建将触发调试回调的调试消息器,请调用
// Provided by VK_EXT_debug_utils
VkResult vkCreateDebugUtilsMessengerEXT(
VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDebugUtilsMessengerEXT* pMessenger);
-
instance
是将使用消息器的实例。 -
pCreateInfo
是指向 VkDebugUtilsMessengerCreateInfoEXT 结构的指针,其中包含回调指针,以及定义此消息器将触发回调的条件。 -
pAllocator
控制主机内存分配,如内存分配章节中所述。 -
pMessenger
是指向 VkDebugUtilsMessengerEXT 句柄的指针,其中返回创建的对象。
应用程序必须确保 vkCreateDebugUtilsMessengerEXT 的执行不会与任何使用 instance
或 instance
的子项作为可调度参数的 Vulkan 命令并行执行。
VkDebugUtilsMessengerCreateInfoEXT
的定义如下:
// Provided by VK_EXT_debug_utils
typedef struct VkDebugUtilsMessengerCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDebugUtilsMessengerCreateFlagsEXT flags;
VkDebugUtilsMessageSeverityFlagsEXT messageSeverity;
VkDebugUtilsMessageTypeFlagsEXT messageType;
PFN_vkDebugUtilsMessengerCallbackEXT pfnUserCallback;
void* pUserData;
} VkDebugUtilsMessengerCreateInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
为0
,保留供将来使用。 -
messageSeverity
是一个 VkDebugUtilsMessageSeverityFlagBitsEXT 的位掩码,指定哪些严重级别的事件将导致调用此回调。 -
messageType
是一个 VkDebugUtilsMessageTypeFlagBitsEXT 的位掩码,指定哪些类型的事件将导致调用此回调。 -
pfnUserCallback
是要调用的应用程序回调函数。 -
pUserData
是要传递给回调的用户数据。
对于创建的每个 VkDebugUtilsMessengerEXT
,VkDebugUtilsMessengerCreateInfoEXT
::messageSeverity
和 VkDebugUtilsMessengerCreateInfoEXT
::messageType
确定何时调用该 VkDebugUtilsMessengerCreateInfoEXT
::pfnUserCallback
。确定在发生事件时是否触发用户的 pfnUserCallback
的过程如下:
-
实现将事件的 VkDebugUtilsMessageSeverityFlagBitsEXT 与创建 VkDebugUtilsMessengerEXT 对象期间提供的
messageSeverity
执行按位与运算。-
如果值为 0,则跳过消息。
-
-
实现将事件的 VkDebugUtilsMessageTypeFlagBitsEXT 与创建 VkDebugUtilsMessengerEXT 对象期间提供的
messageType
执行按位与运算。-
如果值为 0,则跳过消息。
-
-
回调将触发当前事件的调试消息。
回调将直接来自检测到事件的组件,除非其他层为了自己的目的(以不同的方式过滤它们、记录到系统错误日志等)拦截调用。
如果创建了多个 VkDebugUtilsMessengerEXT
对象,应用程序可以接收多个回调。回调始终在与原始 Vulkan 调用相同的线程中执行。
回调可以从多个线程同时调用(如果应用程序正在从多个线程进行 Vulkan 调用)。
// Provided by VK_EXT_debug_utils
typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT;
VkDebugUtilsMessengerCreateFlagsEXT
是一种用于设置掩码的位掩码类型,但目前保留供将来使用。
可以在 VkDebugUtilsMessengerCreateInfoEXT::messageSeverity
中设置的位,指定导致调试消息传递器调用回调的事件严重性,如下所示:
// Provided by VK_EXT_debug_utils
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
指定最详细的输出,指示应捕获来自 Vulkan 加载器、层和驱动程序的所有诊断消息。 -
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
指定信息性消息,例如在调试应用程序时可能方便的资源详细信息。 -
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
指定对 Vulkan 的使用可能暴露应用程序错误。这种情况可能不会立即有害,例如片段着色器输出到没有附件的位置。其他情况可能指向当非预期时几乎肯定是不良的行为,例如使用尚未填充内存的图像。一般来说,如果您看到警告但您知道该行为是预期/期望的,那么只需忽略该警告即可。 -
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
指定应用程序违反了规范的有效使用条件。
VkDebugUtilsMessageSeverityFlagBitsEXT 的值基于严重性排序。标志值越高,消息越严重。这允许在查看 VkDebugUtilsMessageSeverityFlagBitsEXT 值时进行简单的布尔运算比较。 例如:
此外,枚举之间留有空间,以便以后在现有值之间添加新的严重性。 |
// Provided by VK_EXT_debug_utils
typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT;
VkDebugUtilsMessageSeverityFlagsEXT
是一种用于设置零个或多个 VkDebugUtilsMessageSeverityFlagBitsEXT 掩码的位掩码类型。
可以在 VkDebugUtilsMessengerCreateInfoEXT::messageType
中设置的位,指定导致调试消息传递器调用回调的事件类型,如下所示:
// Provided by VK_EXT_debug_utils
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,
// Provided by VK_EXT_device_address_binding_report
VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT = 0x00000008,
} VkDebugUtilsMessageTypeFlagBitsEXT;
-
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
指定发生了一些常规事件。这通常是一个非规范、非性能事件。 -
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
指定在针对 Vulkan 规范进行验证期间发生了一些事情,这可能表明行为无效。 -
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
指定潜在的非最佳 Vulkan 使用,例如当将 VkAttachmentDescription::loadOp
设置为VK_ATTACHMENT_LOAD_OP_CLEAR
时,使用 vkCmdClearColorImage 也可以工作。 -
VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT
指定实现已修改与 Vulkan 对象关联的 GPU 可见虚拟地址集。
// Provided by VK_EXT_debug_utils
typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT;
VkDebugUtilsMessageTypeFlagsEXT
是一个位掩码类型,用于设置零个或多个 VkDebugUtilsMessageTypeFlagBitsEXT 的掩码。
应用程序实现的 VkDebugUtilsMessengerCreateInfoEXT::pfnUserCallback
函数的原型是
// Provided by VK_EXT_debug_utils
typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
-
messageSeverity
指定触发此回调的 VkDebugUtilsMessageSeverityFlagBitsEXT。 -
messageTypes
是一个 VkDebugUtilsMessageTypeFlagBitsEXT 的位掩码,指定触发此回调的事件类型。 -
pCallbackData
在 VkDebugUtilsMessengerCallbackDataEXT 结构中包含所有与回调相关的数据。 -
pUserData
是创建 VkDebugUtilsMessengerEXT 时提供的用户数据。
回调返回一个 VkBool32
,其解释方式由层指定。应用程序应该始终返回 VK_FALSE
。VK_TRUE
值保留用于层开发。
VkDebugUtilsMessengerCallbackDataEXT
的定义如下:
// Provided by VK_EXT_debug_utils
typedef struct VkDebugUtilsMessengerCallbackDataEXT {
VkStructureType sType;
const void* pNext;
VkDebugUtilsMessengerCallbackDataFlagsEXT flags;
const char* pMessageIdName;
int32_t messageIdNumber;
const char* pMessage;
uint32_t queueLabelCount;
const VkDebugUtilsLabelEXT* pQueueLabels;
uint32_t cmdBufLabelCount;
const VkDebugUtilsLabelEXT* pCmdBufLabels;
uint32_t objectCount;
const VkDebugUtilsObjectNameInfoEXT* pObjects;
} VkDebugUtilsMessengerCallbackDataEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
为0
,保留供将来使用。 -
pMessageIdName
为NULL
或以 null 结尾的 UTF-8 字符串,用于标识与提供的消息关联的特定消息 ID。如果消息对应于验证层消息,则此字符串可能包含被认为违反的 Vulkan 规范部分。 -
messageIdNumber
是触发消息的 ID 号。如果消息对应于验证层消息,则此数字与正在触发的消息的内部编号相关。 -
如果
messageTypes
等于VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT
,则pMessage
为NULL
,或者为以 null 结尾的 UTF-8 字符串,详细说明触发条件。 -
queueLabelCount
是pQueueLabels
数组中包含的项目计数。 -
pQueueLabels
为NULL
或指向 VkDebugUtilsLabelEXT 数组的指针,这些标签在回调触发时在当前VkQueue
中处于活动状态。有关更多信息,请参阅 队列标签。 -
cmdBufLabelCount
是pCmdBufLabels
数组中包含的项目计数。 -
pCmdBufLabels
为NULL
或指向 VkDebugUtilsLabelEXT 数组的指针,这些标签在回调触发时在当前VkCommandBuffer
中处于活动状态。有关更多信息,请参阅 命令缓冲区标签。 -
objectCount
是pObjects
数组中包含的项目计数。 -
pObjects
是指向与检测到的问题相关的 VkDebugUtilsObjectNameInfoEXT 对象数组的指针。该数组大致按重要性排序,但保证第 0 个元素始终是此消息的最重要对象。
此结构应仅在触发的回调的生命周期内被视为有效。 |
由于添加队列和命令缓冲区标签的行为类似于推入和弹出堆栈,因此 pQueueLabels
和 pCmdBufLabels
的顺序均基于标签定义的顺序。结果是,pQueueLabels
或 pCmdBufLabels
中的第一个标签将是第一个定义的(因此是最旧的),而每个列表中的最后一个标签将是最近的。
只有当 同样,只有当 |
// Provided by VK_EXT_debug_utils
typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT;
VkDebugUtilsMessengerCallbackDataFlagsEXT
是一个用于设置掩码的位掩码类型,但目前保留供将来使用。
VkDeviceAddressBindingCallbackDataEXT
的定义如下:
// Provided by VK_EXT_device_address_binding_report
typedef struct VkDeviceAddressBindingCallbackDataEXT {
VkStructureType sType;
void* pNext;
VkDeviceAddressBindingFlagsEXT flags;
VkDeviceAddress baseAddress;
VkDeviceSize size;
VkDeviceAddressBindingTypeEXT bindingType;
} VkDeviceAddressBindingCallbackDataEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是一个 VkDeviceAddressBindingFlagBitsEXT 的位掩码,用于指定有关导致调用回调的绑定事件的其他信息。 -
baseAddress
是一个 GPU 可访问的虚拟地址,用于标识与 Vulkan 对象关联的虚拟地址空间的区域的起始位置,如 VkDebugUtilsMessengerCallbackDataEXT 的pObjects
成员所标识。 -
size
是 GPU 可访问虚拟地址空间区域的大小(以字节为单位)。 -
bindingType
是一个 VkDeviceAddressBindingTypeEXT,用于指定导致回调被调用的绑定事件类型。
如果启用了 reportAddressBinding
功能,并且实现绑定或解绑了与 Vulkan 对象关联的虚拟地址空间区域,则实现必须提交具有以下属性的调试消息
-
messageSeverity
等于VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
-
messageTypes
等于VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT
-
VkDebugUtilsMessengerCallbackDataEXT
::pObjects
必须标识关联的 Vulkan 对象 -
VkDeviceAddressBindingCallbackDataEXT
必须包含在VkDebugUtilsMessengerCallbackDataEXT
的pNext
链中
这些调试消息必须为通过 vkBind
*Memory/vkBind
*Memory2 函数显式绑定到 Vulkan 对象的 GPU 虚拟地址空间区域,以及通过内存分配或导入外部内存隐式生成的区域发出。
实现可以在对象通过其他 Vulkan 命令对应用程序可见之前,通过 VkDebugUtilsMessengerEXT
报告与 Vulkan 对象关联的绑定事件。例如,对象创建函数可以报告在对象创建期间发生的绑定事件。在这种情况下,VkDeviceAddressBindingCallbackDataEXT
::flags
必须包含 VK_DEVICE_ADDRESS_BINDING_INTERNAL_OBJECT_BIT_EXT
。
以这种方式报告的对象句柄不是有效的对象句柄,必须不作为任何 Vulkan 命令的输入参数使用。
对象创建函数返回的任何有效对象句柄必须与之前报告的与对象创建关联的任何绑定事件中指定的句柄匹配。
在 VkDeviceAddressBindingCallbackDataEXT::flags
中可以设置的位,用于指定关于绑定事件的附加信息,有:
// Provided by VK_EXT_device_address_binding_report
typedef enum VkDeviceAddressBindingFlagBitsEXT {
VK_DEVICE_ADDRESS_BINDING_INTERNAL_OBJECT_BIT_EXT = 0x00000001,
} VkDeviceAddressBindingFlagBitsEXT;
-
VK_DEVICE_ADDRESS_BINDING_INTERNAL_OBJECT_BIT_EXT
指定 VkDeviceAddressBindingCallbackDataEXT 描述一个尚未通过 Vulkan 命令对应用程序可见的 Vulkan 对象。
// Provided by VK_EXT_device_address_binding_report
typedef VkFlags VkDeviceAddressBindingFlagsEXT;
VkDeviceAddressBindingFlagsEXT 是一个位掩码类型,用于设置零个或多个 VkDeviceAddressBindingFlagBitsEXT 的掩码。
VkDeviceAddressBindingTypeEXT
枚举定义如下:
// Provided by VK_EXT_device_address_binding_report
typedef enum VkDeviceAddressBindingTypeEXT {
VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT = 0,
VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT = 1,
} VkDeviceAddressBindingTypeEXT;
-
VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT
指定已绑定新的 GPU 可访问的虚拟地址范围。 -
VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT
指定已解绑 GPU 可访问的虚拟地址范围。
要有意提交调试消息,请调用
// Provided by VK_EXT_debug_utils
void vkSubmitDebugUtilsMessageEXT(
VkInstance instance,
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData);
-
instance
是调试流的 VkInstance。 -
messageSeverity
是一个 VkDebugUtilsMessageSeverityFlagBitsEXT 值,指定此事件/消息的严重性。 -
messageTypes
是一个 VkDebugUtilsMessageTypeFlagBitsEXT 的位掩码,指定与此消息关联的事件类型。 -
pCallbackData
在 VkDebugUtilsMessengerCallbackDataEXT 结构中包含所有与回调相关的数据。
调用将通过层传播,并根据消息的标志生成回调。除了注册 messenger 时定义的 pUserData
值之外,参数还会传递给回调。
要销毁 VkDebugUtilsMessengerEXT
对象,请调用
// Provided by VK_EXT_debug_utils
void vkDestroyDebugUtilsMessengerEXT(
VkInstance instance,
VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks* pAllocator);
-
instance
是创建回调的实例。 -
messenger
是要销毁的 VkDebugUtilsMessengerEXT 对象。messenger
是一个外部同步的对象,必须不能在同一时间在多个线程上使用。这意味着在回调处于活动状态时必须不调用vkDestroyDebugUtilsMessengerEXT
。 -
pAllocator
控制主机内存分配,如内存分配章节中所述。
应用程序必须确保 vkDestroyDebugUtilsMessengerEXT 不会与也以 instance
或 instance
的子对象作为可调度参数调用的任何 Vulkan 命令并行执行。
调试标记
调试标记提供了一种灵活的方式,使调试和验证层能够接收注释和调试信息。
对象注释 部分描述了如何将名称或二进制数据与 Vulkan 对象关联。
命令缓冲区标记 部分描述了如何将场景的逻辑元素与命令缓冲区中的命令关联。
对象注解
本节中的命令允许应用程序开发人员随意将应用程序定义的信息与 Vulkan 对象相关联。
可以通过调用以下函数为对象指定应用程序定义的名称
// Provided by VK_EXT_debug_marker
VkResult vkDebugMarkerSetObjectNameEXT(
VkDevice device,
const VkDebugMarkerObjectNameInfoEXT* pNameInfo);
-
device
是创建该对象的设备。 -
pNameInfo
是指向 VkDebugMarkerObjectNameInfoEXT 结构的指针,该结构指定要在对象上设置的名称的参数。
VkDebugMarkerObjectNameInfoEXT
结构的定义如下
// Provided by VK_EXT_debug_marker
typedef struct VkDebugMarkerObjectNameInfoEXT {
VkStructureType sType;
const void* pNext;
VkDebugReportObjectTypeEXT objectType;
uint64_t object;
const char* pObjectName;
} VkDebugMarkerObjectNameInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
objectType
是一个 VkDebugReportObjectTypeEXT,指定要命名的对象的类型。 -
object
是要命名的对象。 -
pObjectName
是一个以 null 结尾的 UTF-8 字符串,指定要应用于object
的名称。
应用程序可以通过再次调用 vkDebugMarkerSetObjectNameEXT
并使用新字符串来更改与对象关联的名称。要删除先前设置的名称,pObjectName
应该是一个空字符串。
除了为对象设置名称外,调试和验证层可能还需要在每个对象的基础上使用额外的二进制数据,这些数据在 Vulkan API 中没有其他位置。例如,VkShaderModule
可以附加额外的调试数据,以帮助进行离线着色器跟踪。要将数据附加到对象,请调用
// Provided by VK_EXT_debug_marker
VkResult vkDebugMarkerSetObjectTagEXT(
VkDevice device,
const VkDebugMarkerObjectTagInfoEXT* pTagInfo);
-
device
是创建该对象的设备。 -
pTagInfo
是指向 VkDebugMarkerObjectTagInfoEXT 结构的指针,该结构指定要附加到对象的标签的参数。
VkDebugMarkerObjectTagInfoEXT
结构的定义如下
// Provided by VK_EXT_debug_marker
typedef struct VkDebugMarkerObjectTagInfoEXT {
VkStructureType sType;
const void* pNext;
VkDebugReportObjectTypeEXT objectType;
uint64_t object;
uint64_t tagName;
size_t tagSize;
const void* pTag;
} VkDebugMarkerObjectTagInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
objectType
是一个 VkDebugReportObjectTypeEXT,指定要命名的对象的类型。 -
object
是要标记的对象。 -
tagName
是标签的数字标识符。 -
tagSize
是附加到对象的字节数据数。 -
pTag
是指向包含要与对象关联的数据的tagSize
字节数组的指针。
tagName
参数为要标记的数据类型提供名称或标识符。调试层可以使用它来轻松过滤出仅可由该实现使用的数据。
命令缓冲区标记
典型的 Vulkan 应用程序将在每一帧中提交许多命令缓冲区,每个命令缓冲区包含大量单独的命令。能够以逻辑方式注释属于一起的命令缓冲区区域以及按层次结构细分帧对于开发人员整体查看命令的能力非常重要。
标记命令 vkCmdDebugMarkerBeginEXT
和 vkCmdDebugMarkerEndEXT
定义了一系列命令的区域,这些命令组合在一起,并且可以嵌套以创建层次结构。vkCmdDebugMarkerInsertEXT
命令允许在命令缓冲区内插入单个标签。
可以通过调用以下命令打开标记区域
// Provided by VK_EXT_debug_marker
void vkCmdDebugMarkerBeginEXT(
VkCommandBuffer commandBuffer,
const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
pMarkerInfo
是指向 VkDebugMarkerMarkerInfoEXT 结构的指针,该结构指定要打开的标记区域的参数。
VkDebugMarkerMarkerInfoEXT
结构的定义如下
// Provided by VK_EXT_debug_marker
typedef struct VkDebugMarkerMarkerInfoEXT {
VkStructureType sType;
const void* pNext;
const char* pMarkerName;
float color[4];
} VkDebugMarkerMarkerInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
pMarkerName
是指向以 null 结尾的 UTF-8 字符串的指针,其中包含标记的名称。 -
color
是与标记关联的可选 RGBA 颜色值。特定的实现可以选择忽略此颜色值。这些值按顺序包含 RGBA 值,范围为 0.0 到 1.0。如果color
中的所有元素均为 0.0,则会将其忽略。
可以通过调用以下命令关闭标记区域
// Provided by VK_EXT_debug_marker
void vkCmdDebugMarkerEndEXT(
VkCommandBuffer commandBuffer);
-
commandBuffer
是将命令记录到的命令缓冲区。
应用程序可以在一个命令缓冲区中打开一个标记区域,并在另一个命令缓冲区中关闭它,或者将标记区域拆分到多个命令缓冲区或多个队列提交中。当从提交到单个队列的线性序列来看时,对 vkCmdDebugMarkerBeginEXT
和 vkCmdDebugMarkerEndEXT
的调用必须是匹配和平衡的。
通过调用,可以将单个标记标签插入到命令缓冲区中
// Provided by VK_EXT_debug_marker
void vkCmdDebugMarkerInsertEXT(
VkCommandBuffer commandBuffer,
const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
pMarkerInfo
是指向 VkDebugMarkerMarkerInfoEXT 结构的指针,该结构指定要插入的标记的参数。
调试报告回调
调试报告回调由 VkDebugReportCallbackEXT
句柄表示
// Provided by VK_EXT_debug_report
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
当发生感兴趣的事件时,调试报告回调会提供有关应用程序使用 Vulkan 的更详细反馈。
要注册调试报告回调,应用程序使用 vkCreateDebugReportCallbackEXT。
// Provided by VK_EXT_debug_report
VkResult vkCreateDebugReportCallbackEXT(
VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDebugReportCallbackEXT* pCallback);
-
instance
是回调将记录在其上的实例。 -
pCreateInfo
是指向 VkDebugReportCallbackCreateInfoEXT 结构的指针,该结构定义了调用此回调的条件。 -
pAllocator
控制主机内存分配,如内存分配章节中所述。 -
pCallback
是指向 VkDebugReportCallbackEXT 句柄的指针,创建的对象将在该句柄中返回。
// Provided by VK_EXT_debug_report
typedef struct VkDebugReportCallbackCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDebugReportFlagsEXT flags;
PFN_vkDebugReportCallbackEXT pfnCallback;
void* pUserData;
} VkDebugReportCallbackCreateInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是 VkDebugReportFlagBitsEXT 的位掩码,指定哪些事件将导致调用此回调。 -
pfnCallback
是要调用的应用程序回调函数。 -
pUserData
是要传递给回调的用户数据。
对于创建的每个 VkDebugReportCallbackEXT
,VkDebugReportCallbackCreateInfoEXT
::flags
确定何时调用该 VkDebugReportCallbackCreateInfoEXT
::pfnCallback
。当发生事件时,实现将事件的 VkDebugReportFlagBitsEXT 标志与每个 VkDebugReportCallbackEXT
对象的标志进行按位与运算。对于每个非零结果,将调用相应的回调。回调将直接来自检测到事件的组件,除非其他层为了自己的目的(以不同的方式过滤它们,记录到系统错误日志等)拦截了调用。
如果创建了多个 VkDebugReportCallbackEXT
对象,应用程序可以接收多个回调。回调将始终在与发起 Vulkan 调用的线程相同的线程中执行。
回调可能会同时从多个线程调用(如果应用程序正在从多个线程进行 Vulkan 调用)。
可以在 VkDebugReportCallbackCreateInfoEXT::flags
中设置的位,用于指定导致调试报告的事件,包括
// Provided by VK_EXT_debug_report
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
指定应用程序违反了规范的有效使用条件。 -
VK_DEBUG_REPORT_WARNING_BIT_EXT
指定使用了 Vulkan,这可能会暴露应用程序错误。这种情况可能不会立即造成危害,例如片段着色器输出到没有附件的位置。其他情况可能指向当非预期时几乎肯定是错误的行为,例如使用内存尚未填充的图像。一般来说,如果您看到警告但您知道该行为是预期/期望的,那么只需忽略该警告即可。 -
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT
指定了 Vulkan 的一种可能非最优的使用方式,例如当设置 VkAttachmentDescription::loadOp
为VK_ATTACHMENT_LOAD_OP_CLEAR
时,使用 vkCmdClearColorImage 可能会导致性能问题。 -
VK_DEBUG_REPORT_INFORMATION_BIT_EXT
指定了一条信息性消息,例如在调试应用程序时可能很方便的资源详细信息。 -
VK_DEBUG_REPORT_DEBUG_BIT_EXT
指定了来自实现和层的诊断信息。
// Provided by VK_EXT_debug_report
typedef VkFlags VkDebugReportFlagsEXT;
VkDebugReportFlagsEXT
是一个位掩码类型,用于设置零个或多个 VkDebugReportFlagBitsEXT 的掩码。
应用程序实现的 VkDebugReportCallbackCreateInfoEXT::pfnCallback
函数的原型为:
// Provided by VK_EXT_debug_report
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
指定触发此回调的 VkDebugReportFlagBitsEXT。 -
objectType
是一个 VkDebugReportObjectTypeEXT 值,指定在事件触发时正在使用或创建的对象类型。 -
object
是检测到问题的对象。如果objectType
是VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT
,则object
是未定义的。 -
location
是一个由组件(层、驱动程序、加载器)定义的值,指定触发器的位置。这是一个可选值。 -
messageCode
是一个由层定义的值,指示触发此回调的测试。 -
pLayerPrefix
是一个以 null 结尾的 UTF-8 字符串,它是进行回调的组件名称的缩写。pLayerPrefix
仅在回调期间有效。 -
pMessage
是一个以 null 结尾的 UTF-8 字符串,详细说明触发条件。pMessage
仅在回调期间有效。 -
pUserData
是创建 VkDebugReportCallbackEXT 时给定的用户数据。
回调不得调用 vkDestroyDebugReportCallbackEXT
。
回调返回一个 VkBool32
,其解释方式由层指定。应用程序应该始终返回 VK_FALSE
。VK_TRUE
值保留用于层开发。
object
必须是一个 Vulkan 对象或 VK_NULL_HANDLE。如果 objectType
不是 VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT
并且 object
不是 VK_NULL_HANDLE,则 object
必须是与 VkDebugReportObjectTypeEXT 和 Vulkan 句柄关系中定义的 objectType
关联的相应类型的 Vulkan 对象。
传递给由 VkDebugReportCallbackCreateInfoEXT::pfnCallback
指定的回调函数的 objectType
参数的可能值,指定正在报告的对象句柄的类型,如下所示:
// Provided by VK_EXT_debug_marker, VK_EXT_debug_report
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_VALIDATION_CACHE_EXT_EXT = 33,
// Provided by VK_VERSION_1_1 with VK_EXT_debug_report, VK_KHR_sampler_ycbcr_conversion with VK_EXT_debug_report
VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000,
// Provided by VK_VERSION_1_1 with VK_EXT_debug_report
VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000,
// Provided by VK_EXT_debug_report with VK_NVX_binary_import
VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT = 1000029000,
// Provided by VK_EXT_debug_report with VK_NVX_binary_import
VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT = 1000029001,
// Provided by VK_KHR_acceleration_structure with VK_EXT_debug_report
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000150000,
// Provided by VK_EXT_debug_report with VK_NV_ray_tracing
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000,
// Provided by VK_EXT_debug_report with VK_NV_cuda_kernel_launch
VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_MODULE_NV_EXT = 1000307000,
// Provided by VK_EXT_debug_report with VK_NV_cuda_kernel_launch
VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_FUNCTION_NV_EXT = 1000307001,
// Provided by VK_EXT_debug_report with VK_FUCHSIA_buffer_collection
VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1000366000,
// VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT is a deprecated alias
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 is a deprecated alias
VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
// Provided by VK_KHR_descriptor_update_template with VK_EXT_debug_report
VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,
// Provided by VK_KHR_sampler_ycbcr_conversion with VK_EXT_debug_report
VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT,
} VkDebugReportObjectTypeEXT;
VkDebugReportObjectTypeEXT | Vulkan 句柄类型 |
---|---|
|
未知/未定义的句柄 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
要将自己的消息注入调试流,请调用
// Provided by VK_EXT_debug_report
void vkDebugReportMessageEXT(
VkInstance instance,
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage);
-
instance
是调试流的 VkInstance。 -
flags
指定此事件/消息的 VkDebugReportFlagBitsEXT 分类。 -
objectType
是一个 VkDebugReportObjectTypeEXT,指定在事件触发时正在使用或创建的对象类型。 -
object
是检测到问题的对象。如果事件没有关联对象,则object
可以是 VK_NULL_HANDLE。 -
location
是一个应用程序定义的值。 -
messageCode
是一个应用程序定义的值。 -
pLayerPrefix
是生成此事件/消息的组件的缩写。 -
pMessage
是一个以 null 结尾的 UTF-8 字符串,详细说明触发条件。
调用将通过各层传播,并根据消息的标志生成回调。这些参数将传递给回调,此外还有在注册回调时定义的 pUserData
值。
要销毁 VkDebugReportCallbackEXT
对象,请调用
// Provided by VK_EXT_debug_report
void vkDestroyDebugReportCallbackEXT(
VkInstance instance,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks* pAllocator);
-
instance
是创建回调的实例。 -
callback
是要销毁的 VkDebugReportCallbackEXT 对象。callback
是一个外部同步对象,必须不同时在多个线程上使用。这意味着当回调处于活动状态时,不得调用vkDestroyDebugReportCallbackEXT
。 -
pAllocator
控制主机内存分配,如内存分配章节中所述。
设备丢失调试
设备诊断检查点
可以通过用应用程序定义的诊断检查点注释命令流来跟踪设备执行进度,以用于调试设备丢失。
通过调用 vkCmdSetCheckpointNV 将设备诊断检查点插入到命令流中。
// Provided by VK_NV_device_diagnostic_checkpoints
void vkCmdSetCheckpointNV(
VkCommandBuffer commandBuffer,
const void* pCheckpointMarker);
-
commandBuffer
是将接收标记的命令缓冲区 -
pCheckpointMarker
是一个由应用程序提供的,与检查点关联的不透明值。
请注意,pCheckpointMarker
被视为不透明值。它不需要是一个有效的指针,并且不会被实现取消引用。
如果在执行期间设备遇到错误,实现将在主机执行期间的某个时刻向应用程序返回一个 VK_ERROR_DEVICE_LOST
错误。当发生这种情况时,应用程序可以调用 vkGetQueueCheckpointData2NV 来检索有关设备执行的最近诊断检查点的信息。
// Provided by VK_NV_device_diagnostic_checkpoints with VK_VERSION_1_3 or VK_KHR_synchronization2
void vkGetQueueCheckpointData2NV(
VkQueue queue,
uint32_t* pCheckpointDataCount,
VkCheckpointData2NV* pCheckpointData);
-
queue
是调用者想要检索检查点数据的 VkQueue 对象 -
pCheckpointDataCount
是一个指向与可用或查询的检查点标记数量相关的整数的指针,如下所述。 -
pCheckpointData
要么是NULL
,要么是指向VkCheckpointData2NV
结构数组的指针。
如果 pCheckpointData
是 NULL
,则在 pCheckpointDataCount
中返回可用的检查点标记的数量。否则,pCheckpointDataCount
必须指向一个由应用程序设置为 pCheckpointData
数组中元素数量的变量,并且在返回时,该变量将被实际写入 pCheckpointData
的结构数量覆盖。
如果 pCheckpointDataCount
小于可用检查点标记的数量,则最多写入 pCheckpointDataCount
个结构。
VkCheckpointData2NV 结构定义为
// Provided by VK_NV_device_diagnostic_checkpoints with VK_VERSION_1_3 or VK_KHR_synchronization2
typedef struct VkCheckpointData2NV {
VkStructureType sType;
void* pNext;
VkPipelineStageFlags2 stage;
void* pCheckpointMarker;
} VkCheckpointData2NV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
stage
指示检查点标记数据引用的单个管线阶段。 -
pCheckpointMarker
包含stage
引用的阶段中执行的最后一个检查点标记的值。
可以执行检查点标记的阶段是实现定义的,并且可以通过调用 vkGetPhysicalDeviceQueueFamilyProperties2 查询。
如果在执行期间设备遇到错误,实现将在主机执行期间的某个时刻向应用程序返回一个 VK_ERROR_DEVICE_LOST
错误。当发生这种情况时,应用程序可以调用 vkGetQueueCheckpointDataNV 来检索有关设备执行的最近诊断检查点的信息。
// Provided by VK_NV_device_diagnostic_checkpoints
void vkGetQueueCheckpointDataNV(
VkQueue queue,
uint32_t* pCheckpointDataCount,
VkCheckpointDataNV* pCheckpointData);
-
queue
是调用者想要检索检查点数据的 VkQueue 对象 -
pCheckpointDataCount
是一个指向与可用或查询的检查点标记数量相关的整数的指针,如下所述。 -
pCheckpointData
要么是NULL
,要么是指向VkCheckpointDataNV
结构数组的指针。
如果 pCheckpointData
是 NULL
,则在 pCheckpointDataCount
中返回可用的检查点标记的数量。
否则,pCheckpointDataCount
必须指向一个由应用程序设置为 pCheckpointData
数组中元素数量的变量,并且在返回时,该变量将被实际写入 pCheckpointData
的结构数量覆盖。
如果 pCheckpointDataCount
小于可用检查点标记的数量,则最多写入 pCheckpointDataCount
个结构。
VkCheckpointDataNV 结构定义为
// Provided by VK_NV_device_diagnostic_checkpoints
typedef struct VkCheckpointDataNV {
VkStructureType sType;
void* pNext;
VkPipelineStageFlagBits stage;
void* pCheckpointMarker;
} VkCheckpointDataNV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
stage
是一个VkPipelineStageFlagBits
值,指定检查点标记数据引用的管线阶段。 -
pCheckpointMarker
包含stage
引用的阶段中执行的最后一个检查点标记的值。
可以执行检查点标记的阶段是实现定义的,并且可以通过调用 vkGetPhysicalDeviceQueueFamilyProperties2 查询。
设备故障诊断
要检索有关可能导致设备丢失的故障的诊断信息,请调用
// Provided by VK_EXT_device_fault
VkResult vkGetDeviceFaultInfoEXT(
VkDevice device,
VkDeviceFaultCountsEXT* pFaultCounts,
VkDeviceFaultInfoEXT* pFaultInfo);
-
device
是要从中查询诊断故障信息的逻辑设备。 -
pFaultCounts
是指向 VkDeviceFaultCountsEXT 结构的指针,其中返回描述附加故障信息的结构计数。 -
pFaultInfo
是NULL
或指向 VkDeviceFaultInfoEXT 结构的指针,其中返回故障信息。
如果 pFaultInfo
是 NULL
,则在 pFaultCounts
的 addressInfoCount
和 vendorInfoCount
成员中返回相应的附加故障信息结构的计数。此外,任何供应商特定的二进制崩溃转储的大小都将在 pFaultCounts
的 vendorBinarySize
成员中返回。
如果 pFaultInfo
不是 NULL
,则 pFaultCounts
必须 指向一个 VkDeviceFaultCountsEXT 结构体,其中每个结构体的计数或大小成员(addressInfoCount
、vendorInfoCount
、vendorBinarySize
)由应用程序设置为 pFaultInfo
的相应输出数组成员(pAddressInfos
和 pVendorInfos
)中的元素数量,或者设置为输出缓冲区的大小(以字节为单位,即 pVendorBinaryData
)。返回时,每个结构体的计数成员将被实际写入 pFaultInfo
的相应输出数组成员的结构体数量覆盖。类似地,vendorBinarySize
将被实际写入 pFaultInfo
的 pVendorBinaryData
成员的字节数覆盖。
如果供应商特定的崩溃转储功能未启用,则实现必须将 pFaultCounts
->vendorBinarySize
设置为零,并且必须不修改 pFaultInfo
->pVendorBinaryData
。
如果任何 pFaultCounts
结构体的计数成员小于可用的相应故障属性的数量,则最多会将结构体计数 (addressInfoCount
, vendorInfoCount
) 个元素写入关联的 pFaultInfo
输出数组。类似地,如果 vendorBinarySize
小于可用崩溃转储数据的大小(以字节为单位),则最多会将 vendorBinarySize
个元素写入 pVendorBinaryData
。
如果 pFaultInfo
为 NULL
,则后续对同一个 device
调用 vkGetDeviceFaultInfoEXT 时,pFaultCounts
的 addressInfoCount
、vendorInfoCount
和 vendorBinarySize
成员必须返回相同的值。
如果 pFaultInfo
不为 NULL
,则后续对同一个 device
调用 vkGetDeviceFaultInfoEXT 时,pFaultInfo
的输出成员(pAddressInfos
、pVendorInfos
、pVendorBinaryData
)必须返回相同的值,直到 pFaultCounts
的结构体计数和缓冲区大小成员(addressInfoCount
、vendorInfoCount
、vendorBinarySize
)所描述的限制。如果后续调用 vkGetDeviceFaultInfoEXT 时 pFaultInfo
的输出成员的大小增加,则可能会在额外的可用空间中返回补充信息。
如果任何 pFaultCounts
结构体的计数成员小于可用的相应故障属性的数量,或者如果 pFaultCounts
->vendorBinarySize
小于生成的二进制崩溃转储数据的大小(以字节为单位),则会返回 VK_INCOMPLETE
而不是 VK_SUCCESS
,以指示并非所有可用的属性都被返回。
如果 pFaultCounts
->vendorBinarySize
小于存储二进制崩溃转储头部所需的大小,则不会写入任何内容到 pFaultInfo
->pVendorBinaryData
,并且将零写入 pFaultCounts
->vendorBinarySize
。
VkDeviceFaultCountsEXT
结构体定义为:
// Provided by VK_EXT_device_fault
typedef struct VkDeviceFaultCountsEXT {
VkStructureType sType;
void* pNext;
uint32_t addressInfoCount;
uint32_t vendorInfoCount;
VkDeviceSize vendorBinarySize;
} VkDeviceFaultCountsEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
addressInfoCount
是描述可能导致页面错误的内存访问,或者在发生错误时活动指令的地址的 VkDeviceFaultAddressInfoEXT 结构体的数量。 -
vendorInfoCount
是描述供应商特定故障信息的 VkDeviceFaultVendorInfoEXT 结构体的数量。 -
vendorBinarySize
是供应商特定的二进制崩溃转储的大小(以字节为单位),当导入到外部工具时,可能会提供额外的信息。
VkDeviceFaultInfoEXT
结构体定义为:
// Provided by VK_EXT_device_fault
typedef struct VkDeviceFaultInfoEXT {
VkStructureType sType;
void* pNext;
char description[VK_MAX_DESCRIPTION_SIZE];
VkDeviceFaultAddressInfoEXT* pAddressInfos;
VkDeviceFaultVendorInfoEXT* pVendorInfos;
void* pVendorBinaryData;
} VkDeviceFaultInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
description
是一个char
类型的数组,大小为VK_MAX_DESCRIPTION_SIZE
,其中包含以 null 结尾的 UTF-8 字符串,该字符串是人类可读的故障描述。 -
pAddressInfos
是NULL
或指向 VkDeviceFaultAddressInfoEXT 结构体数组的指针,该数组描述了可能导致页面错误的内存访问,或者描述了发生错误时的活动指令指针。如果不是NULL
,则pAddressInfos
的每个元素都描述了 GPU 虚拟地址空间的一个有界区域,其中包含被访问的 GPU 虚拟地址或活动指令指针的值。 -
pVendorInfos
是NULL
或指向 VkDeviceFaultVendorInfoEXT 结构体数组的指针,该数组描述了供应商特定的故障信息。 -
pVendorBinaryData
是NULL
或指向vendorBinarySize
个字节的数据的指针,该数据将填充供应商特定的二进制崩溃转储,如 供应商二进制崩溃转储 中所述。
在给定故障发生时可用的信息和实现本身的约束条件下,实现应该尽可能填充 VkDeviceFaultInfoEXT 的多个成员。
由于硬件限制,pAddressInfos
描述的是 GPU 虚拟地址空间的范围,而不是精确的地址。访问的精确内存地址或指令指针的精确值必须位于所描述的区域内。
将 |
VkDeviceFaultAddressInfoEXT
结构的定义如下:
// Provided by VK_EXT_device_fault
typedef struct VkDeviceFaultAddressInfoEXT {
VkDeviceFaultAddressTypeEXT addressType;
VkDeviceAddress reportedAddress;
VkDeviceSize addressPrecision;
} VkDeviceFaultAddressInfoEXT;
-
addressType
是触发页面错误的内存操作类型,或是指令指针与错误之间关联的类型。 -
reportedAddress
是设备记录的 GPU 虚拟地址。 -
addressPrecision
是 2 的幂值,指定设备报告地址的精确程度。
reportedAddress
和 addressPrecision
的组合允许计算可能的地址范围,使得:
lower_address = (pInfo->reportedAddress & ~(pInfo->addressPrecision-1))
upper_address = (pInfo->reportedAddress | (pInfo->addressPrecision-1))
|
VkDeviceFaultAddressInfoEXT::addressType
的可能值为:
// Provided by VK_EXT_device_fault
typedef enum VkDeviceFaultAddressTypeEXT {
VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT = 0,
VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT = 1,
VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT = 2,
VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT = 3,
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT = 4,
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT = 5,
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT = 6,
} VkDeviceFaultAddressTypeEXT;
-
VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT
指定 VkDeviceFaultAddressInfoEXT 不描述页面错误或指令地址。 -
VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT
指定 VkDeviceFaultAddressInfoEXT 描述由无效的读取操作触发的页面错误。 -
VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT
指定 VkDeviceFaultAddressInfoEXT 描述由无效的写入操作触发的页面错误。 -
VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT
描述试图执行不可执行内存而触发的页面错误。 -
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT
指定发生错误时的指令指针值。这可能与错误有关,也可能无关。 -
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT
指定与无效指令错误相关的指令指针值。 -
VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT
指定与错误关联的指令指针值。
记录的指令指针值可能无法识别触发错误的特定指令。报告的指令指针和触发指令之间的关系将是特定于供应商的。 |
VkDeviceFaultVendorInfoEXT
结构的定义如下:
// Provided by VK_EXT_device_fault
typedef struct VkDeviceFaultVendorInfoEXT {
char description[VK_MAX_DESCRIPTION_SIZE];
uint64_t vendorFaultCode;
uint64_t vendorFaultData;
} VkDeviceFaultVendorInfoEXT;
-
description
是一个char
类型的数组,大小为VK_MAX_DESCRIPTION_SIZE
,其中包含以 null 结尾的 UTF-8 字符串,该字符串是人类可读的故障描述。 -
vendorFaultCode
是此错误的供应商特定错误代码。 -
vendorFaultData
是与此错误关联的供应商特定错误数据。
供应商二进制崩溃转储
应用程序可以存储调用 vkGetDeviceFaultInfoEXT 获取的供应商特定二进制崩溃转储数据,以便以后使用外部工具进行分析。
但是,此数据的格式可能取决于供应商 ID、设备 ID、驱动程序版本以及设备的其它详细信息。为了使外部应用程序能够识别生成崩溃转储的原始设备,写入 VkDeviceFaultInfoEXT
::pVendorBinaryData
的初始字节必须以有效的崩溃转储标头开始。
崩溃转储标头的第一版本定义如下:
// Provided by VK_EXT_device_fault
typedef struct VkDeviceFaultVendorBinaryHeaderVersionOneEXT {
uint32_t headerSize;
VkDeviceFaultVendorBinaryHeaderVersionEXT headerVersion;
uint32_t vendorID;
uint32_t deviceID;
uint32_t driverVersion;
uint8_t pipelineCacheUUID[VK_UUID_SIZE];
uint32_t applicationNameOffset;
uint32_t applicationVersion;
uint32_t engineNameOffset;
uint32_t engineVersion;
uint32_t apiVersion;
} VkDeviceFaultVendorBinaryHeaderVersionOneEXT;
-
headerSize
是崩溃转储标头的长度(以字节为单位)。 -
headerVersion
是一个 VkDeviceFaultVendorBinaryHeaderVersionEXT 枚举值,指定标头的版本。崩溃转储的使用者应该使用标头版本来解释标头的其余部分。 -
vendorID
是实现的VkPhysicalDeviceProperties
::vendorID
。 -
deviceID
是实现的VkPhysicalDeviceProperties
::deviceID
。 -
driverVersion
是实现的VkPhysicalDeviceProperties
::driverVersion
。 -
pipelineCacheUUID
是与实现的VkPhysicalDeviceProperties
::pipelineCacheUUID
属性匹配的VK_UUID_SIZE
uint8_t
值数组。 -
applicationNameOffset
为零,或从崩溃转储标头的基址到包含应用程序名称的以 null 结尾的 UTF-8 字符串的偏移量。如果applicationNameOffset
非零,则此字符串必须与实例创建期间通过 VkApplicationInfo::pApplicationName
指定的应用程序名称匹配。 -
applicationVersion
必须为零或在实例创建期间由 VkApplicationInfo::applicationVersion
指定的值。 -
engineNameOffset
为零,或从崩溃转储标头的基址到包含用于创建应用程序的引擎名称(如果有)的以 null 结尾的 UTF-8 字符串的偏移量。如果engineNameOffset
非零,则此字符串必须与实例创建期间通过 VkApplicationInfo::pEngineName
指定的引擎名称匹配。 -
engineVersion
必须为零或在实例创建期间由 VkApplicationInfo::engineVersion
指定的值。 -
apiVersion
必须为零或在实例创建期间由 VkApplicationInfo::apiVersion
指定的值。
与 Vulkan API 声明的大多数结构不同,此结构的所有字段都以最低有效字节优先写入,而不管主机字节顺序如何。
C 语言规范未定义结构成员的打包方式。此布局假定紧凑的结构成员打包,成员按照结构中列出的顺序布局,并且结构的预期大小为 56 字节。如果编译器生成偏离该模式的代码,则应用程序必须采用其他方法在正确的偏移量处设置值。
崩溃转储标头的 headerVersion
值的可能值为:
// Provided by VK_EXT_device_fault
typedef enum VkDeviceFaultVendorBinaryHeaderVersionEXT {
VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT = 1,
} VkDeviceFaultVendorBinaryHeaderVersionEXT;
-
VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT
指定二进制崩溃转储标头的第一版本。
活动工具信息
可以通过调用以下命令获取关于为给定物理设备提供调试、分析或类似服务的工具的信息:
// Provided by VK_VERSION_1_3
VkResult vkGetPhysicalDeviceToolProperties(
VkPhysicalDevice physicalDevice,
uint32_t* pToolCount,
VkPhysicalDeviceToolProperties* pToolProperties);
或等效命令:
// Provided by VK_EXT_tooling_info
VkResult vkGetPhysicalDeviceToolPropertiesEXT(
VkPhysicalDevice physicalDevice,
uint32_t* pToolCount,
VkPhysicalDeviceToolProperties* pToolProperties);
-
physicalDevice
是要查询活动工具的物理设备的句柄。 -
pToolCount
是指向描述physicalDevice
上活动工具数量的整数的指针。 -
pToolProperties
可以是NULL
,也可以是指向 VkPhysicalDeviceToolProperties 结构数组的指针。
如果 pToolProperties
为 NULL
,则 physicalDevice
上当前活动工具的数量将在 pToolCount
中返回。否则,pToolCount
必须指向一个由应用程序设置为 pToolProperties
数组中元素数量的变量,并且在返回时,该变量将被实际写入 pToolProperties
的结构数量覆盖。如果 pToolCount
小于当前活动工具的数量,则最多写入 pToolCount
个结构。
活动工具的计数和属性可能会响应规范范围之外的事件而更改。应用程序应该假定这些属性可能在任何给定时间更改。
VkPhysicalDeviceToolProperties 结构体定义如下:
// Provided by VK_VERSION_1_3
typedef struct VkPhysicalDeviceToolProperties {
VkStructureType sType;
void* pNext;
char name[VK_MAX_EXTENSION_NAME_SIZE];
char version[VK_MAX_EXTENSION_NAME_SIZE];
VkToolPurposeFlags purposes;
char description[VK_MAX_DESCRIPTION_SIZE];
char layer[VK_MAX_EXTENSION_NAME_SIZE];
} VkPhysicalDeviceToolProperties;
或者等效于:
// Provided by VK_EXT_tooling_info
typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
name
是一个以 null 结尾的 UTF-8 字符串,包含工具的名称。 -
version
是一个以 null 结尾的 UTF-8 字符串,包含工具的版本。 -
purposes
是一个 VkToolPurposeFlagBits 的位掩码,其中填充了工具支持的目的。 -
description
是一个以 null 结尾的 UTF-8 字符串,包含工具的描述。 -
layer
是一个以 null 结尾的 UTF-8 字符串,包含实现工具的层的名称,如果工具在层中实现 - 否则它可能是一个空字符串。
在 VkPhysicalDeviceToolProperties::purposes
中可以设置的位,用于指定活动工具的目的,包括:
// Provided by VK_VERSION_1_3
typedef enum VkToolPurposeFlagBits {
VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001,
VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002,
VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004,
VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008,
VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010,
// Provided by VK_EXT_debug_report with VK_EXT_tooling_info, VK_EXT_debug_utils with VK_EXT_tooling_info
VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020,
// Provided by VK_EXT_debug_marker with VK_EXT_tooling_info, VK_EXT_debug_utils with VK_EXT_tooling_info
VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040,
// Provided by VK_EXT_tooling_info
VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT,
// Provided by VK_EXT_tooling_info
VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT,
// Provided by VK_EXT_tooling_info
VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT,
// Provided by VK_EXT_tooling_info
VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT,
// Provided by VK_EXT_tooling_info
VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT,
} VkToolPurposeFlagBits;
或者等效于:
// Provided by VK_EXT_tooling_info
typedef VkToolPurposeFlagBits VkToolPurposeFlagBitsEXT;
-
VK_TOOL_PURPOSE_VALIDATION_BIT
指定该工具提供 API 使用的验证。 -
VK_TOOL_PURPOSE_PROFILING_BIT
指定该工具提供 API 使用的性能分析。 -
VK_TOOL_PURPOSE_TRACING_BIT
指定该工具正在捕获有关应用程序 API 使用情况的数据,包括从简单日志记录到捕获数据以便稍后重放的任何内容。 -
VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT
指定该工具在底层实现之上提供额外的 API 功能/扩展。 -
VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT
指定该工具修改呈现给应用程序的 API 功能/限制/扩展。 -
VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT
指定该工具通过 vkCreateDebugReportCallbackEXT 或 vkCreateDebugUtilsMessengerEXT 指定的回调向应用程序报告其他信息 -
VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT
指定该工具使用 调试标记或对象调试注释、队列标签或命令缓冲区标签
// Provided by VK_VERSION_1_3
typedef VkFlags VkToolPurposeFlags;
或者等效于:
// Provided by VK_EXT_tooling_info
typedef VkToolPurposeFlags VkToolPurposeFlagsEXT;
VkToolPurposeFlags 是一种位掩码类型,用于设置零个或多个 VkToolPurposeFlagBits 的掩码。
帧边界
VkFrameBoundaryEXT
结构体定义如下:
// Provided by VK_EXT_frame_boundary
typedef struct VkFrameBoundaryEXT {
VkStructureType sType;
const void* pNext;
VkFrameBoundaryFlagsEXT flags;
uint64_t frameID;
uint32_t imageCount;
const VkImage* pImages;
uint32_t bufferCount;
const VkBuffer* pBuffers;
uint64_t tagName;
size_t tagSize;
const void* pTag;
} VkFrameBoundaryEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
为NULL
或指向扩展此结构的结构的指针。 -
flags
是一个 VkFrameBoundaryFlagBitsEXT 的位掩码,可以标记帧标识符的最后一次提交。 -
frameID
是帧标识符。 -
imageCount
是存储帧结果的图像数量。 -
pImages
是指向具有 imageCount 个条目的 VkImage 对象数组的指针。 -
bufferCount
是存储帧结果的缓冲区数量。 -
pBuffers
是指向具有 bufferCount 个条目的 VkBuffer 对象数组的指针。 -
tagName
是标签数据的数字标识符。 -
tagSize
是标签数据的字节数。 -
pTag
是指向包含标签数据的tagSize
字节数组的指针。
应用程序可以通过将 VkFrameBoundaryEXT
结构添加到 队列提交、VkPresentInfoKHR 或 VkBindSparseInfo 的 pNext
链中,将帧边界信息与队列提交调用关联起来。
帧标识符用于将一个或多个队列提交与帧关联起来。它旨在在帧生命周期内是唯一的,即可以(尽管不建议)重用帧标识符,只要任何两个可能具有重叠队列提交的帧(如上面的示例所示)使用不同的帧标识符。 由于帧的概念取决于应用程序,因此无法验证帧标识符的使用。 良好的做法是使用单调递增的计数器作为帧标识符,并且不要在帧之间重用标识符。 |
pImages
和 pBuffers
数组包含存储帧“最终结果”的图像和缓冲区列表。由于帧的概念取决于应用程序,并非所有帧可能会在图像或缓冲区中产生其结果,但这是 VkFrameBoundaryEXT
要处理的一个足够常见的用例。 请注意,由于图像旨在由已经跟踪此必需信息的工具使用,因此不提供额外的信息(例如图像布局)。 有可能传递最终结果图像列表,使得 VkFrameBoundaryEXT
与 vkQueuePresentKHR 一样具有表达能力,后者通常是默认的帧边界分隔符。
应用程序可以通过使用 tagName
、tagSize
和 pTag
通过标签数据关联任意额外的额外信息。 此额外信息通常是特定于工具的。
在 VkFrameBoundaryEXT::flags
中可以设置的位是
// Provided by VK_EXT_frame_boundary
typedef enum VkFrameBoundaryFlagBitsEXT {
VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT = 0x00000001,
} VkFrameBoundaryFlagBitsEXT;
-
VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT
指定此队列提交是此帧的最后一个提交,即一旦此队列提交终止,则此帧的工作就完成了。
请注意,在存在时间线信号量的情况下,最后一个队列提交可能不是最后一个被提交的,因为时间线信号量允许先等待后发送信号的提交。在帧边界的上下文中,应该标记为最后一个的队列提交是计划最后执行的提交,即使它可能不是最后一个被提交的。
// Provided by VK_EXT_frame_boundary
typedef VkFlags VkFrameBoundaryFlagsEXT;
VkFrameBoundaryFlagsEXT 是一个位掩码类型,用于设置零个或多个 VkFrameBoundaryFlagBitsEXT 的掩码。