《Vulkan Tutorial》 笔记 04:Instance
本部分结果可参考 04_Instance
本章涉及到的关键对象如下所示:
对于一个 Vulkan 应用而言,你首先需要通过创建一个 instance
来初始化 Vulkan 库, instance
是应用与 Vulkan 库的连接,在创建过程中会有相应的操作告知 Driver 你的应用的一些细节。为创建 Instance,首先在头文件中需要在本节中定义的函数和变量,createInstance
用来创建实例并放在 instance
中,checkAvailableExtensions
用来检查当前系统支持的 Extensions,checkRequiredGlfwExtensions
用来检查 GLFW 需要的 Extensions,这两个函数在 createInstance
中被调用:
1 | class HelloTriangleApplication |
在 initVulkan
函数中调用 createInstance
函数创建实例:
1 | void HelloTriangleApplication::initVulkan() |
#创建一个 Instance
对一个 Vulkan 程序而言,首先需要创建一个 instance
,它用来连接应用与 Vulkan 库,同时也会将程序的一些细节指示给驱动。
创建 Instance 的完整实现如下所示:
1 | void HelloTriangleApplication::createInstance() |
其中首先需要创建两个结构体 VkApplicationInfo 和 VkInstanceCreateInfo:
VkApplicationInfo
透露了关于应用的一些信息,驱动可以根据这些信息对程序做一些优化,例如其中的engine
告诉驱动该 Vulkan 应用是否有使用游戏引擎,如这里没有使用,因此将其设为No Engine
,反之可能是Unreal Engine
或Unity
等。VkInstanceCreateInfo
描述了创建 Instance 所需要的信息。- 因为 Vulkan 本身是一个与平台不相关的接口,因此在 Create Info 中需要描述它所依赖的平台的相关的 Extension(如 Surface),这些 Extension 可以从 GLFW 的接口
glfwGetRequiredInstanceExtensions
中获取。 - CreateInfo 中的
enabledLayerCount
和ppEnabledLayerNames
用来指定启用的 Validation Layers,这里暂时不启用,因此将enabledLayerCount
设为 0,并将 ppEnabledLayerNames 设为 nullptr。
- 因为 Vulkan 本身是一个与平台不相关的接口,因此在 Create Info 中需要描述它所依赖的平台的相关的 Extension(如 Surface),这些 Extension 可以从 GLFW 的接口
Vulkan 设计中,许多函数需要的信息都是通过结构体,而不是一系列函数形参。
之后通过 vkCreateInstance
函数实际创建 Instance:
1 | if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) |
这类 Create 函数通常有以下的形参:
- 一个指针指向创建需要的信息结构体
- 一个指针指向创建后的回调函数,在本教程中一直是
nullptr
- 一个指针指向存储创建物体内存的对象。
同时几乎所有的 Vulkan 函数都会返回一个 VkResult
值表示接口运行是否成功,VkResult
的值是 VK_SUCCESS
或其他错误值。
之后函数通过 checkAvailableExtensions
和 checkRequiredGlfwExtensions
函数检查了当前系统支持的 Extensions 和 GLFW 需要的 Extensions。
#检查可用的 Extensions
可以通过 vkEnumerateInstanceExtensionProperties
函数获取所有支持的 extensions,其中第一个参数为用来过滤 extensions 的 Validation Layers 的名称,这里暂不使用,第二个参数为 extensions 的数目,第三个参数为所有 extension 的数据。
使用示例如下所示:
1 | void HelloTriangleApplication::checkAvailableExtensions(const VkInstanceCreateInfo& createInfo) |
上例中调用了两次 vkEnumerateInstanceExtensionProperties
函数,第一次是为了获取数量,第二次则是完整的获取所有的 Extensions。
此时的输出结果如下所示
1 | available extensions: |
#检查需要使用的 GLFW Extensions
如前所述,创建 Vulkan Instance 有平台相关的拓展,这些需要通过 glfwGetRequiredInstanceExtensions
获取到,可以通过以下的方式将依赖的 Extensions 打出:
1 | void HelloTriangleApplication::checkRequiredGlfwExtensions() |
此时结果如下所示:
1 | required extensions: |
#Cleaning up
最后需要处理在应用退出时,销毁创建好 Instance, 该步骤可以通过 vkDestroyInstance
函数实现:
1 | void HelloTriangleApplication::cleanup() |
之后所有创建的 Vulkan 资源都需要在销毁 Instance 前被销毁。