关于dll
介绍
Vulkan API 是硬件厂商提供的,在驱动里.安装Vulkan SDK后,开发者不用关心驱动层,可以通过(windows)vulkan-1.dll或(linux)libvulkan.so.1访问Vulkan API.
loadlibrary的方式
1 |
|
加载Vulkan API函数
方式
第一种方式:可以进行静态链接,并使用vulkan.h里定义的函数原型
第二种方式:不用vulkan.h了定义的原型,而是动态加载函数指针
第一种方式简单,但是每次调用函数时都会重定向一次,效率更低
第二种方式无重定向过程,且可以选择子集,但麻烦点,基本都用这种方式的,这里只介绍这种方式
方式
1.定义VK_NO_PROTOTYPES或者在引入vulkan.h前定义#define VK_NO_PROTOTYPES
2.创建新文件名为ListOfVulkanFunctions.inl
输入一下内容
1 |
|
创建头文件VulkanFunctions.h,输入一下内容
1 |
|
创建源文件VulkanFunctions.cpp,输入一下内容
1 |
|
通过在ListOfVulkanFunctions.inl中添加新的函数名可以加载更多vulkan api
函数名原型:name的原型为PFN_name
分为3类
global-level,instance-level,device-level
global-level
创建变量
PFN_vkEnumerateInstanceExtensionProperties
PFN_vkEnumerateInstanceLayerProperties
PFN_vkCreateInstance
并调用vkGetInstanceProcAddr获取到对于函数指针
在ListOfVulkanFunctions.inl中添加
1 |
|
在VulkanFunctions.cpp的#include “ListOfVulkanFunctions.inl”前添加
1 |
|
instance-level
变量声明一样的
1 | vkEnumeratePhysicalDevices |
不同之处是,调用vkGetInstanceProcAddr获取函数指针,第一个参数为instance
如何判断一个函数是instance-level还是device-level?
所有device-level函数第一个参数为VkDevice,VkQueue,VkCommandBuffer,因此所有第一个参数不是这些且不是global-level函数的就是device-level
需要额外注意的是,extensions能引入新的函数,需要加载它们,以便在程序中调用.
为了加载instance-level函数,对ListOfVulkanFunctions.inl进行更新
1 |
|
更新VulkanFunctions.cpp
1 |
|
1 |
|
device-level
创建logical device(VkDevice logical_device)后,需要渲染3D场景、计算对象碰撞,运行视频帧的时候
与前述基本一样,不同之处在于
调用vkGetDeviceProcAddr(device,”
“)获得函数指针
机核所有3D渲染软件都是使用device-level 函数进行工作的,它们用来创建buffers,images,samplers,shaders.使用device-level函数创建pipeline objects,同步primitives,framebuffers和很多其他资源.并且,最重要的,记录之后提交给queues让硬件执行的操作.
device-level函数可以通过vkGetInstanceProcAddr获取指针,但它不是最理想的.Vulkan被设计为灵活的API,它可以在单个程序里的多个devices上执行操作,但当我们调用vkGetInstanceProcAddr函数,我们不能提供任何与logical device关联的参数,因此这个函数返回的指针不能与device关联.device可能在调用vkGetInstanceProcAddr时都不存在,这是该调用返回一个dispatch函数–根据其参数,调用适用于给定的logical device的函数的实现.但是,这个jump有性能开销:很小但任然会消耗运行时间.
如果像避免这种不必要的jump且请求已给device的函数指针,我们需要调用vkGetDeviceProcAddr,这样能避免中间调用,这种方式有些缺陷:需要给app里所有device都请求各自的函数的函数指针.如果有多个device,需要给每个logical device自己的函数指针列表.使用C++预处理可以很容易获得已知device的函数的函数指针.
如何判断函数是device-level?
第一个参数是VkDevice,VkQueue,VkCommandBuffer
为了加载device-level函数,需要更新ListOfVulkanFunctions.inl
1 |
|
更新VulkanFunctions.cpp
1 |
|
释放Vulkan Loader library
1 |
|