vkCreateInstance выдает ошибку сегментации - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь выучить немного Вулкана, и у меня странная проблема с vkCreateInstance.Кажется, это приводит к ошибкам сегментации, но только в очень специфических обстоятельствах.Чтобы быть более понятным, вот некоторый код:

int main() {
    // Load Vulkan Functions, extensions and stuff
    VkApplicationInfo applicationInfo;
    applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    applicationInfo.pNext = nullptr;
    applicationInfo.pApplicationName = "VulkanDoodles";
    applicationInfo.applicationVersion = VK_MAKE_VERSION(1,0,0);
    applicationInfo.pEngineName = "EngineNamePlaceholder";
    applicationInfo.engineVersion = VK_MAKE_VERSION(1,0,0);
    applicationInfo.apiVersion = VK_MAKE_VERSION(1,0,0);

    VkInstanceCreateInfo instanceCreateInfo;
    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceCreateInfo.pNext = nullptr;
    instanceCreateInfo.flags = 0;
    instanceCreateInfo.pApplicationInfo = &applicationInfo;
    instanceCreateInfo.ppEnabledLayerNames = nullptr;
    instanceCreateInfo.enabledExtensionCount = (uint32_t)desired_extensions.size();
    instanceCreateInfo.ppEnabledExtensionNames = &desired_extensions[0];

    VkInstance instance;
    if(vk::vkCreateInstance(&instanceCreateInfo, nullptr, &instance) != VK_SUCCESS){
        std::cout << "Could not create instance" << std::endl;
        return -1;
    }
    // rest of the code
    return 0;
}

И он работает нормально, экземпляр создан.Поэтому я решил поместить код внутри функции для удобства чтения.Но код, подобный следующему, больше не работает:

VkInstance CreateInstance(const std::vector<const char*> extensions){
    VkApplicationInfo applicationInfo;
    applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    applicationInfo.pNext = nullptr;
    applicationInfo.pApplicationName = "VulkanDoodles";
    applicationInfo.applicationVersion = VK_MAKE_VERSION(1,0,0);
    applicationInfo.pEngineName = "EngineNamePlaceholder";
    applicationInfo.engineVersion = VK_MAKE_VERSION(1,0,0);
    applicationInfo.apiVersion = VK_MAKE_VERSION(1,0,0);

    VkInstanceCreateInfo instanceCreateInfo;
    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceCreateInfo.pNext = nullptr;
    instanceCreateInfo.flags = 0;
    instanceCreateInfo.pApplicationInfo = &applicationInfo;
    instanceCreateInfo.ppEnabledLayerNames = nullptr;
    instanceCreateInfo.enabledExtensionCount = (uint32_t)extensions.size();
    instanceCreateInfo.ppEnabledExtensionNames = &extensions[0];
    VkInstance instance;
    if(vk::vkCreateInstance(&instanceCreateInfo, nullptr, &instance) != VK_SUCCESS){
        std::cout << "Could not create instance" << std::endl;
    }
    return instance;
}

int main(){
    // Load Vulkan Functions, extensions and stuff
    VkInstance instance = CreateInstance(desired_extensions);
    // rest of the code
}

Вызов vkCreateInstance вызывает ошибку сегментации.Кажется, что вектор расширений не является проблемой, учитывая, что следующий фрагмент кода работает правильно:

VkInstanceCreateInfo CreateInstanceInfo(const std::vector<const char*>& extensions){
    VkApplicationInfo applicationInfo;
    applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    applicationInfo.pNext = nullptr;
    applicationInfo.pApplicationName = "VulkanDoodles";
    applicationInfo.applicationVersion = VK_MAKE_VERSION(1,0,0);
    applicationInfo.pEngineName = "EngineNamePlaceholder";
    applicationInfo.engineVersion = VK_MAKE_VERSION(1,0,0);
    applicationInfo.apiVersion = VK_MAKE_VERSION(1,0,0);

    VkInstanceCreateInfo instanceCreateInfo;
    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceCreateInfo.pNext = nullptr;
    instanceCreateInfo.flags = 0;
    instanceCreateInfo.pApplicationInfo = &applicationInfo;
    instanceCreateInfo.ppEnabledLayerNames = nullptr;
    instanceCreateInfo.enabledExtensionCount = (uint32_t)extensions.size();
    instanceCreateInfo.ppEnabledExtensionNames = &extensions[0];

    return instanceCreateInfo;
}

VkInstance CreateInstance(const VkInstanceCreateInfo& instanceCreateInfo){
    VkInstance instance;
    if(vk::vkCreateInstance(&instanceCreateInfo, nullptr, &instance) != VK_SUCCESS){
        std::cout << "Could not create instance" << std::endl;
    }
    return instance;
}

int main(){
    // Load Vulkan Functions, extensions and stuff
    VkInstanceCreateInfo instanceCreateInfo = CreateInstanceInfo(desired_extensions);
    VkInstance instance = CreateInstance(instanceCreateInfo);
    // rest of the code
}

Как уже говорилось, это работает нормально, и я предполагаю, что переменная VkInstanceCreateInfo должна быть объявленавнутри функции main.

Итак, мои вопросы:

Почему vkCreateInstance выбрасывает ошибку сегмента?Почему только иногда?Есть ли что-то странное, что происходит там?

Любое понимание было бы очень полезным.

Также, для протокола, я использую Linux Mint и CLion с cmake версии 3.13 (не уверен, что дажевопросы)

1 Ответ

0 голосов
/ 23 февраля 2019

В вашем среднем фрагменте кода отсутствует инициализация enabledLayerCount, поэтому вы заставляете драйвер выполнять OOBA.

Ваш последний фрагмент возвращает instanceCreateInfo, где pApplicationInfo указывает на уничтоженное VkApplicationInfo, когда он используетсяvkCreateInstance.Вы делаете указатель разыменования драйвера на уничтоженную память.

...