Files
XCEngine/docs/api/XCEngine/RHI/D3D12/D3D12Texture/D3D12Texture.md

3.8 KiB
Raw Blame History

D3D12Texture

命名空间: XCEngine::RHI

类型: class

头文件: XCEngine/RHI/D3D12/D3D12Texture.h

描述: D3D12 后端的纹理资源封装,持有 ID3D12Resource 并附带一层引擎侧格式、类型和状态元数据。

概览

D3D12TextureXCEngine 在 D3D12 后端中对纹理资源的基础封装。它承担两层职责:

  • 管理一个 ID3D12Resource
  • 维护 RHI 层需要的 FormatTextureTypeResourceStates、名称和拥有权标记

这类封装在商业级引擎里很常见,因为上层系统需要统一的纹理抽象,而 D3D12 原生资源对象本身并不会替你维护这些跨模块元数据。

设计定位

D3D12Texture 不是一个“自动把所有状态都维护正确”的智能对象。当前实现更接近:

  • 一个资源句柄封装器
  • 加上一些便于 RHI 使用的缓存字段

因此你需要分清两件事:

  • 资源对象真正的 D3D12 创建参数是什么
  • 引擎侧 m_state / m_format / m_textureType 当前是否已经同步更新

这也是本页重点要讲清楚的地方。

生命周期

线程语义

  • 当前实现没有锁。
  • 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 调试层对象。

关键方法

相关文档