3.5 KiB
3.5 KiB
D3D12RenderPass
命名空间: XCEngine::RHI
类型: class
头文件: XCEngine/RHI/D3D12/D3D12RenderPass.h
描述: D3D12 后端的 render pass 元数据对象,用于保存 AttachmentDesc 并把 RHI 的 load/store 语义映射为 D3D12 access type。
概览
和 D3D12Framebuffer 一样,D3D12RenderPass 不是原生 D3D12 对象。
它当前承担的核心职责是:
- 缓存 color attachment 与 depth-stencil attachment 描述
- 为上层 RHI 保留“render pass”这一统一概念
- 提供若干把
LoadAction/StoreAction翻译成D3D12_RENDER_PASS_*_ACCESS_TYPE的辅助接口
设计定位
在 D3D12 中,渲染过程可以用传统 OMSetRenderTargets(...) + Clear*View(...) 路径完成,也可以逐步接近更显式的 render pass 访问语义。
当前 XCEngine 选的是一个折中方案:
- 保留 render pass 抽象,方便跨后端统一
- 先把 attachment 元数据和访问语义整理出来
- 但命令列表实现目前仍主要依赖手动 clear 和
OMSetRenderTargets(...)
也就是说,D3D12RenderPass 目前更接近“元数据和策略对象”,而不是“驱动层 render pass 实例”。
生命周期
- 构造后为空对象
- Initialize 复制 attachment 描述
- Shutdown 清空颜色附件并复位主要状态
- 析构时自动调用 Shutdown
当前实现的真实行为
- GetNativeHandle 永远返回
nullptr - Initialize 不做输入合法性校验,基本只是复制描述
- GetBeginningAccessType / GetEndingAccessType 提供的是“映射结果”,不是驱动对象状态
StoreAction::Resolve和StoreAction::StoreAndResolve当前都会被映射成D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE- 深度访问辅助函数只看
loadOp/storeOp,不会把stencilLoadOp/stencilStoreOp融入返回值 - 当前 D3D12CommandList 的
BeginRenderPass(...)并没有直接使用这些 access type getter,而是手动依据附件描述执行 clear
为什么这样设计
这是典型的引擎抽象先行路线。
这么做的好处是:
- RHI 层在 Vulkan、D3D12、OpenGL 之间可以共享相近的渲染通道心智模型
- 后端可以逐步演进,而不是一开始就把 D3D12 特性全部绑定死在命令列表实现里
- 文档和测试可以直接围绕 attachment/load/store 语义展开
代价是当前对象的很多能力只是“描述能力”,而不是“执行能力”。调用者不能把这些 getter 理解成已经驱动 GPU 的状态。
当前限制
colorAttachmentCount > 0且colorAttachments == nullptr时会发生非法访问- 不验证格式是否合法或是否适合 D3D12 使用
- 不生成原生 render pass 句柄
- 深度 access helper 不表达 stencil 独立访问语义
- ending access 的
StoreAndResolve语义被简化为RESOLVE
关键方法
- Initialize
- GetBeginningAccessType
- GetEndingAccessType
- GetDepthBeginningAccessType
- GetDepthEndingAccessType
- Shutdown