创建Vulkan实例
译者注:示例代码点击此处
Vulkan实例是一个收集应用程序状态的对象。它包含诸如应用程序名称、引擎的名称和版本之类的信息,或启用实例级扩展和层。
通过实例,我们还可以枚举可用的物理设备并创建逻辑设备,在这些逻辑设备上执行典型的操作,例如图像创建或绘图。因此,在使用Vulkan API之前,我们需要创建一个新的实例对象。
怎么做...
1.准备一个名为desired_extensions的std::vector<charconst*>类型变量。会在这个变量中储存所有扩展名。
2.创建一个名为available_extensions的std::vector<VkExtensionProperties>类型变量。获取到的所有可用扩展会储存在此(参见检查可用实例扩展)。
3.检查确保desired_extensions的每个扩展名,也存在于available_extensions变量中。
4.准备一个名为application_info的VkApplicationInfo类型变量。
1.sType设为VK_STRUCTURE_TYPE_APPLICATION_INFO。
2.pNext设为nullptr。
3.pApplicationName写你的应用名称。
4.applicationVersion结构体成员设置应用程序版本。用VK_MAKE_VERSION宏为其成员major、minor和patch赋值。
5.pEngineName写引擎的名称。
6.engineVersion用VK_MAKE_VERSION宏设置引擎版本。
7.apiVersion设为VK_MAKE_VERSION( 1, 0, 0 )。
5.准备一个名为instance_create_info的VkInstanceCreateInfo类型变量。并设置起成员。
1.sType设为VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO。
2.pNext设为nullptr。
3.flags设为0。
4.pApplicationInfo设为application_info。
5.enabledLayerCount设为0。
6.ppEnabledLayerNames设为nullptr。
7.enabledExtensionCount设为desired_extensions的元素数。
8.ppEnabledExtensionNames设为指向desired_extensions第一个元素的指针(或者如果为空设置成nullptr)
6.准备一个名为instance的VkInstence类型变量。
7.调用vkCreateInstance( &instance_create_info, nullptr, &instance )函数,第一个参数是指向instance_create_info变量,第二个参数为nullptr,第三个参数指向instance变量。
8.检查vkCreateInstance()的返回值是否等于VK_SUCCESS来确保操作成功。
这个怎么运作...
要创建实例,我们需要准备一些信息。 首先,我们需要创建一个我们想要启用的实例级扩展名称数组。 接下来,我们需要检查它们是否在给定硬件上受支持。 这是通过获取所有可用实例级扩展的列表并检查它是否包含我们要启用的所有扩展的名称来完成的:
std::vector<VkExtensionProperties> available_extensions;
// 译者注:获取所有支持的实例扩展
if( !CheckAvailableInstanceExtensions( available_extensions ) ) {
return false;
}
// 译者注:检查期望使用的扩展在不在可用扩展列表里
for( auto & extension : desired_extensions ) {
if( !IsExtensionSupported( available_extensions, extension ) ) {
std::cout << "Extension named '" << extension << "' is not supported." << std::endl;
return false;
}
}
接下来,需要创建一个变量,在其中提供有关应用程序的信息,例如其名称和版本,用于创建应用程序的引擎的名称和版本,以及我们要使用的Vulkan API的版本( 现在API只支持最初的版本):
译者注:在翻译此文时我使用的是vulkansdk-macos-1.1.85.0版本。
VkApplicationInfo application_info = { //译者注
VK_STRUCTURE_TYPE_APPLICATION_INFO, //sType
nullptr, //pNext
application_name, //pApplicationName
VK_MAKE_VERSION( 1, 0, 0 ), //applicationVersion
"Vulkan Cookbook", //pEngineName
VK_MAKE_VERSION( 1, 0, 0 ), //engineVersion
VK_MAKE_VERSION( 1, 0, 0 ) //apiVersion
};
application_info的地址会提供给下面的instance_create_info变量,instance_create_info其中包含用于创建实例的实际参数,除了application_info的指针之外,我们还提供了有关想要启用的扩展数量和名称,以及我们想要启用的层数量和名称,创建Instance对象既不需要扩展也不需要层,只是如果没有这些扩展,将很难创建一个功能齐全的应用程序,因此建议使用它们,可以安全地忽略层。一下是准备用于定义实例参数的变量实例代码:
VkInstanceCreateInfo instance_create_info = { //译者注
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, //sType
nullptr, //pNext
0, //flags
&application_info, //pApplicationInfo
0, //enabledLayerCount
nullptr, //ppEnabledLayerNames
static_cast<uint32_t>(desired_extensions.size()), //enabledExtensionCount
desired_extensions.size() > 0 ? &desired_extensions[0] : nullptr //ppEnabledExtensionNames
};
最后,当我们准备好前面的数据时,我们就可以创建Instance对象了。这是通过vkCreateInstance()函数完成的,它的第一个参数必须指向VkInstanceCreateInfo类型的变量。第三个函数必须指向VkInstance类型的变量创建好的是实例句柄将储此。第二个参数很少使用:它指向VkAllocationCallbacks类型的变量,其中定义了分配器回调函数。这些函数控制主机内存的分配方式,主要用于调式目的,大多数情况下会把他设置为nullptr。
VkResult result = vkCreateInstance( &instance_create_info, nullptr, &instance );
if( (result != VK_SUCCESS) || (instance == VK_NULL_HANDLE) ) {
std::cout << "Could not create Vulkan Instance." << std::endl;
return false;
}
return true;