在 Mac 上使用 MoltenVk/Vulkan 获取 VK_ERROR_LAYER_NOT_PRESENT

Getting VK_ERROR_LAYER_NOT_PRESENT with MoltenVk/Vulkan on Mac

我正在尝试在 Mac 上设置 vulkan/MoltenVk,但我在使验证层和扩展正常工作时遇到了一些问题。

我有 downloaded/installed MoltenVk 和 vulkan 库,设置一些环境变量:

export VULKAN_SDK=/opt/vulkan-sdk
export DYLD_LIBRARY_PATH=$VULKAN_SDK/lib:$DYLD_LIBRARY_PATH
export VK_ICD_FILENAMES=$VULKAN_SDK/etc/vulkan/icd.d/MoltenVK_icd.json
export VK_LAYER_PATH=$VULKAN_SDK/etc/vulkan/explicit_layer.d
export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_standard_validation

vulkaninfo 按预期工作并显示 6 个验证层。

当我尝试构建自己的项目时,找不到图层。

我创建了一个小测试项目来尝试弄清楚发生了什么。它编译 links 没有错误,但是当我 运行 它时我得到

[***MoltenVK ERROR***] VK_ERROR_LAYER_NOT_PRESENT: Vulkan layer VK_LAYER_LUNARG_standard_validation is not supported.
vkCreateInstance result: -6

main.cpp(从https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html复制)

#include <iostream>
#include <vulkan/vulkan.h>

int main(int argc, const char * argv[]) {
    VkInstance instance;
    VkResult result;
    VkInstanceCreateInfo info = {};
    uint32_t instance_layer_count;

    result = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr);
    std::cout << instance_layer_count << " layers found!\n";
    if (instance_layer_count > 0) {
        std::unique_ptr<VkLayerProperties[]> instance_layers(new VkLayerProperties[instance_layer_count]);
        result = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers.get());
        for (int i = 0; i < instance_layer_count; ++i) {
            std::cout << instance_layers[i].layerName << "\n";
        }
    }

    const char * names[] = {
        "VK_LAYER_LUNARG_standard_validation"
    };
    info.enabledLayerCount = 1;
    info.ppEnabledLayerNames = names;

    result = vkCreateInstance(&info, NULL, &instance);
    std::cout << "vkCreateInstance result: " << result  << "\n";

    vkDestroyInstance(instance, nullptr);
    return 0;
}

建造

clang++ main.cpp 
-I/opt/vulkan-sdk/include/ 
-rpath /opt/vulkan-sdk/lib 
-L/opt/vulkan-sdk/lib/ 
-lMoltenVk 
-lvulkan 
-lVkLayer_core_validation 
-lVkLayer_object_lifetimes 
-lVkLayer_stateless_validation 
-lVkLayer_thread_safety -lVkLayer_unique_objects 
-o output

请注意,我link反对 .dylib,但我之前也尝试过使用 .framework 库。

我怀疑我需要 link 其他东西,或者在代码中添加特定的环境变量或#define。 有谁知道如何解决这个问题?

我认为问题在于您 link 应用程序不正确。

Vulkan 加载程序将 MoltenVK 库 (dylib) 视为 ICD(可安装客户端驱动程序)。加载程序是您在 link 命令中使用 -lvulkan linking 的库。 Vulkan 加载器在执行时动态加载 ICD。使用 Vulkan 加载器时,ICD 不会 link 直接添加到应用程序。

同样,Vulkan 加载器在执行时动态加载层。图层未 link 直接添加到应用程序。

MoltenVK 库有点不寻常,因为它的构建方式使得应用程序可以 link 直接访问它,运行 MoltenVK(Vulkan 子集)应用程序无需使用加载程序和层.

但是如果你想使用加载器和图层,你不需要 link MoltenVK 和你的应用程序的图层。你link只是装载机。然后加载程序将 MoltenVK 库作为 ICD 动态加载,并在需要时动态加载图层。

在您的情况下,您似乎首先 linking MoltenVK 库。这可能会首先通过 MoltenVK 库满足所有 Vulkan 符号。您的库列表中的 Vulkan 加载器可能甚至没有包含在您的可执行文件中,因为 MoltenVK 在那里并且 Vulkan 加载器实际上没有做任何事情。

我想如果你删除 -lMoltenVK 和其他 5 个层库,你会做得更好。

您还可以在您的环境中设置 VK_LOADER_DEBUG=all 以查看加载程序正在做什么。我怀疑如果你 运行 你当前的应用程序使用这个集合,你将看不到任何东西,因为加载程序没有参与。

有关详细信息,请参阅 https://vulkan.lunarg.com/doc/sdk/1.1.101.0/mac/loader_and_layer_interface.html