04-texture-samplers

第 4 篇:纹理采样器(Texture Samplers)

原文:Part 4

一句话定位

纹理采样不是一次普通 load,而是一条由资源视图、采样状态、坐标、LOD、地址模式、过滤与格式解码共同决定的高延迟数据路径。

一次采样包含什么

flowchart LR A[shader 坐标/梯度] --> B[LOD 与各向异性判断] S[Sampler State] --> B R[Resource View] --> C[地址与格式解释] B --> C C --> D[纹理缓存/内存请求] D --> E[解压与格式转换] E --> F[过滤与结果返回]

三类状态要分开

  • 资源决定实际存储与布局,例如尺寸、mip 层、数组层和底层内存。
  • 资源视图决定以什么格式和子资源范围解释同一份存储。
  • 采样器状态决定寻址模式、min/mag/mip 过滤、LOD 限制、比较采样和各向异性等行为。

把它们分离可以复用资源,也让硬件描述符更紧凑;代价是驱动必须验证组合是否合法,并处理别名与读写冲突。

LOD、梯度与过滤

纹理坐标在屏幕上变化得越快,单个像素覆盖的纹理区域越大,越需要选择更低分辨率的 mip 以避免混叠。像素阶段通常由邻近 lane 的坐标差估计梯度;显式 LOD 或显式梯度指令则由 shader 提供选择依据。

双线性过滤会读取某一 mip 附近的多个 texel 并加权;三线性会在两个 mip 的过滤结果间再插值;各向异性过滤会针对狭长 footprint 取更多样本。API 中一个“sample”可能展开成多次地址计算、缓存访问与插值。

缓存与压缩

二维空间局部性使纹理缓存有效:相邻像素往往访问相邻 texel。纹理采用 tiled/swizzled 布局,也是为了让二维邻域落入较少缓存线和内存事务。块压缩纹理减少外部带宽;数据在靠近采样端的位置解压,再参与过滤。

缓存只能改善有局部性的访问。随机索引、极端放大/缩小、跨大范围的各向异性采样,都会提高缺失率与请求数。性能分析要同时看 shader 发出多少 sample、每个 sample 展开多少 texel、缓存命中和实际外部带宽。

术语对照

英文 中文理解 备注
SRV / texture view 纹理/资源视图 定义解释格式与子资源范围
sampler state 采样器状态 过滤、寻址、LOD 等
mipmap 多级渐远纹理 预过滤后的多分辨率层级
derivative / gradient 导数/梯度 用于估计屏幕像素的纹理 footprint
anisotropic filtering 各向异性过滤 处理方向差异明显的 footprint
swizzle / tiling 重排/分块布局 增强二维局部性,非线性行优先

面向 UMD/KMD 的阅读提示

  • UMD:追踪 image/sampler descriptor 的构建,特别是 format、swizzle、mip offsets、tiling mode 与压缩元数据。
  • 查 shader lowering:哪些采样操作变成目标 ISA 的 texture 指令,隐式梯度在哪些 shader stage 合法?
  • KMD 通常不解释过滤语义,但必须保证纹理 BO、页表和压缩/辅助表在执行期间有效。
  • 资源从 render target 转为 texture 时,检查是否需要 cache flush、layout transition、decompress/resolve;这类命令体现“上一个写者 → 下一个读者”的可见性关系。

自测与实验

  • 为什么像素 shader 能自然获得隐式梯度,而计算 shader 通常需要显式 LOD/梯度?
  • 同一存储建立不同格式视图时,哪些组合只改变解释,哪些可能触发不可兼容的压缩/布局限制?
  • 用 GPU counter 比较顺序纹理访问和随机纹理访问,区分指令数量与 cache miss 的影响。

本篇总结

纹理单元是一条专门优化的“地址生成 + 缓存 + 解码 + 过滤”流水线;它省下 shader 指令,却仍受局部性和带宽支配。

posted @ 2026-10-26 21:57  Sailxiv  阅读(3)  评论(0)    收藏  举报