3.4 核心资源类型与显存布局


3.4 核心资源类型与显存布局

本节摘要:管线吃的数据住在资源里:顶点缓冲、索引缓冲、常量缓冲与纹理各有行为契约,堆与资源状态决定它们在显存里怎么放、怎么变。本节讲清四类资源的性格差异与放置策略,为第四章的描述符实验备好地基。

四类资源,四张性格标签

顶点缓冲是老实人:一份只读的坐标与属性数组,输入装配阶段按布局声明逐个取用。它的全部学问在 3.2 节已经见过——VBV 三元组与步长。索引缓冲是精打细算的管家:不存顶点,只存"用第几个顶点"的序号,让共享顶点不重复存储。立方体是标准例子:八个顶点加一份索引表,就描述了十二个三角形。常量缓冲是消息中继站:每帧从 CPU 往 GPU 送小体量高频数据(矩阵、时间、参数),它是下一章 4.1 节的主角,这里先记住两个性格——尺寸要 16 字节对齐、更新走"环状缓冲区"避免 CPU 与 GPU 抢同一块内存。纹理是四类里最复杂的一位:二维以上的像素阵列,带格式、 mip 链、采样行为三件套。

资源 典型更新频率 常见放置 关键注意点
顶点 / 索引缓冲 加载一次,长期只读 默认堆(GPU 专属) 经上传堆中转复制
常量缓冲 每帧或每物件 上传堆(CPU 可写) 16 字节对齐 · 环形复用
纹理 加载或流式更新 默认堆 采样器独立于纹理存在
交换链后备缓冲 每帧全量重写 系统按呈现优化 状态在呈现与渲染间切换

纹理与采样器:一对分家的搭档

纹理存数据,采样器定规则——D3D 把两者拆开,这是新手容易困惑的一处。同一张贴纹理,配不同采样器能呈现完全不同的观感:放大时取最近点还是线性插值,缩小时生成 mip 链与否,边缘越界后是重复、镜像还是钳制,全是采样器的参数。一份采样器可以被所有纹理共用,实践中游戏常备两三个预设(各向异性高清档、线性性能档、点素复古档)按材质分配。

Texture2D diffuseMap : register(t0); SamplerState anisoWrap : register(s0); float4 SampleAlbedo(float2 uv) { // 各向异性 + 环形寻址:地板与墙面这类斜视角纹理的常用组合 return diffuseMap.Sample(anisoWrap, uv); }

mip 链值得一提:同一纹理预生成逐级减半的副本,采样器按像素覆盖率自动选级——远处取小图省带宽、近处取大图保细节。纹理显存占用约增加三分之一,换取的画质与带宽双赢,是图形行业最划算的一笔"投资"之一。6.1 节讲带宽优化时会回到它。顺带记一条调试特征:mip 链缺失的症状很独特——远处纹理闪烁噪动、近看又正常;见到"远看闪"先查 mip,十拿九稳。

显存怎么放:堆、状态与驻留的三角关系

D3D 12 的显存管理有三组概念,初见容易绕晕,用一张装配图理清:

**堆(Heap)**是显存的"地块"。默认堆(DEFAULT)住 GPU 专属显存,性能最好但 CPU 摸不到;上传堆(UPLOAD)CPU 可写,数据从它中转进默认堆;回读堆(READBACK)让 CPU 读回 GPU 结果。3.2 节顶点缓冲直接住上传堆是"简化演示",正式项目里静态几何应复制进默认堆。

资源状态是地块上的"使用许可"。同一块缓冲此刻是顶点缓冲、下刻是拷贝目标,状态必须显式声明转换——这就是 3.2 节 ResourceBarrier 的全部意义:驱动靠它安排硬件级的等待与缓存失效。状态标错或漏标,轻则调试层报错,重则设备移除。

**驻留(Residency)**是资源"在不在场"。显存装不下所有资源时,系统可以把不常用的数据逐出显存;程序可以用 API 声明"这批资源马上要用,请留在场内"。开放世界流式加载(6.3 节)把驻留管理做成主动策略,这里先建立概念。

放置决策的口诀: 一次性上传、CPU 常写 → 上传堆,简单直接 长期只读、追求性能 → 默认堆 + 上传堆中转复制一次 GPU 结果要回读 → 回读堆(如截图、性能统计) 状态转换按需最小化 —— 每道屏障都有硬件代价,能合并就合并

压缩纹理:显存账本的第一课

谈显存布局,绕不开一个数字事实:一张 4096 见方的 RGBA 纹理,未压缩要吃掉约 64 MB 显存;一套现代游戏场景动辄上百张这样量级的贴图,显存瞬间见底。图形行业给出的答案不是通用压缩(zip 那类),而是 GPU 可以直接采样的固定速率压缩格式——BC 系列。它的核心思想是分块存储:把纹理切成 4 乘 4 的块,每块只存两个基准色加一份插值索引,块内像素用索引取色。一张块压缩后的纹理通常只有未压缩的四分之一到八分之一,且采样时硬件现场解压,无需 CPU 插手。

选格式的口诀按内容定:普通颜色贴图用 BC1(无透明)或 BC3(带透明);法线贴图用 BC5——它只为两个通道存高精度数据,第三个分量在采样时重建;灰度遮罩用 BC4 单通道。压缩纹理还顺手解决了带宽问题:同样一屏采样,搬运的数据量缩到几分之一,这正是 6.1 节带宽优化的头号手段。实践纪律只有一条:压缩必须在离线资产管线里完成,运行时压缩既慢又伤画质——资产处理一次,运行时受益终身。

一张 2048 见方纹理的显存账(粗算): RGBA 8 位未压缩 ......... 约 16 MB BC1 压缩 ............... 约 4 MB(四分之一) 加 13 级 mip 链 ......... 约 再加三分之一 结论:离线压一道 BC + 全量 mip 链,是质量与显存的最优平衡点

常见疑问:资源创建失败时,先查哪四件事

创建资源失败是初始化期的常客,排查按固定四问走。一问尺寸:是否超出预算(6.3 节的账本)或顶到尺寸上限——4K 六通道渲染目标一上,低显存卡当场拒绝。二问格式:该格式在当前功能级别下是否受支持——级别协商通过不代表所有格式全通,格式支持要单查。三问堆类型与用法是否匹配:比如给默认堆资源要求 CPU 直写,这类组合错误调试层会直说。四问设备是否还活着:设备移除后所有创建都会失败,根因在前面某帧——别在创建函数上浪费时间。四问过后仍失败,再转 5.1 节的环境对表路径。

案例复盘:一次纹理变黑的追凶

背景:某项目在低端机上偶发"模型纹理全黑、几何正常"。操作:先怀疑加载失败,查加载器日志无异常;开调试层无报错;最后用 PIX 抓帧,发现该纹理的描述符指向了已被释放的临时纹理——加载器把纹理存进局部容器,函数返回后容器析构,描述符悬空。结果:把纹理所有权移交给资源管理器,问题消失。解读:描述符只是引用,不是所有权——资源生命周期的失控不一定立刻崩,可能在数帧后才以视觉异常显形,这类"幽灵病灶"只有帧捕获工具能确诊。变式:团队随后加了一条规范——描述符创建处必须注明资源的所有者模块,代码评审按此检查,同类事故归零。

本节要点回顾

  • 四类资源四张脸:顶点缓冲老实、索引缓冲精算、常量缓冲高频小步快跑、纹理复杂三件套(格式、mip、采样)。
  • 纹理与采样器分家:数据与规则解耦,采样器预设按材质分配。
  • 显存三角:堆管放在哪,状态管怎么用,驻留管在不在场——三者拼出 D3D 12 的显存世界观。
  • 所有权纪律:描述符是引用不是所有权,资源生命周期要有人明确接管。

数据的地基打好,下一节讲手动挡驾驶舱最重的拨杆:渲染状态如何打包成管线状态对象。


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