首页 > 编程语言 >Vulkan Support Check and Dynamic Loader C++ code sample

Vulkan Support Check and Dynamic Loader C++ code sample

时间:2023-04-28 12:34:29浏览次数:42  
标签:info code physicalDeviceProperties Support VK Dynamic instance gpu vulkan

很多时候不想静态依赖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 }

 

标签:info,code,physicalDeviceProperties,Support,VK,Dynamic,instance,gpu,vulkan
From: https://www.cnblogs.com/hyb1/p/17361775.html

相关文章

  • 去除vscode顶部栏
    效果:(更高的屏幕占比) 1编辑:/Applications/VisualStudioCode.app/Contents/Resources/app/out/vs/code/electron-main/main.js2找到这行代码newI.BrowserWindow(Ne)改成newI.BrowserWindow({...Ne,frame:false})3设置nativetabs,nativetitle 重启vsco......
  • 产品质量管理利器,华为云发布CodeArts Defect缺陷管理服务
    摘要:近日,华为云CodeArtsDefect缺陷管理服务正式上线,提供结构化缺陷跟踪流程和标准化的质量度量模型。本文分享自华为云社区《产品质量管理利器,华为云发布CodeArtsDefect缺陷管理服务》,作者:华为云头条。美国管理学家彼得曾经说过,“决定水桶盛水量多少的关键因素不是其最长的板......
  • [Termux]更换Termux源 安装Debian容器并 设置Debian镜像源且 安装code-server(附安卓/
    前言Termux开发者称已经不会在GooglePlay上更新该应用了,要么在Github下载要么去F-Driod下载,为了方便下载,本文已经给出下载链接...GitHub下载链接:https://github.com/termux/termux-app/releases/download/v0.118.0/termux-app_v0.118.0+github-debug_universal.apk(GitHub......
  • Dynamic crm 使用JS 更新BPF的stage。
    functionupdateProcess(CurrentRecordId,stageId){ 'usestrict'; varfetchXml=  '<fetch>'+  " <entityname='new_approval_process'>"+  "  <attributename='businessprocessflo......
  • 【二分查找】LeetCode 153. 寻找旋转排序数组中的最小值
    题目链接153.寻找旋转排序数组中的最小值思路首先分析一下旋转数组可能有的状态:左<中<右,此时最小值肯定在左边,应当收缩右边界左<中,中>右,此时最小值肯定在右半段,应当收缩左边界左>中,中<右,此时最小值肯定在左半段,应当收缩右边界分析这三种状态可以发现,中值小......
  • 【LeetCode动态规划#14】子序列系列题(最长递增子序列、最长连续递增序列、最长重复子
    最长递增子序列力扣题目链接(opensnewwindow)给你一个整数数组nums,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列。示例1:输入:nums=[10,9,2,5,3,7......
  • Codeforces Round 867 (Div. 3)(A~D)
    目录A.TubeTubeFeed题意思路代码B.KarinaandArray题意思路代码C.BunLover题意思路代码D.Super-Permutation题意思路代码A.TubeTubeFeed题意给定时间\(t\),每个视频有一个价值\(b_i\),观看一个视频需要\(a_i\)秒,跳过一个视频需要花费\(1s\),求能观看完的价值最大......
  • #yyds干货盘点# LeetCode程序员面试金典:外观数列
    题目:给定一个正整数n,输出外观数列的第n项。「外观数列」是一个整数序列,从数字1开始,序列中的每一项都是对前一项的描述。你可以将其视作是由递归公式定义的数字字符串序列:countAndSay(1)="1"countAndSay(n)是对countAndSay(n-1)的描述,然后转换成另一个数字字符串。前五项......
  • Codeforces Round 867 (Div. 3)
    CodeforcesRound867(Div.3)A-TubeTubeFeed#include<bits/stdc++.h>usingnamespacestd;typedefpair<int,int>PII;typedefpair<string,int>PSI;constintN=50+5,INF=0x3f3f3f3f,Mod=1e6;constdoubleeps=1e-6;typedeflonglongll;......
  • AtCoder Regular Contest 126 E Infinite Operations
    洛谷传送门AtCoder传送门算是对这篇博客的补充吧。设\(a_1\lea_2\le\cdots\lea_n\)。发现最优操作中一定是对相邻的数进行操作,因为如果\(a_j\)想把\(x\)给\(a_i\)(\(i<j\)),最优是依次操作\((j-1,j,x),(j-2,j-1,x),...,(i,i+1,x)\)。这样\(x\)就能造成\((j-i)......