3.8 KiB
3.8 KiB
D3D12Texture
命名空间: XCEngine::RHI
类型: class
头文件: XCEngine/RHI/D3D12/D3D12Texture.h
描述: D3D12 后端的纹理资源封装,持有 ID3D12Resource 并附带一层引擎侧格式、类型和状态元数据。
概览
D3D12Texture 是 XCEngine 在 D3D12 后端中对纹理资源的基础封装。它承担两层职责:
- 管理一个
ID3D12Resource - 维护 RHI 层需要的
Format、TextureType、ResourceStates、名称和拥有权标记
这类封装在商业级引擎里很常见,因为上层系统需要统一的纹理抽象,而 D3D12 原生资源对象本身并不会替你维护这些跨模块元数据。
设计定位
D3D12Texture 不是一个“自动把所有状态都维护正确”的智能对象。当前实现更接近:
- 一个资源句柄封装器
- 加上一些便于 RHI 使用的缓存字段
因此你需要分清两件事:
- 资源对象真正的 D3D12 创建参数是什么
- 引擎侧
m_state/m_format/m_textureType当前是否已经同步更新
这也是本页重点要讲清楚的地方。
生命周期
- 构造后为空对象。
- 可以通过以下路径获得资源:
- Initialize 创建默认堆纹理
- InitializeFromExisting 包装已有资源
- InitializeFromData 创建 2D 纹理并上传初始数据
- InitializeDepthStencil 创建深度纹理
- Shutdown 会
Reset()内部ComPtr,并复位大部分元数据。 - 析构时自动调用
Shutdown()。
线程语义
- 当前实现没有锁。
- D3D12 资源对象本身支持跨线程引用,但该封装里的引擎侧元数据不是并发安全接口;通常仍应在资源创建/管理线程中维护。
当前实现的真实行为
- Initialize 会创建 committed resource,但不会把
m_state更新为传入的initialState。 - InitializeDepthStencil 也会创建处于
D3D12_RESOURCE_STATE_DEPTH_WRITE的资源,但不会同步修改m_state。 D3D12Device::CreateTexture()会在某些路径上补做SetFormat()、SetTextureType()、SetState(),所以工厂路径比手工直接调初始化函数更完整。- InitializeFromExisting 即使传入
nullptr也返回true。 - OwnsResource 当前只是标记,不会改变
Shutdown()的实际释放行为。 - SetName 只设置引擎侧字符串,不会调用
ID3D12Object::SetName()。
为什么这样设计
这种实现很像很多引擎早期或中期阶段的 D3D12 资源层:
- 先保证资源能被统一创建和访问
- 再逐步把状态跟踪、调试命名、子资源语义等能力补齐
它的好处是实现简单、上层可用。 它的代价是文档必须把“哪些字段只是缓存、哪些行为依赖外部调用者补齐”写得非常明确,否则调用方很容易误判资源状态。
当前限制
GetDesc()和GetGPUAddress()没有空指针保护。GetSize()只是近似值,不是显存占用。GetDepth()与 GetArraySize 都读取DepthOrArraySize,语义上需要由调用方自己区分“深度纹理”还是“数组纹理”。OwnsResource不控制Shutdown()是否释放ComPtr。SetName()不会把名称写入 D3D12 调试层对象。