Pipeline State Object
全库目录221
本文目录9
同一个着色器先画普通颜色,再画不同格式的目标或开启MSAA,可能需要不同的管线状态对象。PSO把编译程序与固定状态组合起来,缓存遗漏往往来自把某个状态忘进了键。我们从一次绘制需要的完整组合开始,再看创建、缓存和最后使用完成的边界。
组合与缓存
状态组成
图形 PSO 通常涉及着色器阶段、资源布局、顶点输入、光栅化、深度模板、混合、附件格式与样本数。哪些状态固定在对象里、哪些可动态设置由 API 和启用特性决定。
Vulkan pipeline layout 约束 descriptor 和 push constant 接口;D3D12 root signature 表达根参数。不能只用着色器名称作为缓存键。动态状态不一定进入相同的键,但设置责任仍在绘制路径。
缓存键
下面是平台中立的数据结构轮廓。具体键包含目标 API 真正参与编译与兼容性判断的字段。
struct GraphicsPipelineKey
{
Hash shaderStages;
Hash bindingLayout;
Hash vertexLayout;
Hash rasterState;
Hash depthStencilState;
Hash blendState;
Format colorFormats[MaxTargets];
Format depthFormat;
uint32_t sampleCount;
uint64_t dynamicStateMask;
};缓存里的对象属于创建它的设备,另一设备不能仅凭相同键就复用。磁盘数据的兼容条件按API格式核对,驱动、设备、源码和编译选项都可能使它失效。编码键时逐字段写稳定值,结构padding和未初始化字节没有状态语义,不应参与哈希。
设相同着色器S和顶点布局V,第一次目标为RGBA8、单样本,第二次目标为RGBA16F、4样本。两次着色器身份相同,但附件与样本数都不同;只用(S,V)命中缓存,会把第一份对象交给第二条不兼容绘制。反过来,已声明为动态状态的视口尺寸若没有参与管线固定状态,就不应为每个视口大小复制PSO;调用者仍需在Draw前设置动态值。
缓存查询还需处理并发创建。两个线程同时查到未命中时,以同一规范化键登记一个进行中的请求,后续请求订阅其结果;创建失败时保存诊断并清理占位。只给最终对象表加锁,仍可能在锁外重复编译同一组合。测试应让多个线程同时请求同一键,检查实际创建次数和失败后的重试行为。
创建与消费
创建与使用
材质/Shader 组合 → 状态归一化 → 查缓存
├─ 命中:复用对象
└─ 未命中:编译/创建 → 入缓存
停止新增引用,已录制命令已提交或丢弃,所有提交的GPU使用完成 → 可回收对象及相关布局创建可能涉及驱动编译,CPU 耗时和首次使用时的隐藏工作都需要观察。预热只覆盖列出的完整组合。材质变体、不同 render target 和 MSAA 档位可能生成采集时没有遇到的键。
与着色器变体的关系
静态关键字改变编译结果,PSO 将结果与渲染状态组合。动态分支减少部分着色器组合,可能增加运行时着色成本。渲染状态通常不能简单转成材质 uniform;它们仍决定固定功能行为。
具体缓存收集、构建预编译与卡顿治理见性能专题。机制页负责对象与组合定义,性能页记录采集和测量。
验证方法
- 保持着色器不变,只改变附件格式或样本数,确认缓存键与对象正确区分。
- 记录创建线程、键、命中来源和耗时,定位首次进入场景的尖峰。
- 清空缓存与预热缓存分别运行相同路线,对比首次使用和第二次使用。
- 改编译版本,确认旧磁盘数据被识别为不兼容。
相关主题
示例状态:本页代码用于解释对应的数据和调用约束,完整资源创建、类型与调用环境由项目提供。除文中另列的实际实验外,本页未执行目标引擎编译、GPU捕获或性能计时。
参考资料
- Microsoft:Managing Graphics Pipeline State:PSO 包含状态与动态设置状态;本文缓存键和并发请求合并为引擎侧设计。