Vulkan教程翻译之二 创建Vulkan Instance

原文链接:https://vulkan.lunarg.com/doc/sdk/1.2.131.2/windows/tutorial/html/01-init_instance.html

创建Vulkan Instance

这一章节的代码文件是 01-init_instance.cpp

示例程序中的第一步就是创建一个Vulkan instance。在 LunarG Vulkan Sample库的API-Samples目录下找到01-init_instance.cpp 程序,在阅读本章节关于Vulkan instance的时候准备好查看代码。

Vulkan Instances

在Vulkan API中使用vkInstance对象来存储所有的应用状态信息。应用在执行任何Vulkan操作之前都必须先创建一个Vulkan instance。

基本的Vulkan架构如下所示:

Basic App Loader

如上图所示,一个Vulkan应用已经链接到一个通常被称为loader的Vulkan库。创建一个instance会初始化这个loader。loader会再加载并初始化底层的图形驱动,通常是由GPU硬件厂商提供。

请注意,在这幅图里描绘了几个layer,也是由loader来加载的。layer通常用于验证,也就是通常由驱动执行的错误检查。在Vulkan中,驱动比在其他API(比如OpenGL)中都更加轻量化,部分原因就是它们把验证功能委托给了验证layer。layer是可以配置的,并且可以在每次创建instance的时候选择是否加载。

Vulkan layer不在本教程和示例程序的范围内。所以本教程不再过多涉及layer。更多关于layer的信息可以参考Vulkan SDK download site

vkCreateInstance

查看 01-init_instance.cpp 源码,然后找到有以下原型的 vkCreateInstance 函数调用:

VkResult vkCreateInstance(
    const VkInstanceCreateInfo*                 pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkInstance*                                 pInstance);

一点一点地来分析:

VkResult - 这是函数的返回状态。当你遇到它们时,你可能会需要打开vulkan.h头文件并且检查其中一些定义。你可以在Vulkan Sample代码库的include目录下找到该文件。

VkInstanceCreateInfo - 这个结构体包含了创建该instance所需的所有附加信息。由于这是非常重要的一个部分,稍后你将更深入地了解它。

VkAllocationCallbacks - 这是分配主机内存的函数,带有一个参数,该函数允许应用自己执行主机内存管理。否则,Vulkan将使用默认的系统内存管理功能。比如,应用可能想要管理自己的主机内存便于记录内存分配情况。

示例中没有使用这项功能,所以在这个或其他函数中你会看到该参数一直传的是NULL。

VkInstance - 这是instance创建成功后函数返回的一个句柄。这是一个不透明的句柄,所以不要尝试取消引用它。很多创建对象的Vulkan函数都会以这种方式返回它们所创建对象的句柄。

深入了解 VkInstanceCreateInfo 结构体

创建对象的Vulkan函数通常都有一个VkObjectCreateInfo参数。在示例中找到初始化这个结构体的代码:

typedef struct VkInstanceCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkInstanceCreateFlags       flags;
    const VkApplicationInfo*    pApplicationInfo;
    uint32_t                    enabledLayerCount;
    const char* const*          ppEnabledLayerNames;
    uint32_t                    enabledExtensionCount;
    const char* const*          ppEnabledExtensionNames;
} VkInstanceCreateInfo;

前两个成员在许多 Vulkan CreateInfo 结构体里都能找到。

sType - sType字段表明了结构体的类型。目前你把它设置为VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,是因为它是一个 VkInstanceCreateInfo 结构体。这也许看起来多余,因为只有这个类型的结构体才能作为 vkCreateInstance() 的第一个参数输入。但是因为下面这些原因它还是有一些价值的:

  • 驱动,校验层,或者该结构体的其他消费者可以执行一个简单的有效性检查,并且如果sType不符合预期则可能驳回请求。
  • 在接口参数未完全定义类型的接口中,该结构体可以通过void指针传给消费者。比如,如果一个驱动支持创建instance的extension,它就有可能会查看通过无类型的pNext指针(稍后讨论)传入的结构体。这种情况下,sType成员就会被设置成extension可以识别的值。

由于该成员总是结构体的第一个成员变量,消费者可以轻松地确定结构体的类型然后决定怎么处理它。

pNext - 多数情况下你只需把pNext设置为NULL。此void指针有时用来传递类型化的结构体信息给特定的extension,该结构体里sType成员被设置为extension所定义的值。像之前讨论的那样,extension可以分析随着pNext指针链传入的任何结构体以找到可以识别的。

flags - 目前还没有flag定义,所以设成0。

pApplicationInfo - 这是指向另一个你需要填写的结构体指针。稍后再回到这一部分。

enabledLayerCount 和 ppEnabledLayerNames - 本教程的示例没有使用layer,所以这些成员是空的。

enabledExtensionCount 和 ppEnabledExtensionNames - 本教程的示例没有使用extension。稍后,其他示例会展示extension的用法。

VkApplicationInfo结构体

这个结构体为Vulkan实现提供了应用相关的基本信息:

typedef struct VkApplicationInfo {
    VkStructureType    sType;
    const void*        pNext;
    const char*        pApplicationName;
    uint32_t           applicationVersion;
    const char*        pEngineName;
    uint32_t           engineVersion;
    uint32_t           apiVersion;
} VkApplicationInfo;

sType 和 pNext - 这里和 vkInstanceCreateInfo 结构体里的具有相同含义。

pApplicationName, applicationVersion, pEngineName, engineVersion - 这些是自由填充的字段,如果需要的话应用可以提供。一些tool, loader, layer, 或者driver 也许会在调试或者收集报告信息的时候使用这些字段来提供信息。对驱动而言,甚至可能会根据当前运行的应用来改变它们的操作。

apiVersion - 这个字段表明了用于编译应用的Vulkan API的major minor 和 patch level。如果你正在使用 Vulkan 1.0,major应该是1,minor应该是0。使用 vulkan.h里的VK_API_VERSION_1_0 宏定义就可以,这样的话patch level是0。patch level之间的不同应该不会影响不同版本的兼容性,区别仅仅在于patch level。通常来讲,你应该设置该字段为VK_API_VERSION_1_0,除非有其他特别的原因。


回到代码里

结构体填好以后,示例应用将创建instance:

VkInstance inst;
VkResult res;

res = vkCreateInstance(&inst_info, NULL, &inst);
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
    std::cout << "cannot find a compatible Vulkan ICD\n";
    exit(-1);
} else if (res) {
    std::cout << "unknown error\n";
    exit(-1);
}

vkDestroyInstance(inst, NULL);

在上述代码中,应用对最常见的错误做了一下快速检查,根据结果进行报告。请注意,成功的情况下(VK_SUCCESS)值为0,很多应用都为了便捷把非零值作为错误,这里也是这样做的。

最后,应用在退出之前销毁了instance。

现在你已经创建了一个 Vulkan instance,是时候来弄清你的 Vulkan instance都可以使用哪些图形设备了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值