Rust Ash(Vulkan):如何测试结构体调试名及验证逻辑设备命名?
在Rust Ash(Vulkan)中测试结构体调试名称及验证名称的方法
一、测试结构体的调试名称
Vulkan本身没有提供直接读取对象调试名称的API,通常通过两种方式验证名称是否设置成功:
1. 主动记录名称,在代码中直接校验
设置调试名称时,自己维护一个对象与名称的映射表,后续需要验证时直接对比:
use ash::vk; use std::collections::HashMap; // 维护对象名称映射(可全局或局部存储) let mut object_names = HashMap::new(); let device_handle = device.handle(); let target_name = "MyLogicalDevice"; // 构造名称设置信息 let name_info = vk::DebugUtilsObjectNameInfoEXT { s_type: vk::StructureType::DEBUG_UTILS_OBJECT_NAME_INFO_EXT, object_type: vk::ObjectType::DEVICE, object_handle: device_handle as u64, p_object_name: target_name.as_ptr(), ..Default::default() }; // 调用API设置名称 unsafe { debug_utils.debug_utils_set_object_name(device.handle(), &name_info).unwrap(); } // 将名称存入映射表 object_names.insert((vk::ObjectType::DEVICE, device_handle), target_name.to_string()); // 测试阶段校验名称是否匹配 assert_eq!(object_names.get(&(vk::ObjectType::DEVICE, device_handle)), Some(&target_name.to_string()));
2. 通过调试回调捕获名称信息
注册调试回调,开启VK_LAYER_KHRONOS_validation验证层后,当对象被创建或名称修改时,验证层会发送包含对象名称的消息,可在回调中校验:
// 调试回调函数,用于捕获验证层消息 extern "system" fn debug_callback( _severity: vk::DebugUtilsMessageSeverityFlagsEXT, msg_type: vk::DebugUtilsMessageTypeFlagsEXT, p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT, _user_data: *mut std::os::raw::c_void, ) -> vk::Bool32 { let callback_data = unsafe { *p_callback_data }; let message = unsafe { std::ffi::CStr::from_ptr(callback_data.p_message) }.to_str().unwrap(); // 捕获对象创建类消息,提取名称校验 if msg_type.contains(vk::DebugUtilsMessageTypeFlagsEXT::OBJECT_CREATED) { if let Some(name_ptr) = callback_data.p_object_name { let obj_name = unsafe { std::ffi::CStr::from_ptr(name_ptr) }.to_str().unwrap(); // 这里可添加断言逻辑,验证名称是否符合预期 println!("Created object with name: {}", obj_name); } } vk::FALSE } // 注册调试回调 let messenger_info = vk::DebugUtilsMessengerCreateInfoEXT { s_type: vk::StructureType::DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, message_severity: vk::DebugUtilsMessageSeverityFlagsEXT::VERBOSE | vk::DebugUtilsMessageSeverityFlagsEXT::WARNING | vk::DebugUtilsMessageSeverityFlagsEXT::ERROR, message_type: vk::DebugUtilsMessageTypeFlagsEXT::ALL, pfn_user_callback: Some(debug_callback), ..Default::default() }; let _messenger = unsafe { debug_utils.create_debug_utils_messenger(&messenger_info, None).unwrap() };
二、触发包含逻辑设备名称的验证消息
若已给逻辑设备设置调试名称,只需故意触发一个关联该设备的验证错误,验证层输出的消息就会包含设备名称。例如:
示例:创建参数非法的缓冲区触发验证错误
// 构造非法的缓冲区创建信息(大小设为0,违反Vulkan规范) let invalid_buffer_info = vk::BufferCreateInfo { s_type: vk::StructureType::BUFFER_CREATE_INFO, size: 0, // 非法值,会触发验证错误 usage: vk::BufferUsageFlags::VERTEX_BUFFER, sharing_mode: vk::SharingMode::EXCLUSIVE, ..Default::default() }; // 使用已命名的逻辑设备尝试创建缓冲区 unsafe { match device.create_buffer(&invalid_buffer_info, None) { Err(e) => println!("验证错误输出: {}", e), Ok(_) => (), } }
触发后,验证层的错误消息会类似:
VUID-vkCreateBuffer-size-00064(ERROR / SPEC): msgNum: 1290194433 - vkCreateBuffer: size must be greater than 0. The Vulkan spec states: size must be greater than 0
Objects: 1
[0] 0x1234567890abcdef, type: VK_OBJECT_TYPE_DEVICE, name: MyLogicalDevice
此时就能看到逻辑设备的名称MyLogicalDevice出现在消息中,验证名称设置符合预期。
内容的提问来源于stack exchange,提问作者Makogan
相关产品推荐
相关产品推荐

