使用此代码:
#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 个标志,瞧,对每个人都有效。除了我。
帮助
您需要确保正确配置必要的 Vulkan 扩展和标志,以修复 Apple M2 上的 VK_ERROR_INCOMPATIBLE_DRIVER 错误。另外,请仔细检查 VK_ICD_FILENAMES 和 VK_LAYER_PATH 环境变量是否设置正确。
对代码进行的主要更改是:
更正了扩展名VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME 而不是字符串“VK_KHR_portability_subset”。
确保扩展列表包含正确的名称和标志 需要 Apple M2 兼容性。
添加了 VK_ICD_FILENAMES 和 VK_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_FILENAMES 和 VK_LAYER_PATH:
export VK_ICD_FILENAMES=/path/to/icd.json
export VK_LAYER_PATH=/path/to/layers
将 /path/to/icd.json 和 /path/to/layers 替换为您自己定义的实际路径。