Files
XCEngine/docs/api/XCEngine/RHI/RHIDescriptorPool/RHIDescriptorPool.md
2026-03-29 01:36:53 +08:00

3.5 KiB
Raw Blame History

RHIDescriptorPool

命名空间: XCEngine::RHI

类型: class (abstract)

头文件: XCEngine/RHI/RHIDescriptorPool.h

描述: descriptor set 分配池,负责按指定 heap 类型和容量创建、回收 RHIDescriptorSet

角色概述

RHIDescriptorPool 是当前资源绑定系统里的分配器入口。它的抽象目标比较清晰:

  • 上层先定义 descriptor pool 的类型和容量
  • 再从 pool 中分配一个或多个 RHIDescriptorSet

从设计上看,它相当于在不同后端之间收敛:

  • D3D12 风格的 descriptor heap / descriptor range 分配
  • Vulkan 风格的 descriptor pool / descriptor set 分配
  • OpenGL 当前实现中的绑定点管理

DescriptorPoolDesc 的核心字段

当前 pool 描述来自 RHITypes 中的 DescriptorPoolDesc,最重要的字段是:

  • type
  • descriptorCount
  • shaderVisible

其中 type 对应 DescriptorHeapType

当前支持的池类型

现有测试已经覆盖了以下几种 pool 类型:

  • CBV_SRV_UAV
  • Sampler
  • RTV
  • DSV

这说明当前抽象层已经把常见资源视图和采样器池分开表达,而不是只做单一 descriptor arena。

当前使用路径

典型流程是:

  1. 通过 RHIDevice 创建 RHIDescriptorPool
  2. 调用 AllocateSet 传入 DescriptorSetLayoutDesc
  3. 获得 RHIDescriptorSet
  4. 使用结束后销毁 set再关闭 pool

当前接口还提供 FreeSet,说明 pool 设计时就考虑了 set 生命周期管理,而不是单纯一次性线性分配。

设计理解

这层抽象在商业引擎里很常见,因为 descriptor / binding 资源通常不是孤立对象,而是需要一个分配域:

  • pool 负责容量和类型边界
  • set 负责单次绑定内容

当前实现比较薄,但这是合理的第一步。它已经足够表达“这个 pass / material 需要从哪个类型的绑定池里拿一组 descriptor set”。

当前边界

当前 RHIDescriptorPool 没有直接暴露:

  • 碎片率或剩余容量查询
  • reset-all / frame allocator 语义
  • 多线程分配保证
  • 复杂回收策略

所以更准确的理解是:它是一个够用的基础分配接口,而不是完整的 descriptor allocator 子系统。

测试体现出的真实语义

tests/RHI/unit/test_descriptor.cpptest_descriptor_set.cpp 表明:

  • GetType()GetDescriptorCount() 会反映创建时的 pool 配置
  • Shutdown() 可以重复调用
  • pool 创建成功后可连续 AllocateSet()
  • 部分测试直接通过 pool->FreeSet(set) 回收 set

这说明它已经是 descriptor 相关测试的主要对象,而不是占位接口。

生命周期

RHIDescriptorPoolRHIDevice 创建,使用完成后应:

  1. 先释放或关闭从该 pool 分配出的 set
  2. 调用 Shutdown
  3. delete

公共方法

相关文档