很多时候不想静态依赖VulkanSDK所提供的静态库,因为会遇到一些过早的电脑不支持vulkan,

那么就需要使用动态加载vulkan-1.dll(for Windows)或libMoltenVK.dylib(for MacOS)的方式进行判断了。

VulkanSDK提供了相关头文件实现可以做到相关功能,仅需要include一下头文件 `vulkan/vulkan.hpp`,不需要再额外链接它的vulkan-1.lib文件

本段代码包含三个部分:

1. 判断是否支持vulkan(简单判断)

2. 从系统动态链接库(显卡厂商提供的dll)动态加载Vulkan,然后初始化。

3. 实际使用导出的函数,去遍历此电脑所有支持vulkan的设备。

那么直接贴代码:

  1 #include "vulkan/vulkan.hpp"
2
3 struct GpuInfo
4 {
5 uint32_t api_version = 0;
6 uint32_t driver_version = 0;
7 uint32_t vendor_id = 0;
8 uint32_t device_id = 0;
9 char device_name[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] = {0};
10 // 0 = discrete gpu
11 // 1 = integrated gpu
12 // 2 = virtual gpu
13 // 3 = cpu
14 int type = 0;
15 };
16
17 std::vector<GpuInfo> gpuInfos;
18
19 bool isSupportVulkan = false;
20 std::unique_ptr<vk::DynamicLoader> vulkanDynamicLoader;
21 std::unique_ptr<vk::DispatchLoaderDynamic> vulkanDispatchLoaderDynamic;
22
23 try
24 {
25 #ifdef WIN32
26 std::string vulkanLibraryFilePath = "vulkan-1.dll";
27 #else //APPLE
28 std::string vulkanLibraryFilePath = diropt::CurrentPath() + "/Contents/Frameworks/libMoltenVK.dylib";
29 #endif
30 vulkanDynamicLoader = std::make_unique<vk::DynamicLoader>(vulkanLibraryFilePath);
31 }
32 catch(std::runtime_error& ex)
33 {
34 isSupportVulkan = false;
35 return -1;
36 }
37 if(!vulkanDynamicLoader)
38 {
39 isSupportVulkan = false;
40 return -1;
41 }
42 isSupportVulkan = vulkanDynamicLoader->success();
43 if(!isSupportVulkan)
44 {
45 isSupportVulkan = false;
46 return -1;
47 }
48 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = vulkanDynamicLoader->getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
49 if(!vkGetInstanceProcAddr)
50 {
51 isSupportVulkan = false;
52 return -1;
53 }
54
55 // 用vkGetInstanceProcAddr指针去创建默认的分发器对象并初始化
56 vulkanDispatchLoaderDynamic = std::make_unique<vk::DispatchLoaderDynamic>(vkGetInstanceProcAddr);
57
58 VkResult ret;
59 VkInstance g_instance;
60 uint32_t instance_api_version = VK_MAKE_VERSION(1, 0, 0);
61 typedef VkResult(VKAPI_PTR * PFN_vkEnumerateInstanceVersion)(uint32_t * pApiVersion);
62 PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion =
63 (PFN_vkEnumerateInstanceVersion)vulkanDispatchLoaderDynamic->vkGetInstanceProcAddr(0, "vkEnumerateInstanceVersion");
64 if (vkEnumerateInstanceVersion)
65 {
66 //列举vulkan实例的版本
67 ret = vkEnumerateInstanceVersion(&instance_api_version);
68 if (ret != VK_SUCCESS)
69 {
70 return -1;
71 }
72 }
73
74 VkApplicationInfo applicationInfo;
75 applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
76 applicationInfo.pNext = 0;
77 applicationInfo.pApplicationName = "vulkan-check";
78 applicationInfo.applicationVersion = 0;
79 applicationInfo.pEngineName = "vulkan-check";
80 applicationInfo.engineVersion = 20230447;
81 applicationInfo.apiVersion = instance_api_version;
82
83 VkInstanceCreateInfo instanceCreateInfo;
84 instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
85 instanceCreateInfo.pNext = 0;
86 instanceCreateInfo.flags = 0;
87 instanceCreateInfo.pApplicationInfo = &applicationInfo;
88 instanceCreateInfo.enabledLayerCount = 0;
89 instanceCreateInfo.ppEnabledLayerNames = 0;
90 instanceCreateInfo.enabledExtensionCount = 0;
91 instanceCreateInfo.ppEnabledExtensionNames = 0;
92
93 VkInstance instance = 0;
94 //创建Vulkan实例
95 ret = vulkanDispatchLoaderDynamic->vkCreateInstance(&instanceCreateInfo, 0, &instance);
96 if (ret != VK_SUCCESS)
97 {
98 return -1;
99 }
100 g_instance = instance;
101
102 //再用已经创建好的Vulkan实例去进一步初始化vulkanDispatchLoaderDynamic
103 vulkanDispatchLoaderDynamic->init(instance, vkGetInstanceProcAddr);
104
105 //获取所有支持vulkan的设备列表
106 uint32_t physicalDeviceCount = 0;
107 ret = vulkanDispatchLoaderDynamic->vkEnumeratePhysicalDevices(g_instance, &physicalDeviceCount, 0);
108 if (ret != VK_SUCCESS)
109 {
110 return -1;
111 }
112 #define NCNN_MAX_GPU_COUNT 8
113 if (physicalDeviceCount > NCNN_MAX_GPU_COUNT)
114 physicalDeviceCount = NCNN_MAX_GPU_COUNT;
115
116 std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
117 //列举所有支持Vulkan的物理设备
118 ret = vulkanDispatchLoaderDynamic->vkEnumeratePhysicalDevices(g_instance, &physicalDeviceCount, physicalDevices.data());
119 if (ret != VK_SUCCESS)
120 {
121 return -1;
122 }
123
124 int gpu_info_index = 0;
125 for (uint32_t i = 0; i < physicalDeviceCount; i++)
126 {
127 const VkPhysicalDevice& physicalDevice = physicalDevices[i];
128
129 // device type
130 VkPhysicalDeviceProperties physicalDeviceProperties;
131 vulkanDispatchLoaderDynamic->vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
132
133 // info
134 GpuInfo gpu_info;
135 gpu_info.api_version = physicalDeviceProperties.apiVersion;
136 gpu_info.driver_version = physicalDeviceProperties.driverVersion;
137 gpu_info.vendor_id = physicalDeviceProperties.vendorID;
138 gpu_info.device_id = physicalDeviceProperties.deviceID;
139 memset(gpu_info.device_name, 0, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
140 memcpy(gpu_info.device_name, physicalDeviceProperties.deviceName, strlen(physicalDeviceProperties.deviceName));
141
142 if (physicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_OTHER)
143 gpu_info.type = 0;
144 else if (physicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
145 gpu_info.type = 1;
146 else if (physicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
147 gpu_info.type = 2;
148 else if (physicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)
149 gpu_info.type = 3;
150 else if (physicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)
151 gpu_info.type = 4;
152 else
153 gpu_info.type = -1;
154
155 gpu_info_index++;
156 gpuInfos.emplace_back(gpu_info);
157 }

Vulkan Support Check and Dynamic Loader C++ code sample的更多相关文章

  1. OBJ Loader Source Code

    https://github.com/ChrisJansson/ObjLoader http://www.codeproject.com/Articles/798054/SimpleScene-d-s ...

  2. Java Thread Local – How to use and code sample(转)

    转载自:https://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/ Thread Local ...

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

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

  4. Linux Programe/Dynamic Shared Library Entry/Exit Point && Glibc Entry Point/Function

    目录 . 引言 . C/C++运行库 . 静态Glibc && 可执行文件 入口/终止函数 . 动态Glibc && 可执行文件 入口/终止函数 . 静态Glibc & ...

  5. Linking code for an enhanced application binary interface (ABI) with decode time instruction optimization

    A code sequence made up multiple instructions and specifying an offset from a base address is identi ...

  6. Dynamic Library Design Guidelines

    https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100 ...

  7. Loader的初步学习笔记

    Loader是一个异步加载数据的类,它和AsyncTask有类似也有不同,今天我们就先来学习下它.由于是对比学习,所以我们先来复习下AsyncTask的使用和特点. 一.AsyncTask 参考自:h ...

  8. Position Independent Code (PIC) in shared libraries

    E原文地址:http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/下一文: ...

  9. [译]Vulkan教程(07)物理设备和队列家族

    [译]Vulkan教程(07)物理设备和队列家族 Selecting a physical device 选择一个物理设备 After initializing the Vulkan library ...

  10. [译]Vulkan教程(05)Instance

    [译]Vulkan教程(05)Instance Creating an instance 创建一个instance The very first thing you need to do is ini ...

随机推荐

  1. 百度AIPNLP 文本相似度 文本审核

    效果不如有监督的bert文本相似度好 from aip import AipNlp APP_ID = "22216281" APT_KEY = "foEeYauuvnqW ...

  2. Spark3.0 Standalone模式部署

    之前介绍过Spark 1.6版本的部署,现在最新版本的spark为3.0.1并且已经完全兼容hadoop 3.x,同样仍然支持RDD与DataFrame两套API,这篇文章就主要介绍一下基于Hadoo ...

  3. 力扣570(MySQL)-至少有5名直接下属的经理(简单)

    题目: Employee 表包含所有员工和他们的经理.每个员工都有一个 Id,并且还有一列是经理的 Id. 给定 Employee 表,请编写一个SQL查询来查找至少有5名直接下属的经理.对于上表,您 ...

  4. 【pytorch学习】之自动微分

    5 自动微分 求导是几乎所有深度学习优化算法的关键步骤.虽然求导的计算很简单,只需要一些基本的微积分.但对于复杂的模型,手工进行更新是一件很痛苦的事情(而且经常容易出错).深度学习框架通过自动计算导数 ...

  5. 基于 Wasm 和 ORAS 简化扩展服务网格功能

    简介: 本文将介绍如何使用 ORAS 客户端将具有允许的媒体类型的 Wasm 模块推送到 ACR 注册库(一个 OCI 兼容的注册库)中,然后通过 ASM 控制器将 Wasm Filter 部署到指定 ...

  6. Service Mesh 从“趋势”走向“无聊”

    简介: 过去一年,阿里巴巴在 Service Mesh 的探索道路上依旧扎实前行,这种坚定并非只因坚信 Service Mesh 未来一定是云计算基础技术的关键组成部分,还因需要借这一技术趋势去偿还过 ...

  7. [FE] jsoneditor 在 vue-router 和 vue-ssr 渲染下出现两个实例的问题

    由于 vue-router 页面是无刷新的,如果存在两次渲染,会出现如下情形. 简单粗暴的解决办法是通过判断容器中是否已经有了子节点. 此时再从其他 router link 返回就不会重复渲染了. M ...

  8. [Contract] truffle-flattener 合并 Solidity 文件的依赖到一个文件

    使用 $ npm install truffle-flattener -g $ truffle-flattener <solidity-files> > output.sol 为什么 ...

  9. 通过Google浏览器Cookie文件获取cookie信息,80以上版本有效

    public class ReadCookie { /// <summary> /// </summary> /// <param name="hostName ...

  10. 《Effective C++》第三版-0. 导读(Introduction)

    目录 术语(Terminology) 命名习惯(Naming Conventions) 关于线程(Threading Consideration) TR1和Boost 术语(Terminology) ...