Vulkan 验证层抱怨未启用扩展,代码就像启用了扩展一样工作

Vulkan validation layers complain about extension not enabled, code works as if extension was enabled

我正在尝试使用动态呈现扩展,为此我正在以这种方式初始化我的实例:

    auto enabled = vk::ValidationFeatureEnableEXT::eBestPractices;
    vk::ValidationFeaturesEXT features;
    features.enabledValidationFeatureCount = 1;
    features.pEnabledValidationFeatures = &enabled;

    vk::PhysicalDeviceDynamicRenderingFeaturesKHR dynamic_rendering = {};
    dynamic_rendering.dynamicRendering = true;

    features.pNext = &dynamic_rendering;

    // Setup general information about the current application.
    vk::ApplicationInfo program_info(
        "NeverEngine",
        VK_MAKE_VERSION(1, 0, 0),
        "No Engine",
        VK_MAKE_VERSION(1, 0, 0),
        VK_API_VERSION_1_2);
    // Create Vulkan instance to communicate with the loader.
    vk::InstanceCreateInfo create_info = {};
    create_info.pNext = &features;
    create_info.pApplicationInfo = &program_info,
    create_info.enabledLayerCount = static_cast<uint32_t>(VALIDATION_LAYERS.size()),
    create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data(),
    create_info.enabledExtensionCount = static_cast<uint32_t>(required_extensions.size()),
    create_info.ppEnabledExtensionNames = required_extensions.data();

    auto [result, instance] = vk::createInstanceUnique(create_info);
    Assert(result == vk::Result::eSuccess, "Error: Failed to create instance");

但是我收到了这些错误:

VUID-VkInstanceCreateInfo-pNext-pNext(ERROR / SPEC): msgNum: -1337267667 - Validation Error: [ VUID-VkInstanceCreateInfo-pNext-pNext ] Object 0: VK_NULL_HANDLE, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xb04aea2d | vkCreateInstance: pCreateInfo->pNext chain includes a structure with unexpected VkStructureType VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES; Allowed structures are [VkDebugReportCallbackCreateInfoEXT, VkDebugUtilsMessengerCreateInfoEXT, VkValidationFeaturesEXT, VkValidationFlagsEXT]. This error is based on the Valid Usage documentation for version 204 of the Vulkan header.  It is possible that you are using a struct from a private extension or an extension that was added to a later version of the Vulkan header, in which case the use of pCreateInfo->pNext is undefined and may not work correctly with validation enabled The Vulkan spec states: Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkDebugReportCallbackCreateInfoEXT, VkDebugUtilsMessengerCreateInfoEXT, VkValidationFeaturesEXT, or VkValidationFlagsEXT (https://vulkan.lunarg.com/doc/view/1.3.204.1/linux/1.3-extensions/vkspec.html#VUID-VkInstanceCreateInfo-pNext-pNext)
    Objects: 1
        [0] 0, type: 3, name: NULL
VUID-VkInstanceCreateInfo-pNext-pNext(ERROR / SPEC): msgNum: -1337267667 - Validation Error: [ VUID-VkInstanceCreateInfo-pNext-pNext ] Object 0: VK_NULL_HANDLE, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0xb04aea2d | vkCreateInstance: Includes a pNext pointer (pCreateInfo->pNext) to a VkStructureType (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES), but its parent extension VK_KHR_dynamic_rendering has not been enabled. The Vulkan spec states: Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkDebugReportCallbackCreateInfoEXT, VkDebugUtilsMessengerCreateInfoEXT, VkValidationFeaturesEXT, or VkValidationFlagsEXT (https://vulkan.lunarg.com/doc/view/1.3.204.1/linux/1.3-extensions/vkspec.html#VUID-VkInstanceCreateInfo-pNext-pNext)
    Objects: 1
        [0] 0, type: 1, name: NULL

我的driver、headers和验证层都是最新版本1.3.204

如果我不启用层,只启用 运行 我的代码,事情似乎工作正常,我可以调整我的 window 的大小并按预期更新渲染。这是验证层中的错误吗?

一些 research 建议我应该这样做:

const std::vector<const char*> device_extensions = {
    VK_KHR_SWAPCHAIN_EXTENSION_NAME,
    VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
    VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME,
};

 vk::PhysicalDeviceDynamicRenderingFeaturesKHR dynamic_rendering = {};
    dynamic_rendering.dynamicRendering = true;

    // Get the features of the selected device.
    vk::PhysicalDeviceFeatures device_features = phys_device.getFeatures();

    // The enabledLayerCount and ppEnabledLayerNames parameters are deprecated,
    // they should always be 0 and nullptr.
    // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkDeviceCreateInfo.html
    vk::DeviceCreateInfo create_info = {};
    create_info.pNext = &dynamic_rendering;
    create_info.queueCreateInfoCount = queue_create_infos.size();
    create_info.pQueueCreateInfos = queue_create_infos.data();
    create_info.enabledLayerCount = 0;
    create_info.ppEnabledLayerNames = nullptr;
    create_info.enabledExtensionCount = device_extensions.size();
    create_info.ppEnabledExtensionNames = device_extensions.data();
    create_info.pEnabledFeatures = &device_features;

但这会返回以下错误:

Message ID name: VUID-VkGraphicsPipelineCreateInfo-dynamicRendering-06052
Message: Validation Error: [ VUID-VkGraphicsPipelineCreateInfo-dynamicRendering-06052 ] Object 0: handle = 0x2357fc0, name = Logical device: NVIDIA GeForce GTX 1070, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xdf901c9e | vkCreateGraphicsPipeline: pCreateInfos[0].renderPass is VK_NULL_HANDLE but dynamicRendering is not enabled. The Vulkan spec states: If the dynamicRendering feature is not enabled, renderPass must not be VK_NULL_HANDLE (https://vulkan.lunarg.com/doc/view/1.3.204.1/linux/1.3-extensions/vkspec.html#VUID-VkGraphicsPipelineCreateInfo-dynamicRendering-06052)

我不明白,我正在启用扩展程序。

按照评论中的建议,我看到了这个:

vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice) returns VkResult VK_SUCCESS (0):
    physicalDevice:                 VkPhysicalDevice = 0x32f85c0
    pCreateInfo:                    const VkDeviceCreateInfo* = 0x7fff0d9dbb20:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO (3)
        pNext:                          const void* = NULL

这似乎表明 pNext 设置不正确。

您可能需要将 VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME 添加到 device_extensions 列表中。您没有显示设置该列表的代码。其余的看起来还可以。

driver 继续使用请求的功能并不少见,即使它没有启用。但由于它可以从 driver 更改为 driver,因此最好始终启用您需要的扩展和功能。