3.3 KiB
3.3 KiB
OpenGLPipelineState
命名空间: XCEngine::RHI
类型: class
头文件: XCEngine/RHI/OpenGL/OpenGLPipelineState.h
描述: OpenGL 后端的 CPU 侧管线状态容器;它统一了跨后端 PSO 概念,但真实行为仍然是“在绑定时把缓存状态写回 OpenGL 上下文”。
概览
OpenGLPipelineState 和 D3D12/Vulkan 的原生 PSO 有本质区别。显式 API 的 PSO 更像“预编译、不可变的 GPU 对象”;当前 OpenGL 实现则是一个运行时状态包,里面保存的是:
- graphics program 或 compute program 句柄
- 输入布局描述
- 深度/模板状态
- 混合状态
- 光栅化状态
- viewport / scissor / clear color 等附加缓存
真正的 OpenGL 调用发生在 Bind 和各个 Apply* 方法里,而不是在对象创建时一次性固化。
当前实现的真实行为
- Bind 会优先绑定 compute program,否则绑定 graphics program
Bind()之后只会调用 Apply,即深度/模板、混合、光栅化三类状态- ApplyViewport 与 ApplyScissor 需要单独调用
- SetRenderTargetFormats、SetSampleCount、GetHash 目前基本是占位实现
- IsValid 永远返回
true - EnsureValid 为空实现
- GetNativeHandle 只返回 graphics
m_program
设计背景
商业引擎在做 OpenGL 后端时,通常不会试图伪造一套完全等价于 D3D12/Vulkan 的原生 PSO,而是会保留一个“高层 PSO 接口 + 低层状态写回器”的折中结构。当前实现就属于这一类设计:
- 高层渲染代码仍可依赖统一的
RHIPipelineState - OpenGL 后端把真实成本集中到绑定阶段
- 这样既保留了跨后端 API 一致性,也避免在 OpenGL 上硬造不存在的驱动对象
这和 Unity、Unreal 等商业引擎在老式状态机 API 上常用的策略是一致的:抽象层保持现代接口形状,后端实现接受状态机现实。
生命周期
- OpenGLPipelineState() 初始化为空容器
- 上层通过 SetInputLayout、SetBlendState、SetDepthStencilState、SetRasterizerState 等接口缓存状态
- 设备创建 graphics pipeline 时,会通过 SetOwnedGraphicsShader 把编译好的
OpenGLShader交给它管理 - 命令提交阶段由 Bind 把状态真正写入 OpenGL
- Shutdown 释放自有 graphics shader,并重置程序句柄与标记位
重要限制
- 不是原生 OpenGL pipeline object
- 不是不可变对象,状态可以随时被覆盖
- 不自动应用 viewport / scissor
- 部分 RHI 描述字段只被缓存,没有进入真实 OpenGL 调用
- 没有稳定的 hash 和严格的创建期验证
关键方法
- Bind
- Apply
- SetComputeShader
- SetOwnedGraphicsShader
- SetBlendState
- SetDepthStencilState
- SetRasterizerState