Vulkan Support Check and Dynamic Loader C++ code sample
很多时候不想静态依赖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的更多相关文章
- OBJ Loader Source Code
https://github.com/ChrisJansson/ObjLoader http://www.codeproject.com/Articles/798054/SimpleScene-d-s ...
- 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 ...
- [译]Vulkan教程(03)开发环境
[译]Vulkan教程(03)开发环境 这是我翻译(https://vulkan-tutorial.com)上的Vulkan教程的第3篇. In this chapter we'll set up y ...
- Linux Programe/Dynamic Shared Library Entry/Exit Point && Glibc Entry Point/Function
目录 . 引言 . C/C++运行库 . 静态Glibc && 可执行文件 入口/终止函数 . 动态Glibc && 可执行文件 入口/终止函数 . 静态Glibc & ...
- 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 ...
- Dynamic Library Design Guidelines
https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100 ...
- Loader的初步学习笔记
Loader是一个异步加载数据的类,它和AsyncTask有类似也有不同,今天我们就先来学习下它.由于是对比学习,所以我们先来复习下AsyncTask的使用和特点. 一.AsyncTask 参考自:h ...
- Position Independent Code (PIC) in shared libraries
E原文地址:http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/下一文: ...
- [译]Vulkan教程(07)物理设备和队列家族
[译]Vulkan教程(07)物理设备和队列家族 Selecting a physical device 选择一个物理设备 After initializing the Vulkan library ...
- [译]Vulkan教程(05)Instance
[译]Vulkan教程(05)Instance Creating an instance 创建一个instance The very first thing you need to do is ini ...
随机推荐
- 关于mac使用figma以及企业微信3.1.18版本,CPU系统占用率飙升至70%
问题描述 使用一段时间正常,不知道是修改了什么设置,还是有什么软件冲突,导致cpu使用率极高 系统进程中有一个 kernel_task 占用了大量的cpu 并且该占用并不会消失,只要figma打开就会 ...
- 【笔记】Cross Join&lag与lead函数
Oracle Cross Join交叉连接 语法 CROSS JOIN 指定第一个表的所有行与第二个表的所有行连接.如果 table1 中有"x"行,table2 中有" ...
- 如何落地云原生DevOps?
简介: 什么是云原生DevOps?在阿里内部有怎样的实践?企业又该如何落地?阿里云云效专家团队提出了下一代精益产品开发方法体系--ALPD,提供了系统的云原生DevOps落地的方法支撑,帮助企业渐进式 ...
- 工商银行分布式服务C10K场景的解决方案
简介: 未来,中国工商银行将持续致力于 Dubbo 的金融级规模化应用. 作者:颜高飞,微服务领域架构师,主要从事服务发现.高性能网络通信等研发工作,擅长 ZooKeeper.Dubbo.RPC 协议 ...
- [Gin] 支持 FORM 和 JSON 参数的绑定与验证
Gin 支持对不同传参方式的参数进行统一绑定并验证,比如如下两种格式: Content-Type: application/x-www-form-urlencoded with a=XX&b= ...
- IIncrementalGenerator 解析 ValueTuple 的定义
本文将告诉大家如何在分析器里面解析代码里面对于 ValueTuple 的定义,包括如何获取 ValueTuple 里面的 Item 的类型和命名 开始之前先创建一个用来被分析的项目,在这个项目里面定义 ...
- 2018-11-14-git无法pull仓库refusing-to-merge-unrelated-histories
title author date CreateTime categories git无法pull仓库refusing to merge unrelated histories lindexi 201 ...
- Kafka 监听器详解
Kafka 监听器详解 Kafka Assistant 是一款 Kafka GUI 管理工具--管理Broker,Topic,Group.查看消费详情.监控服务器状态.支持多种消息格式. 目录 Kaf ...
- Linux中的umask
在Linux中,当创建一个文件或者目录的时候,系统会自动为这个文件或者目录赋予默认的权限,而umask命令就是用来控制这个默认权限的. 查看umask umask的查看有两种方式,一种不带选项-S,一 ...
- d3d12龙书阅读----绘制几何体(下)
d3d12龙书阅读----绘制几何体(下) 本节在上一节的基础上,对整个绘制过程进行优化,将绘制单个几何体的内容拓展到了多个几何体,同时对根签名进行了进一步地探索. 帧资源 在之前绘制每帧的结尾,我们 ...