Home > OS >  Why does vkCreateInstance return "VK_ERROR_INCOMPATIBLE_DRIVER" on MacOS despite vulkan su
Why does vkCreateInstance return "VK_ERROR_INCOMPATIBLE_DRIVER" on MacOS despite vulkan su

Time:06-29

I am currently trying to develop my vulkan based graphics engine on my laptop (MacBook Pro with Intel Iris Pro GPU). I started this project on my desktop PC (Windows with NVIDIA GTX 1080 ti GPU). This works flawlessly on my desktop PC. But when I try building and executing this on my laptop, the executable fails trying to create the vulkan instance and returns "VK_ERROR_INCOMPATIBLE_DRIVER" as a VkResult.

Disclaimer: I am new to c , and I am aware that the following code does not conform to most c coding conventions. I am trying to make my code as readable as possible so I can learn better.

I am trying to create a new vulkan instance with the following code:

VkApplicationInfo app_info{};                                // APPLICATION INFO
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;         // type of the struct
app_info.pApplicationName = application_name;                // name of the application
app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);      // version
app_info.pEngineName = application_engine_name;              // name of the engine
app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);           // version
app_info.apiVersion = VK_API_VERSION_1_0;                    // API version

// get available GLFW extensions
uint32_t glfw_extension_count = 0;                                            
const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);

// setup create info struct
VkInstanceCreateInfo instance_create_info{};                          // INSTANCE CREATION INFO
instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;  // type of struct
instance_create_info.pApplicationInfo = &app_info;                     // application info from above
instance_create_info.enabledExtensionCount = glfw_extension_count;      // amount of extensions to be enabled
instance_create_info.ppEnabledExtensionNames = glfw_extensions;        // extensions to enable
instance_create_info.enabledLayerCount = enable_validation_layers ? static_cast<uint32_t>(validation_layers.size()) : 0; // validation layer count
instance_create_info.ppEnabledLayerNames = enable_validation_layers ? validation_layers.data() : nullptr;                // validation layer names

// try creating instance, catch potential error code
VkResult creation_result = vkCreateInstance(&instance_create_info, nullptr, &vulkan_instance);

// check result of instance creation, handle errors
if (creation_result != VK_SUCCESS)
{
    string message = "ERROR: Instance creation failed with result '";
    message  = get_result_string(creation_result);
    message  = "'.";
    throw runtime_error(message);
}

// get extensions available for vulkan instance
uint32_t extension_count = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
vector<VkExtensionProperties> extensions(extension_count);
vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data());

Validation layers are disabled, so the last two lines for the CreateInfo struct can be disregarded. "get_result_string()" simply returns a cleaner error string based on the provided VkResult:

string get_result_string (VkResult vulkan_result)
{
    switch (vulkan_result)
    {
        case VK_SUCCESS:
            return "SUCCESS";
        case VK_ERROR_OUT_OF_HOST_MEMORY:
            return "OUT OF HOST MEMORY";
        case VK_ERROR_OUT_OF_DEVICE_MEMORY:
            return "OUT OF DEVICE MEMORY";
        case VK_ERROR_INITIALIZATION_FAILED:
            return "INITIALIZATION FAILED";
        case VK_ERROR_LAYER_NOT_PRESENT:
            return "LAYER NOT PRESENT";
        case VK_ERROR_EXTENSION_NOT_PRESENT:
            return "EXTENSION NOT PRESENT";
        case VK_ERROR_INCOMPATIBLE_DRIVER:
            return "INCOMPATIBLE DRIVER";
        default:
            return "UNKNOWN RESULT '"   vulkan_result;
    }
}

Running vkcube in the Applications folder of the VulkanSDK folder works error free. Running vulkaninfo returns no errors and can create the instance and physical device successfully. According to the Vulkan Hardware Database, the GPU of my laptop should be supported. The OS is up to date, which should mean the drivers are up to date as well. The overall build command for the executable is as follows:

g   -std=c  17 -O2 -g [SRC FILES] -o [OUTPUT FILE] -L /.../VulkanSDK/1.3.216.0/macOS/lib /.../VulkanSDK/1.3.216.0/macOS/lib/libvulkan.1.dylib /.../VulkanSDK/1.3.216.0/macOS/lib/libvulkan.1.3.216.dylib -L /usr/local/Cellar/glfw/3.3.7/lib/ -lglfw -I /.../VulkanSDK/1.3.216.0/macOS/include -I /usr/local/include/glm -I /usr/local/include/GLFW

At this point, I have no idea why my executable can't create a vulkan instance. Some help here would be much appreciated! Anyone got an idea?

CodePudding user response:

SDK 1.3.216 introduced a change in how devices are enumerated on MacOSX, and your code must make use of the portability subset extension to discover your devices (again).

In order to use the portability subset extension:

  • Enable the VK_KHR_portability_enumeration instance extension
  • Add (or set) the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR flag for your instance create info
  • Enable the VK_KHR_portability_subset device extension

With these changes, you should be able to create your instance and device on MacOS.

CodePudding user response:

We tried to make this as painless as possible, in addition to warning about it in previous SDK notes, we had a popup in the SDK installer warning about this, added a not to the release notes here: https://vulkan.lunarg.com/doc/sdk/1.3.216.0/mac/release_notes.html

And put the sample code for the fix in the Getting Started Guide here: https://vulkan.lunarg.com/doc/sdk/1.3.216.0/mac/getting_started.html

  • Related