Vulkan - Apple M2 中的 VK_ERROR_INCOMPATIBLE_DRIVER 错误

问题描述 投票:0回答:1

使用此代码:

#include <vulkan/vulkan.h>

#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include <vector>
class HelloTriangleApplication {

public:
    void run() {
        initWindow();
        initVulkan();
        mainLoop();
        cleanup();
    }
private:
    VkInstance instance;
    
    void initWindow() {
    }
    void initVulkan() {
        createVulkanInstance();
    }
    
    void mainLoop() {
    }
    
    void cleanup() {
        vkDestroyInstance(instance, nullptr);
    }
    
    void createVulkanInstance() {
        VkApplicationInfo appInfo{};
        appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
        appInfo.pApplicationName = "Hello Triangle";
        appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
        appInfo.pEngineName = "No Engine";
        appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
        appInfo.apiVersion = VK_API_VERSION_1_0;
        
        VkInstanceCreateInfo instanceCreateInfo{};
        instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
        instanceCreateInfo.pApplicationInfo = &appInfo;
        setRequiredExtensions(&instanceCreateInfo);
                
        VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
        if (result != VK_SUCCESS) {
            throw std::runtime_error("Failed to create Vulkan instance. Error code: " + std::to_string(static_cast<int>(result)));
        }
        delete [] instanceCreateInfo.ppEnabledExtensionNames;
    }
   
    void setRequiredExtensions(VkInstanceCreateInfo* instanceCreateInfo) {
        std::vector<const char*> requiredExtensions;

        #ifdef __APPLE__
        requiredExtensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
        requiredExtensions.push_back("VK_KHR_portability_subset");
        requiredExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
        instanceCreateInfo->flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
        #endif
       
        
        const char** enabledExtensions = new const char*[requiredExtensions.size()];
        for (size_t i = 0; i < requiredExtensions.size(); i++) {
            enabledExtensions[i] = requiredExtensions[i];
        }
        
        instanceCreateInfo->enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size());
        instanceCreateInfo->ppEnabledExtensionNames = enabledExtensions;
        
        std::cout << "Requesting extensions:" << std::endl;
        for (const auto& ext : requiredExtensions) {
            std::cout << "\t" << ext << std::endl;
        }
    }
};

int main() {
    const char* vk_icd = std::getenv("VK_ICD_FILENAMES");
    const char* vk_layer = std::getenv("VK_LAYER_PATH");
    if (!vk_icd) throw std::runtime_error("VK_ICD_FILENAMES environment variable is not set");
    if (!vk_layer) throw std::runtime_error("VK_LAYER_PATH environment variable is not set");
    #ifndef NDEBUG
    std::cout << "VK_ICD_FILENAMES: " << (vk_icd ? vk_icd : "Not set") << std::endl;
    std::cout << "VK_LAYER_PATH: " << (vk_layer ? vk_layer : "Not set") << std::endl;
    #endif
    
    HelloTriangleApplication app;
    
    try {
        app.run();
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    
    return EXIT_SUCCESS;
}

...我在 vkCreateInstance 上得到

VK_ERROR_INCOMPATIBLE_DRIVER

从 1.3.216 Vulkan SDK 开始,Vulkan Loader 严格执行新的 VK_KHR_PORTABILITY_subset 扩展。实例创建时出现此错误消息的最可能原因是未能遵守此扩展,这会阻止所有平台上的应用程序默认选择不符合要求的 Vulkan 实现而不选择加入。MoltenVK 目前不完全符合要求,因此支持此扩展扩展对于构建强大且可移植的基于 Vulkan 的应用程序是必要的,这些应用程序是 Vulkan 生态系统中的好公民。

选择加入很简单。首先将 VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR 位添加到 VkInstanceCreateInfo 结构的 .flags 成员中,然后将两个实例扩展添加到实例扩展列表中:VK_KHR_portability_enumeration 和 VK_KHR_get_physical_device_properties2。

我做了:

#ifdef __APPLE__
requiredExtensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
requiredExtensions.push_back("VK_KHR_portability_subset");
requiredExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
instanceCreateInfo->flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif

不起作用,仍然错误-9。

https://stackoverflow.com/a/72791361/22757599

启用 VK_KHR_portability_enumeration 实例扩展 为您的实例创建信息添加(或设置)VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR 标志 启用 VK_KHR_portability_subset 设备扩展

如果不创建实例,我无法设置设备扩展。我已经设置了前两个。不起作用。

但你知道什么是有趣的吗?对此只有一种解决办法。每个解决方案都是相同的。

https://www.reddit.com/r/vulkan/comments/11a1kq4/problem_with_vulkan_in_apple_m2/

https://github.com/ocornut/imgui/issues/6101

https://vulkan-tutorial.com/FAQ

VK_ERROR_INCOMPATIBLE_DRIVER 与 Mac OS 和 Vulkan MoltenVK

我可以在这里排列一堵柏林墙的链接,只是用这些问题和相同的答案,但你明白我的意思。没有人,实际上没有一个人说“嘿,这对我不起作用,这里,拿着这个”,这只是这个解决方案。启用 2 个扩展,设置 1 个标志,瞧,对每个人都有效。除了我。

帮助

c++ macos vulkan
1个回答
0
投票

您需要确保正确配置必要的 Vulkan 扩展和标志,以修复 Apple M2 上的 VK_ERROR_INCOMPATIBLE_DRIVER 错误。另外,请仔细检查 VK_ICD_FILENAMES 和 VK_LAYER_PATH 环境变量是否设置正确。

对代码进行的主要更改是:

  1. 更正了扩展名VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME 而不是字符串“VK_KHR_portability_subset”。

  2. 确保扩展列表包含正确的名称和标志 需要 Apple M2 兼容性。

  3. 添加了 VK_ICD_FILENAMESVK_LAYER_PATH 环境变量 检查。

通过放置以下内容来更改您提到的代码片段:


requiredExtensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); requiredExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); // 正确的扩展名 requiredExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); instanceCreateInfo->flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;


确保在 shell 中正确设置环境变量 VK_ICD_FILENAMESVK_LAYER_PATH

export VK_ICD_FILENAMES=/path/to/icd.json
export VK_LAYER_PATH=/path/to/layers

将 /path/to/icd.json 和 /path/to/layers 替换为您自己定义的实际路径。

© www.soinside.com 2019 - 2024. All rights reserved.