vkCreateInstance 抛出分段错误

vkCreateInstance throws Segmentation Fault

我正在尝试学习一些 Vulkan,但是 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(不确定这是否重要)

您的中间代码片段缺少 enabledLayerCount 初始化,因此您让驱动程序执行 OOBA。

你的最后一个片段 returns instanceCreateInfo 其中 pApplicationInfo 指向被销毁的 VkApplicationInfo 当它被 vkCreateInstance 使用时。您使驱动程序取消引用指向已销毁内存的指针。