Vulkan 开发(五):Vulkan 逻辑设备

图片来自《Vulkan 应用开发指南》
Vulkan 开发系列文章:
1. 开篇,Vulkan 概述
2. Vulkan 实例
3. Vulkan 物理设备
4. Vulkan 设备队列
在 Vulkan 中,逻辑设备(Logical Device)是与物理设备(Physical Device)交互的接口。它抽象了对特定 GPU (物理设备)的访问,使得应用程序能够提交命令并管理资源,而无需直接与物理硬件打交道。
举例来说,物理设备可能包含了三种队列:图形、计算和传输。但是逻辑设备创建的时候,可以只关联一个单独的队列(比如图形),这样我们就可以很方便地向队列提交指令缓存了。
创建逻辑设备
创建逻辑设备时,你需要指定你希望使用的队列族和队列、启用的扩展、以及一些其他特性。我们通过 vkCreateDevice() 函数创建逻辑设备。其定义如下:
vkCreateDevice
VkResult vkCreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice);
-
physicalDevice 指定在哪一个物理设备上创建逻辑设备。
-
pCreateInfo 创建逻辑设备的配置信息。
-
pAllocator 内存分配器。为 nullptr 表示使用内部默认分配器,否则为自定义分配器。
-
pDevice 创建逻辑设备的结果。
其中 VkDeviceCreateInfo 定义如下:
VkDeviceCreateInfo
typedef struct VkDeviceCreateInfo {
VkStructureType sType;
const void* pNext;
VkDeviceCreateFlags flags;
uint32_t queueCreateInfoCount;
const VkDeviceQueueCreateInfo* pQueueCreateInfos;
uint32_t enabledLayerCount;
const char* const* ppEnabledLayerNames;
uint32_t enabledExtensionCount;
const char* const* ppEnabledExtensionNames;
const VkPhysicalDeviceFeatures* pEnabledFeatures;
} VkDeviceCreateInfo;
-
sType 是该结构体的类型枚举值, 必须 是 VkStructureType::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO 。
-
pNext 要么是 NULL 要么指向其他结构体来扩展该结构体。
-
flags 目前没用上,为将来做准备。
-
queueCreateInfoCount 指定 pQueueCreateInfos 数组元素个数。
-
pQueueCreateInfos 指定 VkDeviceQueueCreateInfo 数组。用于配置要创建的设备队列信息。
-
enabledLayerCount 指定 ppEnabledLayerNames 数组元素个数。该成员已被 遗弃 并 忽略 。
-
ppEnabledLayerNames 指定要开启的验证层。该成员已被 遗弃 并 忽略 。
-
enabledExtensionCount 指定 ppEnabledExtensionNames 数组中元素个数。
-
ppEnabledExtensionNames 指定要开启的扩展。该数组数量必须大于等于 enabledExtensionCount 。
-
pEnabledFeatures 配置要开启的特性。
其中 queueCreateInfoCount 和 pQueueCreateInfos 用于指定在逻辑设备中需要创建的 设备队列 。其中 VkDeviceQueueCreateInfo 定义如下:
VkDeviceQueueCreateInfo
// 由 VK_VERSION_1_0 提供
typedef struct VkDeviceQueueCreateInfo {
VkStructureType sType;
const void* pNext;
VkDeviceQueueCreateFlags flags;
uint32_t queueFamilyIndex;
uint32_t queueCount;
const float* pQueuePriorities;
} VkDeviceQueueCreateInfo;
-
sType 是该结构体的类型枚举值, 必须 是 VkStructureType::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO 。
-
pNext 要么是 NULL 要么指向其他结构体来扩展该结构体。
-
flags 配置额外的信息。可设置的值定义在 VkDeviceQueueCreateFlagBits 枚举中。
-
queueFamilyIndex 指定目标设备队列族的索引。
-
queueCount 指定要在 queueFamilyIndex 中创建设备队列的数量。
-
pQueuePriorities 指向元素数量为 queueCount 的 float 数组。用于配置创建的每一个设备队列的优先级。
其中 queueFamilyIndex 必须 是目标物理设备中有效的设备队列族索引,并且 queueCount 必须小于等于 queueFamilyIndex 索引对应的设备队列族中的队列数量。
其中 pQueuePriorities 配置的优先级的有效等级范围为[0, 1] ,值越大,优先级越高。其中 0.0 是最低的优先级, 1.0 是最高的优先级。在某些设备中,优先级越高意味着将会得到更多的执行机会,具体的队列调由设备自身管理, Vulkan 并不规定调度规则。
设备扩展
前文创建实例的时候可以设置实例的扩展,在 VkDeviceCreateInfo 我们需要通过 enabledExtensionCount 和 ppEnabledExtensionNames 来指定该逻辑设备要开启的 设备扩展 ( Device Extension )。
在开启设备扩展之前,我们需要通过 vkEnumerateDeviceExtensionProperties(...) 函数获取目标设备支持的扩展。其定义如下:
vkEnumerateDeviceExtensionProperties
// 由 VK_VERSION_1_0 提供
VkResult vkEnumerateDeviceExtensionProperties(
VkPhysicalDevice physicalDevice,
const char* pLayerName,
uint32_t* pPropertyCount,
VkExtensionProperties* pProperties);
-
physicalDevice 要查询扩展的目标物理设备。
-
pLayerName 要么为 空 要么为 层 的名称。
-
pPropertyCount 要么为 空 要么为 pProperties 中元素的数量。
-
pProperties 为扩展信息数组。元素个数 必须 大于等于 pPropertyCount 中指定数量。
枚举设备扩展:
VkPhysicalDevice physicalDevice;//之前获取的物理设备;uint32_t extension_property_count = 0;
vkEnumerateDeviceExtensionProperties(physicalDevice, &extension_property_count, nullptr);std::vector<VkExtensionProperties> extension_properties(extension_property_count);
vkEnumerateDeviceExtensionProperties(physicalDevice, &extension_property_count, extension_properties.data());
有 几个常用的设备扩展:
-
VK_KHR_swapchain 交换链。用于与VK_KHR_surface 和平台相关的 VK_{vender}_{platform}_surface 扩展配合使用。用于窗口化显示渲染结果。
-
VK_KHR_display 某些平台支持直接全屏显示渲染结果(比如嵌入式平台:车载、移动平台等)。
-
VK_KHR_display_swapchain 全屏显示交换链。与 VK_KHR_display 扩展配合使用。
获取设备队列
在创建完逻辑设备后,就可以通过 vkGetDeviceQueue() 函数获取设备队列。其定义如下:
void vkGetDeviceQueue(
VkDevice device,
uint32_t queueFamilyIndex,
uint32_t queueIndex,
VkQueue* pQueue);
-
device 目标逻辑设备。
-
queueFamilyIndex 是前面获取的目标设备队列的队列族索引。
-
queueIndex 对应 VkDeviceQueueCreateInfo::queueCount 的对应设备队列索引, 用于区分创建的多个队列。
-
pQueue 对应 VkDeviceQueueCreateInfo::queueCount 创建的第 queueIndex 的设备队列。
创建逻辑设备示例
//获取目标队列族索引
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());// 找到支持图形操作的队列族
int graphicsQueueFamilyIndex = -1;
for (uint32_t i = 0; i < queueFamilyCount; i++) {if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {graphicsQueueFamilyIndex = i;break;}
}//定义队列创建信息
float queuePriority = 1.0f;
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = graphicsQueueFamilyIndex;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &queuePriority;//定义逻辑设备创建信息//设备扩展
std::vector<const char*> device_extensions;
device_extensions.push_back("VK_KHR_swapchain");VkDeviceCreateInfo deviceCreateInfo = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
deviceCreateInfo.ppEnabledExtensionNames = device_extensions.data();// 你可以在这里指定设备特性和扩展
VkPhysicalDeviceFeatures deviceFeatures = {};
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;//调用 vkCreateDevice 函数创建逻辑设备,并获取设备句柄。
VkDevice device;
if (vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device) != VK_SUCCESS) {throw std::runtime_error("failed to create logical device!");
}// 获取图形队列句柄
VkQueue graphicsQueue;
vkGetDeviceQueue(device, graphicsQueueFamilyIndex, 0, &graphicsQueue);//Vulkan 编程...//销毁逻辑设备
vkDestroyDevice(device, nullptr);
技术交流
进技术交流群/获取源码,添加我的微信:Byte-Flow
相关文章:
Vulkan 开发(五):Vulkan 逻辑设备
图片来自《Vulkan 应用开发指南》 Vulkan 开发系列文章: 1. 开篇,Vulkan 概述 2. Vulkan 实例 3. Vulkan 物理设备 4. Vulkan 设备队列 在 Vulkan 中,逻辑设备(Logical Device)是与物理设备(Physical D…...
Kafka 解决消息丢失、乱序与重复消费
一、引言 在分布式系统中,Apache Kafka 作为一种高吞吐量的分布式发布订阅消息系统,被广泛应用于日志收集、流式处理、消息队列等场景。然而,在实际使用过程中,可能会遇到消息丢失、乱序、重复消费等问题,这些问题可能…...
计算机专业毕业生面试工具推荐:白瓜面试
随着毕业季的临近,计算机专业的毕业生们即将步入职场,面试成为了他们必须面对的挑战。在这个过程中,选择合适的面试工具可以大大提高求职成功率。今天,我要向大家推荐一款专为计算机专业毕业生设计的面试工具——白瓜面试。 为什…...
数字IC开发:布局布线
数字IC开发:布局布线 前端经过DFT,综合后输出网表文件给后端,由后端通过布局布线,将网表转换为GDSII文件;网表文件只包含单元器件及其连接等信息,GDS文件则包含其物理位置,具体的走线࿱…...
高空作业未系安全带监测系统 安全带穿戴识别预警系统
在各类高空作业场景中,安全带是保障作业人员生命安全的关键防线。然而,由于人为疏忽或其他原因,作业人员未正确系挂安全带的情况时有发生,这给高空作业带来了巨大的安全隐患。为有效解决这一问题,高空作业未系安全带监…...
k8s的配置和存储(ConfigMap、Secret、Hostpath、EmptyDir以及NFS的服务使用)
ConfigMap 简介 在 Kubernetes 中,ConfigMap 是一种用于存储非敏感信息的 Kubernetes 对象。它用于存储配置数据,如键值对、整个配置文件或 JSON 数据等。ConfigMap 通常用于容器镜像中的配置文件、命令行参数和环境变量等。 ConfigMap 可以通过三种方…...
JS轮播图实现自动轮播、悬浮停止轮播、点击切换,下方指示器与图片联动效果
代码: <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…...
使用 Kafka 和 MinIO 实现人工智能数据工作流
MinIO Enterprise Object Store 是用于创建和执行复杂数据工作流的基础组件。此事件驱动功能的核心是使用 Kafka 的 MinIO 存储桶通知。MinIO Enterprise Object Store 为所有 HTTP 请求(如 PUT、POST、COPY、DELETE、GET、HEAD 和 CompleteMultipartUpload…...
力扣题86~90
题86(中等): python代码 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def partition(self, head: Optional[Li…...
【JavaEE】【多线程】定时器
目录 一、定时器简介1.1 Timer类1.2 使用案例 二、实现简易定时器2.1 MyTimerTask类2.2 实现schedule方法2.3 构造方法2.4 总代码2.5 测试 一、定时器简介 定时器:就相当于一个闹钟,当我们定的时间到了,那么就执行一些逻辑。 1.1 Timer类 …...
CI/CD 的原理
一、CI/CD 的概念 CI/CD是一种软件开发流程,旨在通过自动化和持续的集成、测试和交付实现高质量的软件产品。 CI(Continuous Integration)持续集成 目前主流的开发方式是协同开发,即多位开发人员同事处理同意应用不同模块或功能。 如果企业在同一时间将…...
进一步认识ICMP协议
在日常工作中,我们经常需要判断网络是否连通,相信大家使用较多的命令就是 ping啦。ping命令是基于 ICMP 协议来实现的,那么什么是 ICMP 协议呢?ping命令又是如何基于 ICMP 实现的呢? 今天这篇文章,我们就来…...
NUUO网络视频录像机upload.php任意文件上传漏洞复现
文章目录 免责声明漏洞描述搜索语法漏洞复现nuclei修复建议 免责声明 本文章仅供学习与交流,请勿用于非法用途,均由使用者本人负责,文章作者不为此承担任何责任 漏洞描述 NUUO网络视频录像机(Network Video Recorder࿰…...
WebGL 3D基础
1. 归一化函数 对一个向量进行归一化处理,即调整向量的模长(长度)为1,同时保持其方向不变。 // 归一化函数 function normalized(arr) {let sum 0;for (let i 0; i < arr.length; i) {sum arr[i] * arr[i];}const middle …...
Docker 部署MongoDb
1. 编写docker-compose.conf 文件 version: 3 services:mongo:image: mongo:latest # 指定 MongoDB 版本,确保 > 3.6container_name: mongo-replicarestart: alwayscommand: ["mongod", "--replSet", "rs0", "--oplogSize&…...
【Hadoop】hadoop的路径分不清?HDFS路径与本地文件系统路径的区别
/usr/local/hadoop /user/hadoop /home/hadoop/ 这里有些路径名很相似,帮我区分? 在Hadoop生态系统中,理解文件存储的位置对于有效管理数据至关重要。Hadoop分布式文件系统(HDFS)提供了一个高度可靠的存储系统…...
倪师学习笔记-天纪-易经八卦
一、简介 卦代表事情,爻代表时机,三爻为一卦八卦对应的天相,六十四卦对应人间事 二、八卦性 1、乾 天父亲向下看,无所求,雄心万丈始终如一,贞,坚心,专心至刚,天威&am…...
自动驾驶性能分析时,非常有用的两个信息
自动驾驶的关键路径如下,传感器的数据发送给感知模块;感知模块根据传感器数据来确定车辆所处的环境,比如前方有没有障碍物,是不是和车道线保持着适当的距离等;感知处理之后的数据传递给规控模块,规控根据车…...
数据结构 - 并查集
文章目录 一、并查集原理二、并查集实现三、并查集的应用 一、并查集原理 在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复…...
canvas基础+应用+实例
文章目录 Canvas基础知识要点一、基本概念二、常用参数三、实例四、场景应用说明完结 Canvas基础知识要点 一、基本概念 Canvas是HTML5中的一个标签,用于在网页上通过JavaScript绘制图形、动画等。它提供了一个空白的、基于像素的绘图区域,就像一块画布…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
