Understanding Vulkan Objects

​ 和学习其他API一样,学习Vulkan API中有一个重要部分:了解Vulkan API定义了拿下类型,以及这些类型之间的关系。为了帮助理解这些类型,接下来会绘制一幅关系图,表现它们之间的关系,尤其是创建依赖关系。

​ 每个Vulkan类型都有一个特定的前缀Vk。这些前缀在下面的关系图中将会被省略。每个Vulkan函数都有一个特定前缀vk。举个例子:关系图中的Sampler,其实表示VkSampler。这些Vulkan类型不能被视为指针或者数字,把它理解成句柄是一个不错的方向,它是一个不透明的句柄。绿色背景对象的原始类型是uint32_t

​ 带箭头的实线表示创建顺序。举个例子,创建DescriptorSet之前,必选先创建DescriptorPool

​ 带实心菱形的实线表示包含关系,也就是说,该对象无需创建,直接从它的父对象中获取。举个例子:PhysicalDevice对象并不是创建的,而是从Instance对象中枚举的。

​ 虚线表示其他关系,比如:提交各种命令到CommandBUffer对象。

在这里插入图片描述
InstanceVulkan应用第一个创建的对象。它用于连接上层应用与Vulkan运行时驱动,因此,在上层应用中应该只创建一个。同时,它也用于存储Vulkan程序相关状态的软件结构,因此,所有上层应用想要使能的验证层或特性扩展,都应该在创建Instance时被指定。

PhysicalDevice:表示GPU硬件的抽象。上层应用可以从Instance对象中枚举得到物理设备,之所以是枚举的原因在于可以存在多个物理设备。同时,可以从PhysicalDevice对象中查询VendorIdDeviceId和所有支持的特性,以及相关属性和限制。

PhysicalDevice对象可以枚举得到所有可用的Queue Families。最主要的就是图形队列,其次还有计算队列或传输队列。

PhysicalDevice对象还可以枚举得到支持Memory HeapsMemory TypesMemory Heap表示特定的RAM池,它能抽象母板上的RAM、或GPU片上的RAM、或任何其他Host-Or-Device内存。在分配内存时,上层应用必须指定Memory Type,它承载了堆内存的特定需求,比如:Host-VisibleCoherent(CPU and GPU Visible)。根据不同的供应商,这些类型会有不同的组合。

Device:它是基于物理设备创建的逻辑设备。它是Vulkan API中最基本的对象,几乎所有对象的创建都会依赖它。在创建逻辑设备时,需要指定期望使能的设备特性,比如:各向异性纹理过滤。同时,上层应用也必须指明将会使用的队列,包括其索引和Queue Families

Queue:它接收指令,并将指令提交到GPU上去执行。所有GPU执行任务,都会填充到CommandBuffers中,然后提交到Queues,使用Vulkan API函数vkQueueSubmit。如果,上层应用分别制定了图形队列和计算队列,则可以将不同的CommandBuffers提交对应的队列。

CommandPool:它是一个简单的对象,唯一的功能就是分配CommandBuffer。它也需要指定Queue Family

CommandBuffer:它是从CommandPool对象中分配的。它表示在逻辑设备上执行各种指令的缓冲。在这个指令缓冲上面,上层应用可以填充各种各样的指令,所有指令都有相同的前缀vkCmd

Sampler:它不会被绑定到任何特定的Image上。它更像是一组状态参数,比如:滤波模式(nearest or linear),或寻址模式(repeat, clamp-to-edge, clamp-to-border)。

BufferImage是两种占用设备内存的资源类型。

Buffer是相对简单的那种,它是任意的二进制数据的容器,且以字节(Byte)为单位的长度。

Image则表示像素集合。在其他API中,被称之为纹理(textture)。上层应用创建一个Image时,有很多参数需要指定。比如:类型上可以分为1D,2D,3D;像素格式也有很多种(比如:R8G8B8A8_UNORM or R32_SFLOAT);也可以是一组离散图像,用于mipmap;Image在不同的驱动实现下,可以有两种内部组成格式(tilinglayout)。

创建一个Buffer或者Image,驱动并不会自动为之分配内存。上层应用需要分成3步去创建:

  • Allocate DeviceMemory
  • Create Buffer or Image
  • Bing them together using function vkBindBufferMemory or vkBindImageMemory

这就是为什么上层应用必须创建DeviceMemory对象,它代表了一块内存,按照指定的内存类型和按照字节为单位指定大小。同时,上层应用不应该为每一个BufferImage分别创建一个DeviceMemory。取而代之的是,上层应用应该批发一大块DeviceMemory用于众多BufferImage。这是因为,分配DeviceMemory是一个开销较大的操作,同时,驱动也限制了DeviceMemory分配的数量。这个限制可以在PhysicalDevice中查询。

这里有一个例外,SwapChain中的Image则不需要上层应用主动分配并绑定DeviceMemory

BufferImage被创建、绑定DeviceMemory,在渲染过程中也不能被直接使用。

BufferView:它必须依赖已经创建好的Buffer对象,才能被创建。同时,创建的时候必须传递偏移和范围,来表示该BufferView仅仅只是访问其中一部分。

ImageView:它必须依赖已经创建好的Image对象,才能被创建。同时,也必须传递一组参数,来限制该ImageView的访问范围和方式。

着色器访问这些资源(BufferImageSampler)的方式是描述符。但是,描述符本身并不存在,它们总是被被描述符集管理。在创建描述符集之前,应用程序必须先创建一个DescriptorSetLayout,它是用于定义描述符集的行为模板。举个例子:假设,应用程序的某个着色器需要如下资源:

Binding slotResource
0One uniform buffer(called constant buffer in DirectX) available to the vertex shader stage.
1Another uniform buffer available to the fragment shader stage
2A sampled image
3A sampler, also available to the fragment shader stage

在创建描述符集之前,应用程序需要创建一个DescriptorPool,它专用于分配DescriptorSet。在创建DescriptorPool之前,应用程序必须指定将来需要使用的描述符集的类型以及最大可分配数量。

最终,应用程序分配DescriptorSet所需要的前置对象包括DescriptorPoolDescriptorSetLayout

DescriptorSet表示保存实际描述符集的内存,可以对其进行配置,以便描述符集指向特定的BufferBufferViewImageSampler。应用程序可以通过掉用函数vkUpdateDescriptorSets

可以通过函数vkCmdBindDescriptorSetsCommandBuffer中需要使用的描述符集绑定。这个函数还需要PipelineLayout对象。它表示渲染管线的配置,指定描述符集的类型将会在CommandBuffer中使用。

FrameBuffer:应用程序可以创建一个FrameBuffer对象,必须指定RenderPassImageView数组。同时,它的数量和格式必须匹配RenderPass

Pipeline下次再看

Semaphore:它的创建无需参数,用于Queue之间的同步。

Event:它的创建无需参数,专用于GPUCPU之间的同步,调用的函数是vkCmdSetEventvkCmdResetEventvkCmdWaitEvent。同样,也可以在CPU的其他线程中调用函数vkGetEventStatus获取Event的状态。

参考:https://gpuopen.com/learn/understanding-vulkan-objects/

参考:https://docs.vulkan.org/spec/latest/chapters/pipelines.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/735635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

map和set(二)——AVL树的简单实现

引入 二叉搜索树有其自身的缺陷,假如往树中 插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成O(N),因此 map、set等关联式容器的底层结构是对二叉树进行了平衡处理,即采用平衡树来实现。简…

点投影到平面方程

点到平面的距离公式 如何计算点到平面距离 - 知乎 点到平面的投影 - 知乎

康奈尔开源近10万份审稿意见,未来论文发表或将由AI定夺

大语言模型(LLMs)的进步为自动化论文评审开辟了新途径,这些模型在学术反馈领域展现出巨大潜力。自动化评审的核心优势在于其能够精准指出论文草稿的不足之处,助力作者优化研究。尽管已有丰富的同行评审数据,但现有自动…

20.2 nginx

20.2 nginx 1. 学习目标2. 介绍2.1 正向代理2.2 反向代理2.3 动态静态资源分离2.4 nginx优缺点3. 安装3.1 Linux安装****************************************************************************************************************************************************…

AtCoder Beginner Contest 344 (A~F)

比赛地址传送门 A - Spoiler #include <bits/stdc.h> using namespace std; int main() {string line;cin>>line;int l0,rline.length()-1;while(line[l]!|) l;while(line[r]!|) r--;for(int i0;i<line.length();i) {if(i<l||i>r) cout<<line[i];…

基于stm32的流水灯设计

1基于stm32的流水灯设计[proteus仿真] 速度检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的自行车测速系统设计 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&#xffe5;&#xff0c…

《领导的气场——8堂课讲透中国式领导智慧》读书笔记

整体感悟 个人感觉书籍比较偏说教、理论&#xff0c;没有看完。 现仅仅摘录自己“心有戚戚焉”的内容。 经典摘录 管理的本质是通过别人完成任务。有一百件事情&#xff0c;一个人都做了&#xff0c;那只能叫勤劳&#xff1b;有一百件事情&#xff0c;主事的人自己一件也不做&…

js 获取浏览器相关的宽高尺寸

window 屏幕 屏幕分辨率的高&#xff1a; window.screen.height 屏幕分辨率的宽&#xff1a; window.screen.width 屏幕可用工作区高度&#xff1a; window.screen.availHeight 屏幕可用工作区宽度&#xff1a; window.screen.availWidth document 网页 网页可见区域宽&#xf…

shell 查询json文件的某一行并 替换json 键值字符串右边的内容(使用jq工具)

在shell中处理JSON文件时&#xff0c;直接通过shell命令行工具&#xff08;如sed&#xff09;进行精确的键值替换可能会比较困难和复杂&#xff0c;因为JSON数据结构需要解析器来正确识别键值对。推荐使用专门处理JSON的工具&#xff0c;如jq。 假设你有一个简单的JSON文件dat…

C语言学习--练习4(二维数组)

目录 1.统计有序数组中的负数 2.矩阵对角线元素和 3.最富有客户的资产总量 4.托普利兹矩阵 5.矩阵中的幸运数 6.二进制矩阵中的特殊位置 7.岛屿的周长 1.统计有序数组中的负数 //直接遍历二维数组即可 int countNegatives(int** grid, int gridSize, int* gridColSize) …

京东面试官问我,你在catch块中写业务代码吗?

文章目录 面试题背景我的理解实际运用场景 面试题背景 京东二面&#xff0c;面试官主要考察软实力吧。问了几个问题&#xff1a; 你觉得什么样的代码是好代码&#xff1f;平时你是如何做系统稳定性建设的&#xff1f;你在catch块中写过业务代码吗&#xff1f; 本文主要是谈谈…

比特币普通地址、隔离见证(兼容)、隔离见证(原生)、Taproot 地址傻傻分不清楚

我们在使用比特币钱包的时候&#xff0c;可以看到各种地址类型&#xff1a;普通地址、隔离见证&#xff08;兼容&#xff09;、隔离见证&#xff08;原生&#xff09;、Taproot 地址。 看得我们一脸懵逼&#xff0c;为什么会有这么多种类型的地址&#xff1f; 它们之间都有什么…

选修-单片机作业第1/2次

第一次作业 第二次作业 1、51 系列单片机片内由哪几个部分组成&#xff1f;各个部件的最主要功能是什么&#xff1f; 51系列单片机的内部主要由以下几个部分组成&#xff0c;每个部件的主要功能如下&#xff1a; 1. **中央处理器&#xff08;CPU&#xff09;**&#xff1a;这是…

图片上传组件

el-upload图片上传 背景代码 背景 项目需要多张图片上传回显&#xff0c;图片上传后返回图片ID&#xff0c;不返回url&#xff0c;需要通过图片ID获取token然后再拼接成图片下载的URL。选择el-upload组件进行开发。 file-list&#xff1a;文件列表&#xff0c;上传下载都需要…

线程池的执行流程

线程池是一种常见的并发编程模式&#xff0c;用于管理和复用线程以执行异步任务。其执行流程通常包括以下步骤&#xff1a; 初始化线程池&#xff1a; 在使用线程池之前&#xff0c;首先需要初始化线程池。在初始化过程中&#xff0c;需要指定线程池的参数&#xff0c;如线程池…

018-VUE框架优点

VUE框架优点 一句话总结 vue 作为一款轻量级框架&#xff0c;门槛低&#xff0c;上手快&#xff0c;简单易学&#xff1b;vue 可以进行组件化开发&#xff0c;数据与结构相分离&#xff0c;使代码量减少&#xff0c;从而提升开发效率&#xff0c;易于理解&#xff1b;vue 最突出…

装windows11+centos双系统时遇到问题及解决方法

从u盘启动提示linpus lite has been blocked 首先下载iso镜像文件&#xff0c;制作u盘启动工具&#xff0c;进行启动&#xff0c;这里进入bios界面进行启动项选择后&#xff0c;虽然已经将usb作为首要启动值 却会出现上图所示被“block”情形 需要在bios界面security选项&…

【数理统计实验(四)】方差分析

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

【动态规划】代码随想录算法训练营第四十四天 |完全背包,518. 零钱兑换 II , 377. 组合总和 Ⅳ (待补充)

完全背包理论基础 完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 完全背包和…

三、实战篇 优惠券秒杀

源码仓库地址&#xff1a;gitgitee.com:chuangchuang-liu/hm-dingping.git 1、全局唯一ID 数据库默认自增的存在的问题&#xff1a; id增长规律明显受单表数据量的限制 场景一分析&#xff1a;id如果增长规律归于明显&#xff0c;容易被用户或者商业对手猜测出一些敏感信息&…