在Vulkan API 1.2环境下如何启用Synchronization 2特性?
之前在开发机上使用Vulkan API 1.3.201,已将Synchronization 2作为核心特性正常使用。现在为兼容更多设备,切换到API 1.2版本,设置appInfo.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0):
- 创建实例时传入了
VK_KHR_surface等扩展和VK_LAYER_KHRONOS_synchronization2层 - 创建设备时传入
VK_KHR_synchronization2等扩展及VK_LAYER_KHRONOS_validation层 - 设备初始化时设置了
VkPhysicalDeviceVulkan12Features::timelineSemaphore = true
但调用vkCmdPipelineBarrier2KHR时出现验证错误:
Validation Error: [ VUID-vkCmdPipelineBarrier2-synchronization2-03848 ] Object 0: handle = 0x20b77c136f0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xa060404 | vkCmdPipelineBarrier2KHR(): Synchronization2 feature is not enabled The Vulkan spec states: The synchronization2 feature must be enabled
1. 启用VK_KHR_synchronization2对应的设备特性
在Vulkan 1.2中,Synchronization 2并非核心特性,而是以VK_KHR_synchronization2扩展的形式存在。你需要单独获取并启用该扩展对应的特性结构体:
// 初始化Synchronization 2特性结构体 VkPhysicalDeviceSynchronization2FeaturesKHR sync2Features = {}; sync2Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR; sync2Features.synchronization2 = VK_TRUE; // 将该结构体链入设备创建信息的pNext链中 VkDeviceCreateInfo deviceCreateInfo = {}; deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; // ... 填充其他设备创建参数(如队列族、扩展列表等) ... deviceCreateInfo.pNext = &sync2Features; // 创建设备 VkResult result = vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
2. 确保创建设备时已启用VK_KHR_synchronization2扩展
创建设备时的扩展列表必须包含VK_KHR_synchronization2,否则即使设置了特性结构体也无法生效:
const char* deviceExtensions[] = { VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, // ... 其他需要的设备扩展 ... }; VkDeviceCreateInfo deviceCreateInfo = {}; // ... 其他设置 ... deviceCreateInfo.enabledExtensionCount = sizeof(deviceExtensions) / sizeof(deviceExtensions[0]); deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions;
3. 明确核心特性与扩展特性的区别
你之前设置的VkPhysicalDeviceVulkan12Features::timelineSemaphore是Vulkan 1.2的核心特性,和Synchronization 2扩展是两个独立的特性。Timeline信号量是Synchronization 2的依赖项,但启用它并不等同于启用Synchronization 2扩展,必须单独配置后者。
4. 实例层的作用说明
VK_LAYER_KHRONOS_synchronization2层仅用于验证或模拟Synchronization 2的行为,不能替代设备层面的特性启用。它的作用是在不支持该扩展的设备上帮助调试,但实际运行时必须依赖设备本身的扩展支持。
内容的提问来源于stack exchange,提问作者Elad Maimoni

