加载全局级函数
译者注:示例代码点击此处
我们已经获得了vkGetInstanceProcAddr()函数,通过这个函数,我们可以以独立于OS的方式加载所有其他Vulkan API入口点。
Vulkan函数可分为全局函数、实例函数和设备函数三个层次。设备级函数用于执行典型的操作,如绘图、着色器模块创建、图像创建或数据复制。实例级函数允许我们创建逻辑设备。要加载设备和实例级函数,我们需要创建一个实例。这个操作是用全局级函数来执行的,我们需要先加载它。
怎么做...
1.创建一个类型PFN_vkEnumerateInstanceExtensionProperties名为vkEnumerateInstanceExtensionProperties的变量。
2.创建一个类型PFN_vkEnumerateInstanceLayerProperties名为vkEnumerateInstanceLayerProperties的不变量。
3.创建一个类型PFN_vkCreateInstance名为vkCreateInstance的变量。
4.调用vkGetInstanceProcAddr(nullptr,"vkEnumerateInstanceExtensionProperties"),将结果强转成PFN_vkEnumerateInstanceExtensionProperties类型,并赋值给vkEnumerateInstanceExtensionProperties变量。
5.调用vkGetInstanceProcAddr(nullptr,"vkEnumerateInstanceLayerProperties"),将结果强转成PFN_vkEnumerateInstanceLayerProperties类型,并赋值给vkEnumerateInstanceLayerProperties变量。
6.调用vkGetInstanceProcAddr(nullptr,"vkCreateInstance"),将结果强转成PFN_vkCreateInstance类型,并赋值给vkCreateInstance变量。
7.判断所有变量的值是否不等于nullptr,确认检查是否成功。
这个怎么运作...
在Vulkan中,只有三个全局级函数:vkEnumerateInstanceExtensionProperties()、vkEnumerateInstanceLayerProperties()和vkCreateInstance()。它们在实例创建期间用于检查哪些实例级扩展和层可用,以及创建实例本身。
获取全局级函数的过程类似于从Vulkan Loader导出的加载函数。这就是为什么最方便的方法是将全局级函数的名称添加到ListOfVulkanFunctions.inl文件中,如下:
#ifndef GLOBAL_LEVEL_VULKAN_FUNCTION
#define GLOBAL_LEVEL_VULKAN_FUNCTION( function )
#endif
GLOBAL_LEVEL_VULKAN_FUNCTION( vkEnumerateInstanceExtensionProperties )
GLOBAL_LEVEL_VULKAN_FUNCTION( vkEnumerateInstanceLayerProperties )
GLOBAL_LEVEL_VULKAN_FUNCTION( vkCreateInstance )
#undef GLOBAL_LEVEL_VULKAN_FUNCTION
如前所述需要加载全局级函数,我们不需要改变VulkanFunctions.h,只需要修改实现如下:
#define GLOBAL_LEVEL_VULKAN_FUNCTION( name ) \
name = (PFN_##name)vkGetInstanceProcAddr( nullptr, #name ); \
if( name == nullptr ) { \
std::cout << "Could not load global-level function named: " \
#name << std::endl; \
return false; \
}
#include "ListOfVulkanFunctions.inl"
return true;
自定义GLOBAL_LEVEL_VULKAN_FUNCTION宏获取函数名并将其提供给vkGetInstanceProcAddr()函数。它试图加载给定的函数,在失败的情况下,返回nullptr。由vkGetInstanceProcAddr()函数返回的结果都被转换到PFN_<name>类型,并存储在适当的变量中。
在失败的情况下,显示一条消息,以便用户知道哪个函数不能加载。