很多时候不想静态依赖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. 学习 XQuery:XML数据查询的关键

    XQuery 是 XML 数据的查询语言,类似于 SQL 是数据库的查询语言.它被设计用于查询 XML 数据. XQuery 示例 for $x in doc("books.xml" ...

  2. steam社区留言红小作文模板

    steam社区留言红小作文模板 Dear steam: Im a steam user which most play csgo.i saw i had be banned in steam comm ...

  3. 力扣977(Java)-有序数组的平方(简单)

    题目: 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 示例 1: 输入:nums = [-4,-1,0,3,10]输出:[0,1, ...

  4. 力扣448(java)-找到数组中所有消失的数(简单)

    题目: 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内.请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果. 示例 ...

  5. 跃居AppStore第一!X-Engine如何支撑钉钉数据量激增

    钉钉作为国内领先的企业IM工具,在中国有超过亿级别的用户.随着新型冠状病毒肺炎疫情的爆发,大量的企业员工选择了soho模式,企业办公协同工具的需求瞬间爆发. 钉钉作为中国企业办公IM的首选应用,不仅具 ...

  6. DataFunTalk:阿里建设一站式实时数仓的经验分享

    简介: 本文内容整理于阿里资深技术专家姜伟华在DataFunTalk上的演讲,为大家介绍阿里巴巴基于一站式实时数仓Hologres建设实时数仓的经验和解决方案. 导读:大数据计算正从规模化走向实时化, ...

  7. 实时 OLAP, 从 0 到 1

    简介: BTC.com 团队在实时 OLAP 方面的技术演进过程及生产优化实践. 作者|高正炎 本文主要介绍 BTC.com 团队在实时 OLAP 方面的技术演进过程及生产优化实践,内容如下: 业务背 ...

  8. OpenKruise v0.10.0 版本发布:新增应用弹性拓扑管理、应用防护等能力

    简介: 阿里云开源的云原生应用自动化管理套件.CNCF Sandbox 项目 -- OpenKruise,今天发布 v0.10.0 新版本,这也会是 OpenKruise v1.0 之前的最后一个 m ...

  9. Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/xxx". at createRouterError 的说明和解决

    错误说明 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: & ...

  10. 2024 CKA考试

    一.考试形式 第一次考试可能有点紧张,训练时1小时不到搞定,考试用了1个半小时,记得考试前多练几次题目,就算紧张也可以在120分钟里考完,可以记住关键词去kubernetes.io中查找 考试模式:线 ...