Вулкан загрузить vkCreateDebugReportCallbackEXT

Попадаю в Vulkan и наткнулся на свою первую проблему. При попытке создать обратный вызов отчета об отладке (уровни проверки и расширения отладки доступны в моем драйвере intel hd vulkan, по крайней мере, так написано), он не сообщает мне, что vkCreateDebugReportCallbackEXT является неразрешенным символом. При попытке получить указатель на функцию он не сообщает мне, что vkCreateDebugReportCallbackEXT уже определен.

Что и есть в шапке Vulkan. Я мог бы установить VK_NO_PROTOTYPES, но тогда мне пришлось бы загружать все вручную. Это можно обойти? Просто использовать другое имя для указателя функции не получится, так как я использую Vulkan-Hpp, и он использует vkCreateDebugReportCallbackEXT как есть. Это ошибка драйвера, говорящая мне, что расширения отладки доступны, но их нет?

Кстати, я использую VS2015.

Спасибо за любую помощь


person pettersson    schedule 23.08.2016    source источник
comment
Странно, но я не вижу vulkan.hpp даже для использования этой команды расширения.   -  person krOoze    schedule 23.08.2016


Ответы (2)


Это нормально. vulkan.h определяет их как глобальные функции. Но команды загрузчика явно возвращают функцию указатель.

Обычно вы просто используете другое имя, которое вам нравится. Но мне тоже нравятся канонические имена ...

Я решаю эту проблему, определяя функцию самостоятельно (используя объявление из vulkan.h), которая, в свою очередь, вызывает загруженный указатель:

VKAPI_ATTR VkResult VKAPI_CALL vkCommandEXT( /*...*/ ){
    return fpCommandEXT( /*...*/ );
}

(Бесстыдная самореклама) Вот так:
https://github.com/krOoze/Hello_Triangle/blob/8227220/ErrorHandling.h#L181

Я заставляю команду загружаться при первом использовании, если вам это не нравится, в более старом коммите у меня был более обычный загрузчик:
https://github.com/krOoze/Hello_Triangle/blob/699ab57/HelloTriangle.cpp#L731

PS:
сами Khronos просто добавили код загрузчика, который прекрасно это иллюстрирует:
https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0/src/ext_loader/vulkan_ext.c

Если вы обрабатываете несколько VkInstance или VkDevice, загруженные функции должны быть отправлены на правильный экземпляр или устройство. Например, я делаю это (вероятно, неэффективно) здесь:
https://github.com/krOoze/Hello_Triangle/blob/a691de5/ExtensionLoader.h

person krOoze    schedule 23.08.2016
comment
Очередная бессовестная самореклама! Мой загрузчик Vk: github.com/AlessandroBorges/Bor_Vulkan/ master / Vulkan / jni / и github.com / AlessandroBorges / Bor_Vulkan / blob / master / Vulkan / jni /. CPP обновлен до Vulkan 1.0.7. Скоро исправлю до 1.0.21.1. - person Alex Byrth; 24.08.2016

У меня была такая же проблема, я не смог найти решение, поэтому решил ее таким образом (может ошибаться, но я просто хочу поделиться, если это кому-то поможет):

struct DebugDispatch {
    //KHRONOS
    PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = 0;
    PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = 0;
    //LUNARG
    PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = 0;
    PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = 0;
}

VKAPI_ATTR vk::Bool32 VKAPI_CALL debugReportCallback(...){...}
VKAPI_ATTR vk::Bool32 VKAPI_CALL debugUtilsMessengerCallback(...){...}

enum class ValidationFlagsBits : unsigned int {
    NONE = 0,
    KHRONOS = 1,
    LUNARG = 1 << 1
};

typedef vk::Flags<ValidationFlagsBits> ValidationFlags;

void Example(){
    ...

    vk::Instance instance;
    instance = vk::createInstance(...);

    DebugDispatch debug_dispatch;
    vk::DebugReportCallbackEXT debug_report_callback;
    vk::DebugUtilsMessengerEXT debug_utils_messenger;
    
    if(validation_flags & ValidationFlagsBits::KHRONOS){
        debug_dispatch.vkCreateDebugReportCallbackEXT = 
            (PFN_vkCreateDebugReportCallbackEXT)instance.getProcAddr("vkCreateDebugReportCallbackEXT");
        debug_dispatch.vkDestroyDebugReportCallbackEXT =
            (PFN_vkDestroyDebugReportCallbackEXT)instance.getProcAddr("vkDestroyDebugReportCallbackEXT");
        
        vk::DebugUtilsMessengerCreateInfoEXT create_info{};
        create_info.messageSeverity = ...;
        create_info.messageType = ...;
        create_info.pfnUserCallback = reinterpret_cast<PFN_vkDebugUtilsMessengerCallbackEXT>(&debugUtilsMessengerCallback);

        debug_utils_messenger = instance.createDebugUtilsMessengerEXT(create_info, nullptr, debug_dispatch);
    }
    if(validation_flags & ValidationFlagsBits::LUNARG){
        debug_dispatch.vkCreateDebugUtilsMessengerEXT =
            (PFN_vkCreateDebugUtilsMessengerEXT)instance.getProcAddr("vkCreateDebugUtilsMessengerEXT");
        debug_dispatch.vkDestroyDebugUtilsMessengerEXT =
            (PFN_vkDestroyDebugUtilsMessengerEXT)instance.getProcAddr("vkDestroyDebugUtilsMessengerEXT");

        vk::DebugReportCallbackCreateInfoEXT create_info{};
        create_info.flags = ...;
        create_info.pfnCallback = reinterpret_cast<PFN_vkDebugReportCallbackEXT>(&debugReportCallback);

        debug_report_callback = instance.createDebugReportCallbackEXT(create_info, nullptr, debug_dispatch);
    }

    ...

    if(validation_flags & ValidationFlagsBits::KHRONOS){
        instance.destroyDebugUtilsMessengerEXT(debug_utils_messenger, nullptr, debug_dispatch);
    }
    if(validation_flags & ValidationFlagsBits::LUNARG){
        instance.destroyDebugReportCallbackEXT(debug_report_callback, nullptr, debug_dispatch);
    }
    instance.destroy();
}
person Kazz    schedule 01.04.2021