Search code examples
vulkan

Vulkan - How to enable Synchronization 2 feature?


I am trying to use Vulkan Synchronization2 feature. However, even though I enable it (correctly as far as I can tell), the validation layer reports an error when trying to use vkCmdPipelineBarrier2:

Validation Error: [ VUID-vkCmdPipelineBarrier2-synchronization2-03848 ] Object 0: handle = 0x258b5ee3dc0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xa060404 | vkCmdPipelineBarrier2(): Synchronization2 feature is not enabled The Vulkan spec states: The synchronization2 feature must be enabled (https://vulkan.lunarg.com/doc/view/1.3.211.0/windows/1.3-extensions/vkspec.html#VUID-vkCmdPipelineBarrier2-synchronization2-03848)

Here is my instance creation code:

    DEBUGGER_TRACE("Requested instance layers = {}", desc.required_layers);
    DEBUGGER_TRACE("Requested instance extenstions = {}", desc.required_instance_extentions);

    vk::InstanceCreateInfo createInfo{
        .flags = vk::InstanceCreateFlags(),
        .pApplicationInfo = &appInfo,
        .enabledLayerCount = static_cast<uint32_t>(desc.required_layers.size()),
        .ppEnabledLayerNames = desc.required_layers.data(), // enabled layers
        .enabledExtensionCount = static_cast<uint32_t>(desc.required_instance_extentions.size()),
        .ppEnabledExtensionNames = desc.required_instance_extentions.data()
    };

    return std::make_pair(vkr::Instance(context, createInfo), version);

And my device creation code:

    DEBUGGER_TRACE("Requested device layers = {}", desc.required_layers);
    DEBUGGER_TRACE("Requested device extentions = {}", desc.required_extentions);


    vk::DeviceCreateInfo deviceInfo{
        .pNext = &features,
        .flags = vk::DeviceCreateFlags(),
        .queueCreateInfoCount = static_cast<uint32_t>(deviceCreationDesc.create_info.size()),
        .pQueueCreateInfos = deviceCreationDesc.create_info.data(),
        .enabledLayerCount = static_cast<uint32_t>(desc.required_layers.size()),
        .ppEnabledLayerNames = desc.required_layers.data(),
        .enabledExtensionCount = static_cast<uint32_t>(desc.required_extentions.size()),
        .ppEnabledExtensionNames = desc.required_extentions.data(),
        .pEnabledFeatures = &deviceFeatures
    };

    _device = std::make_shared<vkr::Device>(*chosenPhysicalDevice, deviceInfo);

My debug traces print the following:

Requested instance layers =
{VK_LAYER_KHRONOS_validation,VK_LAYER_KHRONOS_synchronization2}

Requested instance extensions =
{VK_KHR_surface,VK_KHR_win32_surface,VK_EXT_debug_utils} 

Requested device layers =
{VK_LAYER_KHRONOS_validation,VK_LAYER_KHRONOS_synchronization2}

Requested device extentions =
{VK_KHR_swapchain,VK_KHR_synchronization2}

When using the Vulkan Configurator, I can Force Enable synchronization 2 and everything works just fine.

So what could be wrong? How to enable synchronization 2?


Solution

  • Synchronization 2 is a set of functionality exposed in two ways. It was originally introduced as a KHR extension to Vulkan 1.0. It was adopted as a core feature for Vulkan 1.3. And while these are largely the same (I have no idea if they're actually identical)... they're still exposed in two separate ways, with two different sets of named functions.

    You requested the extension, but you tried to use the core feature... which you did not request. You need to be consistent: if you want to code against the core feature, you must ask for it as a feature, not an extension.