5.4 KiB
RHIDevice
命名空间: XCEngine::RHI
类型: class (abstract)
头文件: XCEngine/RHI/RHIDevice.h
描述: RHI 设备抽象,负责初始化后端、暴露能力信息,并作为绝大多数资源、命令与管线对象的统一创建入口。
角色概述
RHIDevice 在当前架构里承担的是“设备即工厂”的职责。渲染器不需要分别依赖 buffer 工厂、texture 工厂、pipeline 工厂和 descriptor 工厂,而是统一通过一个设备对象创建后端资源。这种做法和很多商业级引擎底层渲染架构一致,优点是上层入口集中、后端差异被压缩在实现层,代价是 RHIDevice 接口面会比较大。
为什么这样设计
- 上层渲染代码只需要依赖一套
RHI入口,不必按后端分叉创建流程。 BufferDesc、TextureDesc、GraphicsPipelineDesc这些描述结构可以直接作为跨后端契约。- 同一个创建请求可以在不同后端走不同实现细节,例如直接 CPU 写入、上传缓冲复制、延迟编译或立即创建。
这和 Unity SRP、Unreal RHI 一类设计的核心思路一致:高层描述保持统一,真正的后端差异放在设备和资源实现里消化。
生命周期
初始化
Initialize(const RHIDeviceDesc&) 负责建立后端上下文,并填充能力与设备信息。当前设备描述主要控制调试层、GPU 验证和适配器选择,说明引擎仍然把设备创建视为底层、工程化的初始化步骤,而不是面向最终用户的复杂配置界面。
关闭
Shutdown() 负责释放设备级状态。当前 RHI 仍然以显式 Shutdown() 为主,而不是完全依赖析构自动回收,因此调用方应把“显式关闭后再销毁对象”视为标准用法。
缓冲创建模型
CreateBuffer 现在有两种形态,且它们表达的是两种不同层级的需求:
virtual RHIBuffer* CreateBuffer(const BufferDesc& desc) = 0;
virtual RHIBuffer* CreateBuffer(
const BufferDesc& desc,
const void* initialData,
size_t initialDataSize,
ResourceStates finalState = ResourceStates::GenericRead);
基础重载
CreateBuffer(const BufferDesc&) 只负责创建资源本体,不附带初始化数据。具体放在哪种堆、初始状态是什么、后端如何实现,都由具体设备类决定。
带初始数据的重载
这个重载是最近补进来的便捷契约,目的是让上层可以用一条调用完成“创建 + 上传初始内容 + 进入目标状态”。基类默认实现会:
- 在
initialData == nullptr或大小为0时退化到基础重载。 - 拒绝
initialDataSize > desc.size的非法输入。 - 先创建基础缓冲。
- 对前半段调用
SetData(initialData, initialDataSize)。 - 如果
desc.size更大,则把剩余区间补零。 - 最后把资源状态设置为
finalState。
这个默认实现强调的是统一语义,而不是最优性能。它适合小型静态数据、启动期资源或测试代码,不适合高频流式上传。
后端差异
D3D12Device对带初始数据的CreateBuffer做了专门重写,会显式创建上传缓冲、录制拷贝命令并做状态转换。- 其他后端当前只需要满足统一契约,不一定都实现了同等级别的上传路径优化。
这正是抽象层的价值所在:上层只说“我要一个带初始内容的缓冲”,至于后端是 CPU 直写、上传队列复制还是暂时退化实现,都留给设备实现层。
所有权与使用约定
当前 RHI 仍然大量返回裸指针,调用方负责:
- 在使用结束前调用对象自己的
Shutdown()。 - 在确认资源不再被引用后显式
delete。
因此文档和代码都不应把这层接口描述成“天然 RAII 安全”的现代封装。它更接近商业引擎底层后端常见的显式生命周期模型。
公开方法
- Initialize
- Shutdown
- CreateBuffer
- CreateTexture
- CreateSwapChain
- CreateCommandList
- CreateCommandQueue
- CreateShader
- CreatePipelineState
- CreatePipelineLayout
- CreateFence
- CreateSampler
- CreateRenderPass
- CreateFramebuffer
- CreateDescriptorPool
- CreateDescriptorSet
- CreateVertexBufferView
- CreateIndexBufferView
- CreateRenderTargetView
- CreateDepthStencilView
- CreateShaderResourceView
- CreateUnorderedAccessView
- GetCapabilities
- GetDeviceInfo
- GetNativeDevice