3.2 缓冲区与图像资源


文档摘要

3.2 缓冲区与图像资源 本节摘要:Vulkan 只有两类数据资产:缓冲是一维字节数组,图像是带格式与维度解释的存储。本节讲清两者的参数体系——用法位决定能被谁使用、图像的五维属性决定它是什么、视图决定它被看成什么——并完整走一遍离屏渲染目标的创建流程。 缓冲与图像的正式定义可以这样给:缓冲是未经解释的一维字节序列,图像是自带格式语义的多维存储。前者靠你在着色器里自行解释字节含义,后者由硬件按格式直接理解。两者都遵循 3.1 节的三步绑定,但图像多出五维属性与视图规则——这些差异决定了各自的适用战场,也是本节的主线。 一、缓冲:用法位即准入印章 VkBufferCreateInfo 只有四个核心字段:size、usage、sharingMode、flags。

3.2 缓冲区与图像资源

本节摘要:Vulkan 只有两类数据资产:缓冲是一维字节数组,图像是带格式与维度解释的存储。本节讲清两者的参数体系——用法位决定能被谁使用、图像的五维属性决定它是什么、视图决定它被看成什么——并完整走一遍离屏渲染目标的创建流程。

缓冲与图像的正式定义可以这样给:缓冲是未经解释的一维字节序列,图像是自带格式语义的多维存储。前者靠你在着色器里自行解释字节含义,后者由硬件按格式直接理解。两者都遵循 3.1 节的三步绑定,但图像多出五维属性与视图规则——这些差异决定了各自的适用战场,也是本节的主线。

一、缓冲:用法位即准入印章

VkBufferCreateInfo 只有四个核心字段:size、usage、sharingMode、flags。其中 usage 是重点——它不是注释,而是准入印章:只有在使用位里声明过的能力,对应命令才会受理这个缓冲。漏写 TRANSFER_DST_BIT 的话,拷贝命令会当场退件;事后补用法的唯一办法是销毁重建(usage 不可变)。

用法位 授权的操作 典型资源
TRANSFER_SRC / DST 拷贝的源与目的 暂存缓冲、上传目标
VERTEX / INDEX 顶点装配读取 网格数据
UNIFORM_TEXEL_BUFFER 以格式化纹理视角读 常量数组
STORAGE_TEXEL_BUFFER 格式化读写 可写数据数组
STORAGE_BUFFER 字节级读写(SSBO) 粒子、变换缓冲
UNIFORM_BUFFER 常量块(UBO) 每对象参数
SHADER_DEVICE_ADDRESS 取设备地址供指针引用 光追场景数据

组合规则按需取交集:一张「先经暂存上传、再作顶点流、还要被计算着色器更新」的缓冲,就把三个对应位都写上。用法越多,驱动可选的放置方案越少,所以别无脑全开——每个位都要有真实的消费者。

二、图像:五维属性定义的资产

图像的信息密度比缓冲高一个量级。VkImageCreateInfo 的字段可以归成五个维度:维度形态(imageType:一维、二维、三维)与 extent;格式(VkFormat 决定每个纹素的解释,颜色、深度、压缩格式各有清单);mip 层数(mipLevels,主图加各级缩小版);数组层(arrayLayers,立方体贴图占六层、阴影级联各占一层);样本数(samples,多重采样的采样点数)。

两个属性值得单独展开。tiling:OPTIMAL(默认)由驱动决定物理排布,采样与渲染最快,但 CPU 无法直接解释其内存内容;LINEAR 排布可预测、可映射直写,但性能差且支持面收窄——它基本只用于「CPU 直写的小型上传纹理」这类边缘场景。usage 位:与缓冲同理,且交互更严格——既要采样又要渲染写入的图像必须同时声明 SAMPLED 与 COLOR_ATTACHMENT 两位。

图 3-2:从图像到视图:资产与使用面

图 3-2:从图像到视图:资产与使用面

三、视图:同一资产的多个使用面

VkImageView 是资源的「取景框」:从完整图像里框出一段(mip 区间、层区间、面别),并声明解释方式。交换链图像、帧缓冲附件、着色器采样,消费的都是视图而不是裸图像。一图多视图是常态——上图的四个视图来自同一张 VkImage。

VkImageViewCreateInfo vi = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}; vi.image = offscreenColor; // 3.1 节三步绑定后的资产 vi.viewType = VK_IMAGE_VIEW_TYPE_2D; vi.format = offscreenFormat; // 通常与图像一致,兼容时也可不同 vi.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; vi.subresourceRange.baseMipLevel = 0; vi.subresourceRange.levelCount = 5; // 只暴露前五级 mip vi.subresourceRange.baseArrayLayer = 0; vi.subresourceRange.layerCount = 1; VkImageView view; vkCreateImageView(device, &vi, NULL, &view);

aspectMask 是最容易错的一项:颜色图像用 COLOR 位,深度模板图像按需取 DEPTH、STENCIL 或两者;把深度图像的视图建成 COLOR 面是初学者高频错误,验证层的报错信息会直接点名。缓冲的对应物是 VkBufferView(把字节序列按格式解释成纹素数组),用得少,概念同源。

四、案例:离屏 HDR 渲染目标的完整手续

背景:后处理管线需要一张与屏幕等大、RGBA16F 格式、可采样可写入的离屏图像。初版实现采样正常但写入时验证层报「imageUsage 不含 COLOR_ATTACHMENT」。

操作:按五维体系重新过账。维度形态与 extent 对齐交换链尺寸;格式选 RGBA16F(查 vkGetPhysicalDeviceFormatProperties 确认支持 COLOR_ATTACHMENT 与 SAMPLED 两个特性位——格式不是万能的,每张格式在不同用法上要单独查询);用法位同时声明 COLOR_ATTACHMENT、SAMPLED、TRANSFER_DST(清屏与拷入用);mipLevels 取一(渲染目标无需 mipmap);样本数一;tiling 默认最优。然后按 3.1 的三步绑定显存,再为「作为附件用」与「作为采样用」分别建两个视图。

结果:后处理链正常工作。两个视图的分工让「写它」与「读它」各自拿到正确的取景框,渲染通道(第 4 章)的附件声明也直接引用了对应视图。

解读:这个案例浓缩了本节全部要点——格式要按用途查、用法位要按消费者开、视图按角色分裂。报错发生在写入阶段而不是创建阶段,说明用法位的核对发生在命令受理时,验证层的价值就是把这种「延迟爆炸」提前到当场。

变式:需要 mipmap 的常规纹理则相反:mipLevels 计满整条链,渲染只碰第零层视图,mip 生成用 vkCmdBlitImage 逐层搬迁(3.3 节实操)。同一套五维账本,不同资产算出不同配置。

五、选型速查

最后给一张决策便签。要存原始字节(网格、索引、通用数据),用缓冲加对应用法位。要硬件过滤采样,用图像加 SAMPLED。要被管线渲染写入,用图像加附件位并配视图进帧缓冲。要 CPU 直写直读,优先考虑缓冲加主机可见内存,图像的线性排布是退路而不是捷径。把这段口诀记牢,多数资源设计题三十秒内可以定案。

本节要点回顾

  • 两类资产:缓冲是无解释字节流、图像是带格式语义的存储,战场由数据是否需要硬件解释决定。
  • 用法位是印章:命令按位受理,漏位当场退件,事后唯一补救是销毁重建。
  • 图像五维:形态、格式、mip、层数、样本数,加上 tiling 与用法位构成完整资产描述。
  • 视图即取景框:mip 区间、层区间、面别三重框定,一图多视图是常态;面别与用法必须一致。
  • 格式按用途查:FormatProperties 的每类特性位单独确认,「支持这个格式」永远要追问「在哪类用法上支持」。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U