当前位置: 首页 > news >正文

Vulkan 学习(3)---- Vulkan 物理设备和队列组

目录

      • Vulkan 物理设备
        • 枚举出物理设备
        • 获取物理设备属性
        • 参考代码
      • Vulkan 队列组
        • 获取设备 QueueFamily 和 QueueFamilyProperty
        • 参考代码:

Vulkan 物理设备

Vulkan 物理设备 (PhysicalDevice) 一般是指支持 Vulkan 的物理硬件,通常是系统的一部分-- 显卡、加速器、数字信号处理器或者其他的组件。
系统里有固定数量的物理设备,每个物理设备都有自己的一组固定的功能

vulkan 编程中,我们通常需要枚举出所有的物理设备,并且找到我们需要的那个:
vulkan 编程模型

枚举出物理设备

使用 vkEnumeratePhysicalDevices 枚举出所有的物理设备:

VkResult vkEnumeratePhysicalDevices(VkInstance                                  instance,uint32_t*                                   pPhysicalDeviceCount,VkPhysicalDevice*                           pPhysicalDevices);
  • instance 是之前使用 vkCreateInstance 创建的 VkInstance handle
  • pPhysicalDeviceCount 是用于指定或获取的物理设备数量,通过这个值返回物理设备的数量
  • pPhysicalDevices 要么是 nullptr 要么是数量不小于 pPhysicalDeviceCountVkPhysicalDevice 数组,通过这个值返回物理设备的属性

需要注意的是,如果pPhysicalDeviceCount 中指定的数量小于系统中的物理设备数量,则 pPhysicalDevices 中写入的物理设备不是所有,vkEnumeratePhysicalDevices 只会写入传入的 pPhysicalDeviceCount 个物理设备属性到 pPhysicalDevices 并返回 VkResult::VK_INCOMPLET
如果所有物理设备成功写入,则会返回 VkResult::VK_SUCCESS

获取物理设备属性

使用 vkGetPhysicalDeviceProperties() 函数获取物理设备信息
获取到的 PhysicalDeviceProperties 的含义如下:

typedef struct VkPhysicalDeviceProperties {uint32_t                            apiVersion;uint32_t                            driverVersion;uint32_t                            vendorID;uint32_t                            deviceID;VkPhysicalDeviceType                deviceType;char                                deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];uint8_t                             pipelineCacheUUID[VK_UUID_SIZE];VkPhysicalDeviceLimits              limits;VkPhysicalDeviceSparseProperties    sparseProperties;
} VkPhysicalDeviceProperties;
  • apiVersion 该设备驱动支持的 Vulkan 版本
  • driverVersion 该设备驱动版本
  • vendorID 设备供应商的 ID
  • deviceID 设备的 ID
  • deviceType 设备类型
  • deviceName 设备名称
  • pipelineCacheUUID 设备的通用唯一识别码( universally unique identifier )
  • limits 设备的限制信息
  • sparseProperties 稀疏数据属性

其中的 deviceType 设备类型是下面的几种之一:

typedef enum VkPhysicalDeviceType {VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,// 集成显卡VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,// 独立显卡VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,// 虚拟环境中虚拟显卡VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,// 中央处理器VK_PHYSICAL_DEVICE_TYPE_CPU = 4,VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkPhysicalDeviceType;

一般首选使用 VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU 独立显卡,之后再考虑使用 VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU 集成显卡

参考代码

下面参考代码枚举出系统所有物理设备并且打印出了所有的物理设备属性:

void vulkanBasicDemo::vulkanCreatePhysicalDevice() {uint32_t physicalDeviceCount = 0;vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);std::cout << "physicalDeviceCount:" << physicalDeviceCount << std::endl;//枚举物理设备std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());for (const auto& device : physicalDevices) {VkPhysicalDeviceProperties deviceProperties;vkGetPhysicalDeviceProperties(device, &deviceProperties);std::cout << "apiVersion:" << deviceProperties.apiVersion << std::endl;std::cout << "driverVersion:" << deviceProperties.driverVersion << std::endl;std::cout << "vendorID:" << deviceProperties.vendorID << std::endl;std::cout << "deviceID:" << deviceProperties.deviceID << std::endl;std::cout << "deviceType:" << deviceProperties.deviceType << std::endl;std::cout << "deviceName:" << deviceProperties.deviceName << std::endl;// 这里可以根据应用程序的需求选择合适的设备if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {// 选择该设备physicalDevice = device;break;}}
}

结果如下:

vkInstance create success!.
vulkanBasicDemo construct
vulkanBasicDemo destruct
vkInstance create success!.
vulkanBasicDemo construct
physicalDeviceCount:1
apiVersion:4206856
driverVersion:1659737
vendorID:32902
deviceID:42912
deviceType:1
deviceName:Intel(R) Iris(R) Xe Graphics // 本机的显卡是 Intel 自带的集成显卡

Vulkan 队列组

Vulkan中,设备队列是一个重要概念,应用程序通过将指令记录到指令缓存,然后提交到队列,而物理设备会读取设备队列中的任务,并且通过异步方式进行处理

Vulkan_queue

每个物理设备都会包含一个或者多个队列组(Queue Family),每个队列组这种包含一个或者多个队列,这些队列用于处理不同的任务,比如图形渲染,计算任务和传输操作
Vulkan QueueFamilu
Vulkan 将设备队列按照队列组的方式进行组织,规则如下:

  1. 一个队列组可以支持一个或者多个功能
  2. 一个队列组中包含一个或者多个队列
  3. 同一个队列组中的所有队列支持相同的功能
  4. 队列族之间可以有相同的功能,但两两队列之间不能有两个功能集
获取设备 QueueFamily 和 QueueFamilyProperty
void vkGetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice                            physicalDevice,
uint32_t*                                   pQueueFamilyPropertyCount,
VkQueueFamilyProperties*                    pQueueFamilyProperties
);

使用上面的 vkGetPhysicalDeviceQueueFamilyProperties 或者设备的 QueueFamily信息,需要调用两次

使用vkGetPhysicalDeviceQueueFamilyProperties获取设备的QueueFamily属性,
其中 VkQueueFamilyProperties 定义如下:

typedef struct VkQueueFamilyProperties {VkQueueFlags    queueFlags;uint32_t        queueCount;uint32_t        timestampValidBits;VkExtent3D      minImageTransferGranularity;
} VkQueueFamilyPropertie
  • queueFlags是一个空白位码,表示队列族支持的操作类型
  • queueCount表示该队列中可用的队列数量
  • timestampValidBits表示时钟查询返回的有效时钟。该值为0表示该队列不支持时钟时钟。如果支持,时钟时钟返回的值将包含该时钟时钟的有效数据
  • minImageTransferGranularity表示该队列族支持的最小图像传输粒度。该粒度用于定义在执行图像传输操作(如复制或分层布局转换)时的最小单位

其中VkQueueFlags可用的值定义在VkQueueFlagBits中,定义如下:

typedef enum VkQueueFlagBits {VK_QUEUE_GRAPHICS_BIT = 0x00000001,//图形VK_QUEUE_COMPUTE_BIT = 0x00000002, //计算VK_QUEUE_TRANSFER_BIT = 0x00000004, //传输VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, //稀疏绑定// 由 VK_VERSION_1_1 提供VK_QUEUE_PROTECTED_BIT = 0x00000010,
} VkQueueFlagBits;

Vulkan 的设备队列是用于提交命令方便GPU执行的关键机制,理解队列组和设备队列的工作原理,有助于更好好的使用Vulkan功能特性

参考代码:

下面函数用于枚举出物理设备所有的QueueFamily,并且打印出QueueFamily属性:

void vulkanBasicDemo::VulkanEnumrateQueueFamily() {uint32_t queueFamilyCount;vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);std::cout << "PhysicalDeviceQueueFamilyCount:" << queueFamilyCount << std::endl;std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilyProperties.data());std::cout << "dump queueFamilyProperties:" << std::endl;for (const auto& queueFamilyPropery : queueFamilyProperties) {std::cout << "===================================" << std::endl;std::cout << "queueFamilyProperty queueFlags:" << queueFamilyPropery.queueFlags << std::endl;std::cout << "queueFamilyProperty queueFlags to string:" << queueflagtoString(queueFamilyPropery.queueFlags) << std::endl;std::cout << "queueFamilyProperty queueCount:" << queueFamilyPropery.queueCount << std::endl;}for (uint32_t i = 0; i < queueFamilyCount; i++) {if (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {graphicsQueueFamilyIndex = i;break;}}std::cout << "graphicsQueueFamilyIndex:" << graphicsQueueFamilyIndex << std::endl;
}

结果如下:

dump queueFamilyProperties:
===================================
queueFamilyProperty queueFlags:15
queueFamilyProperty queueFlags to string:graphics computes transfer sparse
queueFamilyProperty queueCount:1
===================================
queueFamilyProperty queueFlags:32
queueFamilyProperty queueFlags to string:video_decode
queueFamilyProperty queueCount:2
graphicsQueueFamilyIndex:0

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ARM编译器简介
  • C语言——查漏补缺
  • 手机CPU性能天梯图(2024年8月),含安兔兔/GB6/3DMark跑分
  • 架构师软考-每日两道单选题12
  • Java中的抽象类与接口
  • [Qt][布局管理器]详细讲解
  • 【Docker】Elasticsearch 8.12 安装与搭建
  • Python大数据分析——Kmeans聚类分析
  • 智驭灌区,科技领航—— 高效灌区信息化系统管理平台
  • 【面试常问之网络】网络故障排查方面
  • AtCoder Regular Contest 180 C. Subsequence and Prefix Sum (dp好题 辅助数组)
  • Go语言实现依赖注入
  • Git代码管理规范
  • 负载均衡详细概念介绍之(四层和七层实现)
  • 微信小程序怎样实现前后台交互?
  • Codepen 每日精选(2018-3-25)
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • Fundebug计费标准解释:事件数是如何定义的?
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • input实现文字超出省略号功能
  • java2019面试题北京
  • Meteor的表单提交:Form
  • PHP的Ev教程三(Periodic watcher)
  • Webpack 4x 之路 ( 四 )
  • windows下mongoDB的环境配置
  • Zepto.js源码学习之二
  • 每天10道Java面试题,跟我走,offer有!
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 算法-插入排序
  • 微信支付JSAPI,实测!终极方案
  • 原生js练习题---第五课
  • ​iOS安全加固方法及实现
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​补​充​经​纬​恒​润​一​面​
  • ​力扣解法汇总946-验证栈序列
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (3)STL算法之搜索
  • (c语言+数据结构链表)项目:贪吃蛇
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (十三)Maven插件解析运行机制
  • (四)Android布局类型(线性布局LinearLayout)
  • (原創) 未来三学期想要修的课 (日記)
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • ***测试-HTTP方法
  • .equals()到底是什么意思?
  • .gitignore
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .net refrector
  • .Net 高效开发之不可错过的实用工具
  • .NET开发者必备的11款免费工具
  • .pop ----remove 删除