创建Vulkan实例

一、简介
Vulkan API使用vkInstance对象来存储所有每个应用的状态。应用程序必须在执行任何其他Vulkan操作之前创建一个Vulkan实例,基本的Vulkan架构看起来是这样的:
在这里插入图片描述
诚如前面几篇介绍Vulkan的教程而言,我们基于Adreno GPU SDK可以很轻易的实现图形的渲染,在高通开发者网站中也存在大量的与此相关的视频文档等资料,当然也可以在极客教程中进行基础学习,希望大家在此有所收获。
好了,接下来进入整体,我们应当如何创建Vulkan实例。

二、创建Vulkan实例
创建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(1, 0, 0);
appInfo.pEngineName = “No Engine”;
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_0;

如前所述,Vulkan中的许多数据结构要求在sType成员中明确的指定类型。pNext成员可用于指向特定的扩展结构。
Vulkan中的大量信息通过结构体而不是函数参数传递,我们将填充一个结构体以提供足够的信息创建instance。下一个结构体不是可选的,它需要告知Vulkan驱动程序我们需要使用哪些全局的 extensions 和 validation layers。这里的全局意味着它适用于整个程序,而不是特定的设备。
VkInstanceCreateInfo结构体信息如下:

typedef struct VkInstanceCreateInfo{
VkStructType sType;
const void* pNext;
VkInstanceCreateFlags flags;
const VkApplicationInfo* pApplicationInfo;
uint32_t enabledLayerCount;
const char* const* ppEnableLayerNames;
uint32_t enableExtensionCount;
const char* const* ppEnableExtensionNames;
}VkInstanceCreateInfo;

VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_INFO;
createInfo.pApplicationInfo = &appInfo;
Vulakn对于平台特性是零API支持的(至少暂时这样),这意味着需要一个扩展才能与不同平台的窗体系统进行交互。GLFW有一个方便的内置函数,返回它有关的扩展信息,我们可以传递给struct:
unsigned int glfwExtensionCount = 0;
const char** glfwExtensions;

glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);

createInfo.enabledExtensionCount = glfwExtensionCount;
createInfo.ppEnabledExtensionNames = glfwExtensions;

结构体的最后两个成员确定需要开启的全局的validation layers。
Createinfo.enabledLayerCount = 0;
接下来调用vkcreateInstance创建一个instance:
VkResult result = vkCreateInstance(&createInfo,nullptr,&instance);
在Vulkan中创建实例化相关的函数参数需要遵循:
1) 使用有关creation info 的结构体指针。
2) 使用自定义分配器回调的指针。
3) 使用保存新对象句柄的指针。
几乎所有的Vulkan函数都返回一个值为VK_SUCCESS或错误代码的VkResult类型的值。要检查instance是否已经成功创建,我们不需要保存结果,仅仅使用VK_SUCCESS值来检测即可:
if(vkCreateInstance(&createInfo,nullptr,&instance)!=VK_SUCCESS){
throw std::runtimer_error(“failed to create instance!”);
}
现在我们就可以运行程序,确认我们的instance是否创建成功。

检查可选功能:
在创建instance之前检索支持的扩展列表,通过vkEnumerateInstanceExtensionProperties函数。它指向一个变量,该变量存储扩展数量和一个VkExtensionProperties数组来存储扩展的详细信息。它也接受一个可选择的参数,允许我们通过特定的validation layers过滤扩展,现在我们暂时忽略这些。
要分配一个数组来保存扩展的详细信息,我们首先需要知道有多少个扩展存在。可以通过将后一个参数置空来获取扩展数量:
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr,&extensionCount,nullptr);
现在我们去分配一个集合去持有扩展的详细信息(include):
std::vector extensions(extensionCount);
最后我们可以遍历扩展的详细信息:
vkEnumerateInstanceExtensionProperties(nullptr,&extensionCount,extensions.data());
每个vkExtensionProperties结构体包含扩展的名称和版本,可以打印出来这些具体的信息:
std::cout << “available extensions:”<< std::endl;
for(const auto& extension : extensions){
std::cout << “\t” << extension.extensionName << std::endl;
}
如果需要获取有关Vulkan支持的一些详细信息,可以将此代码添加到createInstance函数。

退出:
在退出程序前,需要正确销毁VkInstance,这部分可以定义在cleanup函数中,调用vkDestroyInstance函数完成:
void cleanup(){
vkDestroyInstance(instance,nullptr);
glfwDestroyWindow(window);
glfwTerminate();
}

你可能感兴趣的:(Adreno,GPU)