操作系统:Windows8.1

显卡:Nivida GTX965M

开发工具:Visual Studio 2017


Creating an instance

与Vulkan打交道,通常的步骤是创建一个intance去初始化Vulkan library。这个instance是您的应用程序与Vulkan库之间的连接桥梁,通常创建过程中,需要向驱动程序提供一些应用层的信息。

首先添加一个createInstance函数,并在initVulkan函数中调用。

void initVulkan() {
createInstance();
}

另外添加一个类成员来保存instance句柄:

private:
VkInstance instance;

现在我们创建一个instance,并且为该数据结构赋予自定义应用程序的信息。这些数据从技术角度是可选择的,但是它可以为驱动程序提供一些有用的信息来优化程序特殊的使用情景,比如驱动程序使用一些图形引擎的特殊行为。这个数据结构称为VkApplicationInfo:

VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pNext = nullptr;
appInfo.pApplicationName = "Hello Triangle";
appInfo.applicationVersion = VK_MAKE_VERSION(, , );
appInfo.pEngineName = "No Engine";
appInfo.engineVersion = VK_MAKE_VERSION(, , );
appInfo.apiVersion = VK_API_VERSION_1_0;

如前所述,Vulkan中的许多数据结构要求在sType成员中明确的指定类型。pNext成员可用于指向特定的扩展结构。我们在这里使用默认初始化,将其设置为nullptr。

Vulkan中的大量信息通过结构体而不是函数参数传递,我们将填充一个结构体以提供足够的信息创建instance。下一个结构体不是可选的,它需要告知Vulkan驱动程序我们需要使用哪些全局的 extensions 和 validation layers。这里的全局意味着它适用于整个程序,而不是特定的设备,这些内容将在接下来的小节中说明。

VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;

前几个参数比较简单。接下来的两个指定需要的全局扩展,Vulakn对于平台特性是零API支持的(至少暂时这样),这意味着需要一个扩展才能与不同平台的窗体系统进行交互。GLFW有一个方便的内置函数,返回它有关的扩展信息,我们可以传递给struct:

unsigned int glfwExtensionCount = ;
const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); createInfo.enabledExtensionCount = glfwExtensionCount;
createInfo.ppEnabledExtensionNames = glfwExtensions;

结构体的最后两个成员确定需要开启的全局的validation layers。我们将会在下一节中深入探讨这部分内容,在这一节设置为空。

createInfo.enabledLayerCount = ;

我们现在已经指定了Vulkan创建一个实例需要的一切信息,调用vkCreateInstance创建属于我们的第一个instance:

VkResult result = vkCreateInstance(&createInfo, nullptr, &instance);

如你所见,Vulkan中创建、实例化相关的函数参数一般遵循如下原则定义:

  1. 使用有关creation info 的结构体指针
  2. 使用自定义分配器回调的指针
  3. 使用保存新对象句柄的指针

如果一切顺利,此刻instance的句柄应该存储在VkInstance类成员中了。几乎所有的Vulkan函数都返回一个值为VK_SUCCESS或错误代码的VkResult类型的值。要检查instance是否已经成功创建,我们不需要保存结果,仅仅使用 VK_SUCCESS 值来检测即可:

if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
throw std::runtime_error("failed to create instance!");
}

现在运行程序,确认我们的instance创建成功。

Checking for extension support


如果你查看vkCreateInstance的文档,你会看到一个可能出现的错误代码是VK_ERROR_EXTENSION_NOT_PRESENT。我们可以简单地指定我们需要的扩展,如果该错误代码返回,则终止它们。这对于窗体系统或者诸如此类的扩展是有意义的,那么如何检查可选功能呢?

在创建instance之前检索支持的扩展列表,通过vkEnumerateInstanceExtensionProperties函数。它指向一个变量,该变量存储扩展数量和一个VkExtensionProperties数组来存储扩展的详细信息。它也接受一个可选择的参数,允许我们通过特定的validation layers过滤扩展,现在我们暂时忽略这些。

要分配一个数组来保存扩展的详细信息,我们首先需要知道有多少个扩展存在。可以通过将后一个参数置空来获取扩展数量:

uint32_t extensionCount = ;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);

现在我们分配一个集合去持有扩展的详细信息(include <vector>)

std::vector<VkExtensionProperties> extensions(extensionCount);

最后我们可以遍历扩展的详细信息:

vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());

每个VkExtensionProperties结构体包含扩展的名称和版本。我们可以用简单的for循环打印他们(\t是缩进)

std::cout << "available extensions:" << std::endl;

for (const auto& extension : extensions) {
std::cout << "\t" << extension.extensionName << std::endl;
}

如果需要获取有关Vulkan支持的一些详细信息,可以将此代码添加到createInstance函数。作为一个尝试,创建一个函数,检查glfwGetRequiredInstanceExtensions返回的所有扩展是否都包含在受支持的扩展列表中。

Cleaning up


在程序退出前,请正确销毁VkInstance。这部分可以定义在cleanup函数中,调用vkDestroyInstance函数完成。

void cleanup() {
vkDestroyInstance(instance, nullptr); glfwDestroyWindow(window); glfwTerminate();
}

vkDestroyInstance函数的参数很简单。像之前小节提到的,Vulkan中的分配和释放功能有一个可选的分配器回调,我们通过将nullptr设置忽略。后续小节中创建的所有Vulkan相关资源,集中在cleanup函数中进行清理,且确保在销毁instance之前销毁。

在进行更复杂的内容之前,是时候了解validation layers了。

获取工程代码 GitHubcheckout

Vulkan Tutorial 03 理解Instance的更多相关文章

  1. Vulkan Tutorial 04 理解Validation layers

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 What are validation layers? Vulkan API的设计核 ...

  2. [译]Vulkan教程(03)开发环境

    [译]Vulkan教程(03)开发环境 这是我翻译(https://vulkan-tutorial.com)上的Vulkan教程的第3篇. In this chapter we'll set up y ...

  3. Vulkan Tutorial 05 物理设备与队列簇

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Selecting a physical device 通过VkInstance初始 ...

  4. Vulkan Tutorial 05 逻辑设备与队列

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 在选择要使用的物理设备之后,我们需要设置一个逻辑设备用于交 ...

  5. Vulkan Tutorial 07 Window surface

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 到目前为止,我们了解到Vulkan是一个与平台特性无关联的API集合.它不能直接与窗 ...

  6. Vulkan Tutorial 08 交换链

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 在这一章节,我们了解一下将渲染图像提交到屏幕的基本机制.这种机制成为交换链,并且需要 ...

  7. Vulkan Tutorial 11 Shader modules

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 与之前的图像API不同,Vulkan中的着色器代码必须以二进制字节码的格式使用,而不 ...

  8. Vulkan Tutorial 12 Fixed functions

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 早起的图形API在图形渲染管线的许多阶段提供了默认的状态.在Vulkan中,从vie ...

  9. Vulkan Tutorial 13 Render passes

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Setup 在我们完成管线的创建工作,我们接下来需要告诉Vulkan渲染时候使用的f ...

随机推荐

  1. LeetCode OJ:Count Primes(质数计数)

    Count the number of prime numbers less than a non-negative number, n. 计算小于n的质数的个数,当然就要用到大名鼎鼎的筛法了,代码如 ...

  2. 原创:Scala学习笔记(不断更新)

    Scala是一种函数式语言和面向对象语言结合的新语言,本笔记中就零散记下学习scala的一些心得,主要侧重函数式编程方面. 1. 以递归为核心控制结构. 实现循环处理的方式有三种:goto,for/w ...

  3. 【python】使用asyncore进行异步通信

    参考博文:http://blog.csdn.net/livefun/article/details/8721772 参考博文:https://www.cnblogs.com/tomato0906/ar ...

  4. asp.net viewstate 数据过大 导致错误

    当在ViewState中放入dataSet的数据量比较大的时候,当再点页面上的控件时,不会返回到后台,并且会出现如下错误: 或者是上面的12030改成500的错误. --解决方法:Viewstate绑 ...

  5. 前端之JavaScript 03

    window对象 所有浏览器都支持 window 对象.概念上讲.一个html文档对应一个window对象.功能上讲: 控制浏览器窗口的.使用上讲: window对象不需要创建对象,直接使用即可. W ...

  6. HDU - 6241 :Color a Tree(不错的二分)

    Bob intends to color the nodes of a tree with a pen. The tree consists of NN nodes. These nodes are ...

  7. 【转】C# Socket编程(2)识别网络主机

    [转自:https://www.cnblogs.com/IPrograming/archive/2012/10/11/CSharp_Socket_2.html] 一个客户端想要发起一次通信,先决条件就 ...

  8. LeetCode Optimal Division

    原题链接在这里:https://leetcode.com/problems/optimal-division/description/ 题目: Given a list of positive int ...

  9. lvds配置

    基于Altera FPGA的LVDS配置应用一例 在特权同学发表博文<Cyclone III的LVDS接口注意事项>后,不少网友发邮件询问LVDS具体应用的一些问题.这些网友,归根到底,估 ...

  10. is is not == !=之间的区别

    简单来说,python中的is与is not运算符可判断两个对象是否为同一对象.若为同一个对象,则对象1 is 对象2为True .反正,若非同一个对象,则对象1 is not 对象2为True 要理 ...