cvulkan

VK_KHR_swapchain extension not found even if vkcube runs perfectly


I am making an app with vulkan and encountered a problem.

In my laptop (only integrated graphics), the vkcube.exe runs perfectly fine. So there is no extension support problem. But when i create an app myself it says that VK_KHR_swapchain extension is not present.

Also there is a safety check in which i call vkEnumerateDeviceExtensionProperties, and VK_KHR_swapchain is present in the list, so it must be supported. These are the device extensions supported by my integrated GPU:

[09:19:24:716] [TRACE]: Device Extension: VK_EXT_device_address_binding_report
[09:19:24:716] [TRACE]: Device Extension: VK_EXT_full_screen_exclusive
[09:19:24:717] [TRACE]: Device Extension: VK_KHR_swapchain
    VkDeviceCreateInfo device_create_info      = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
    device_create_info.queueCreateInfoCount    = index_count;
    device_create_info.pQueueCreateInfos       = queue_create_info;
    device_create_info.pEnabledFeatures        = &device_features;
    device_create_info.enabledExtensionCount   = 1;
    const char* extension_names[1]             = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
    device_create_info.ppEnabledExtensionNames = (const char* const*)&extension_names;

    device_create_info.enabledLayerCount   = 0;
    device_create_info.ppEnabledLayerNames = 0;

    GRD_LOG_DEBUG("Creating logical device for physical device: %s", context->device.properties.deviceName);
    VkResult result = vkCreateDevice(
        context->device.physical_device,
        &device_create_info,
        context->allocator,
        &context->device.logical_device);
    if (result != VK_SUCCESS)
    {
        GRD_LOG_FATAL("Could not create vulkan logical device. Result: %d", result);
        return FALSE;
    }

This is the output:

[08:58:45:587] [DEBUG]: Creating logical device for physical device: Intel(R) Iris(R) Xe Graphics
[08:58:45:587] [ERROR]: loader_validate_device_extensions: Device extension VK_KHR_swapchain not supported by selected physical device or enabled layers.
[08:58:45:589] [ERROR]: vkCreateDevice: Failed to validate extensions in list
[08:58:45:589] [FATAL]: Could not create vulkan logical device. Result: -7 // Result Code for Extension not present

These are the instance extensions that were enabled.

[08:58:45:482] [DEBUG]: Vulkan Required extensions:
[08:58:45:482] [DEBUG]:     1: VK_KHR_surface
[08:58:45:483] [DEBUG]:     2: VK_KHR_get_physical_device_properties2
[08:58:45:483] [DEBUG]:     3: VK_KHR_portability_enumeration
[08:58:45:483] [DEBUG]:     4: VK_KHR_win32_surface
[08:58:45:483] [DEBUG]:     5: VK_EXT_debug_utils

Solution

  • Ok guys, nothing wrong with vulkan, not that i expected anything to be wrong in vulkan.

    I was using a custom allocator. In the reallocate callback, i was allocating new memory but wasnt copying the old memory block to the new address which may have resulted in some data corruptions (data loss actually as the new allocations were zeroed out instead of containing old data) and led to this error.

    Once i added logic for copying the previous memory block data to the new address in the reallocate callback, the program was working as expected.

    Although the real code changes are complex and over 100s of lines, here is a overview of what was wrong and how it got corrected.

    See VkAllocationCallbacks - VkSpec for understanding the function definition and what the parameters mean/represent.

    Before:

    void* VKAPI_PTR vulkan_memory_reallocate(
        void* pUserData,
        void* pOriginal,
        size_t size,
        size_t alignment,
        VkSystemAllocationScope allocationScope)
    {
        if (pOriginal)
        {
            free_aligned_memory(pOriginal); 
        }
    
        return allocate_aligned_memory(size, alignment);
    }
    

    After fixing:

    void* VKAPI_PTR vulkan_memory_reallocate(
        void* pUserData,
        void* pOriginal,
        size_t size,
        size_t alignment,
        VkSystemAllocationScope allocationScope)
    {
        void* new_ptr     = allocate_aligned_memory(size, alignment);
        // size of memory requested by vulkan during allocation of pOriginal.
        // i.e. the amount of bytes we have to copy from the previous address to the new address.
        uint64 block_size = 0;
        get_block_size(pOriginal, &block_size);
        grd_copy_memory(new_ptr, pOriginal, block_size);
    
        if (pOriginal)
        {
            free_aligned_memory(pOriginal);
        }
    
        return new_ptr;
    }