在 Mac 上使用 MoltenVk/Vulkan 获取 VK_ERROR_LAYER_NOT_PRESENT

Jro*_*dev 3 c++ macos clang++ vulkan

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

我已经下载/安装了 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

[***MoltenVK ERROR***] VK_ERROR_LAYER_NOT_PRESENT: Vulkan layer VK_LAYER_LUNARG_standard_validation is not supported.
vkCreateInstance result: -6
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

建造

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
Run Code Online (Sandbox Code Playgroud)

请注意,我链接的是 .dylibs,但我之前也尝试过使用 .framework 库。

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

Kar*_*ltz 5

我认为问题在于您错误地链接了您的应用程序。

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

类似地,Vulkan 加载器在执行时动态加载层。层不直接链接到应用程序。

MoltenVK 库有点不寻常,因为它的构建方式使得应用程序可以直接链接到它并运行 MoltenVK(Vulkan 子集)应用程序,而无需使用加载器和层。

但如果您想使用加载器和层,则无需将 MoltenVK 和层链接到您的应用程序。您仅链接加载程序。然后,加载程序将 MoltenVK 库动态加载为 ICD,并根据请求动态加载各层。

就您而言,您似乎首先链接了 MoltenVK 库。这可能最终会首先通过 MoltenVK 库满足所有 Vulkan 符号。您的库列表中的 Vulkan 加载程序可能甚至没有包含在您的可执行文件中,因为 MoltenVK 就在那里,而 Vulkan 加载程序实际上没有执行任何操作。

我认为如果你删除-lMoltenVK5 个其他层库,你会做得更好。

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

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