feat: implement descriptor heap with thread-safe allocation
D3D12 Resources: - Add descriptor_handle struct with CPU/GPU handles - Add descriptor_heap class for descriptor management - Implement allocate() and free() methods - Add mutex for thread-safe access - Support all D3D12 descriptor heap types D3D12 Core: - Add device() function to expose main device - Add release() template function for COM objects Documentation: - Add changelog for descriptor heap implementation - Update D3D12 Wiki with descriptor heap section - Mark descriptor heap task as completed
This commit is contained in:
212
docs/changelogs/2026-03/20260330-d3d12-descriptor-heap.md
Normal file
212
docs/changelogs/2026-03/20260330-d3d12-descriptor-heap.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# 变更记录:描述符堆实现
|
||||
|
||||
**提交日期**: 2026-03-30
|
||||
**提交哈希**: `a03c544`
|
||||
**变更类型**: 功能实现
|
||||
|
||||
---
|
||||
|
||||
## 变更概述
|
||||
|
||||
本次提交实现了 D3D12 描述符堆(Descriptor Heap)管理类,提供描述符的分配和释放功能,支持多线程安全访问。
|
||||
|
||||
## 新增文件
|
||||
|
||||
### Engine/Graphics/Direct3D12/
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `D3D12Resources.h` | 描述符句柄和描述符堆类定义 |
|
||||
| `D3D12Resource.cpp` | 描述符堆实现 |
|
||||
|
||||
## 修改文件
|
||||
|
||||
| 文件 | 变更说明 |
|
||||
|------|----------|
|
||||
| `D3D12Core.h` | 添加 `device()` 函数声明和 `release` 模板函数 |
|
||||
| `D3D12Core.cpp` | 添加 `device()` 函数实现 |
|
||||
| `D3D12CommonHeader.h` | 添加 `<mutex>` 头文件 |
|
||||
|
||||
---
|
||||
|
||||
## 技术要点
|
||||
|
||||
### 1. descriptor_handle 结构
|
||||
|
||||
```cpp
|
||||
struct descriptor_handle
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE cpu{}; // CPU 句柄
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE gpu{}; // GPU 句柄(着色器可见时有效)
|
||||
|
||||
constexpr bool is_valid() const { return cpu.ptr != 0; }
|
||||
constexpr bool is_shader_visible() const { return gpu.ptr != 0; }
|
||||
};
|
||||
```
|
||||
|
||||
**设计要点**:
|
||||
- 封装 CPU 和 GPU 双句柄
|
||||
- 提供有效性检查方法
|
||||
- DEBUG 模式下记录容器和索引用于调试
|
||||
|
||||
### 2. descriptor_heap 类
|
||||
|
||||
```cpp
|
||||
class descriptor_heap
|
||||
{
|
||||
public:
|
||||
explicit descriptor_heap(const D3D12_DESCRIPTOR_HEAP_TYPE type);
|
||||
|
||||
bool initialize(u32 capacity, bool is_shader_visible);
|
||||
void release();
|
||||
|
||||
descriptor_handle allocate(); // 分配描述符
|
||||
void free(descriptor_handle handle); // 释放描述符
|
||||
|
||||
// 访问器
|
||||
constexpr ID3D12DescriptorHeap* heap() const;
|
||||
constexpr D3D12_CPU_DESCRIPTOR_HANDLE cpu_start() const;
|
||||
constexpr D3D12_GPU_DESCRIPTOR_HANDLE gpu_start() const;
|
||||
constexpr bool is_shader_visible() const;
|
||||
|
||||
private:
|
||||
ID3D12DescriptorHeap* _heap;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE _cpu_start{};
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE _gpu_start{};
|
||||
std::unique_ptr<u32[]> _free_handles{}; // 空闲句柄池
|
||||
std::mutex _mutex; // 线程安全
|
||||
u32 _capacity{0};
|
||||
u32 _size{0};
|
||||
u32 _descriptor_size{0};
|
||||
const D3D12_DESCRIPTOR_HEAP_TYPE _type;
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 描述符堆类型
|
||||
|
||||
| 类型 | 用途 | 着色器可见 |
|
||||
|------|------|------------|
|
||||
| `D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV` | 常量缓冲区、着色器资源、无序访问 | 可选 |
|
||||
| `D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER` | 采样器 | 可选 |
|
||||
| `D3D12_DESCRIPTOR_HEAP_TYPE_RTV` | 渲染目标视图 | 否 |
|
||||
| `D3D12_DESCRIPTOR_HEAP_TYPE_DSV` | 深度模板视图 | 否 |
|
||||
|
||||
### 4. 内存模型
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Shader-Visible 描述符堆 (GPU 显存) │
|
||||
│ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │
|
||||
│ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │...│ │ │ │ │
|
||||
│ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ │
|
||||
│ ↑ │
|
||||
│ _cpu_start / _gpu_start │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
|
||||
_free_handles[] = [0, 1, 2, 3, 4, 5, ...] // 空闲索引池
|
||||
_size = 0 // 已分配数量
|
||||
```
|
||||
|
||||
### 5. 分配算法
|
||||
|
||||
```cpp
|
||||
descriptor_handle allocate()
|
||||
{
|
||||
std::lock_guard lock(_mutex); // 线程安全
|
||||
|
||||
const u32 index = _free_handles[_size]; // 取空闲索引
|
||||
const u32 offset = index * _descriptor_size; // 计算偏移
|
||||
++_size; // 递增已分配数量
|
||||
|
||||
descriptor_handle handle{};
|
||||
handle.cpu.ptr = _cpu_start.ptr + offset; // CPU 句柄
|
||||
if(is_shader_visible())
|
||||
handle.gpu.ptr = _gpu_start.ptr + offset; // GPU 句柄
|
||||
|
||||
return handle;
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 线程安全
|
||||
|
||||
```cpp
|
||||
std::mutex _mutex; // 保护并发访问
|
||||
|
||||
// 使用 lock_guard 保护
|
||||
std::lock_guard lock(_mutex);
|
||||
```
|
||||
|
||||
描述符堆可能被多个线程并发访问(资源创建/销毁),需要互斥锁保护。
|
||||
|
||||
---
|
||||
|
||||
## D3D12Core 扩展
|
||||
|
||||
### 新增 device() 函数
|
||||
|
||||
```cpp
|
||||
// D3D12Core.h
|
||||
ID3D12Device *const device();
|
||||
|
||||
// D3D12Core.cpp
|
||||
ID3D12Device *const device()
|
||||
{
|
||||
return main_device;
|
||||
}
|
||||
```
|
||||
|
||||
提供对 D3D12 设备的访问,用于创建描述符堆等资源。
|
||||
|
||||
### 新增 release 模板函数
|
||||
|
||||
```cpp
|
||||
template<typename T>
|
||||
constexpr void release(T*& resource)
|
||||
{
|
||||
if(resource)
|
||||
{
|
||||
resource->Release();
|
||||
resource = nullptr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
通用的 COM 对象释放模板,避免代码重复。
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
```cpp
|
||||
// 创建描述符堆
|
||||
descriptor_heap cbv_srv_heap{D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV};
|
||||
cbv_srv_heap.initialize(100, true); // 100个描述符,着色器可见
|
||||
|
||||
// 分配描述符
|
||||
descriptor_handle handle = cbv_srv_heap.allocate();
|
||||
|
||||
// 创建视图
|
||||
device->CreateShaderResourceView(texture, &srvDesc, handle.cpu);
|
||||
|
||||
// 绑定到管线
|
||||
ID3D12DescriptorHeap* heaps[] = { cbv_srv_heap.heap() };
|
||||
cmdList->SetDescriptorHeaps(1, heaps);
|
||||
cmdList->SetGraphicsRootDescriptorTable(0, handle.gpu);
|
||||
|
||||
// 释放描述符
|
||||
cbv_srv_heap.free(handle);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 后续工作
|
||||
|
||||
- [ ] 实现资源类(Texture, Buffer)
|
||||
- [ ] 实现交换链
|
||||
- [ ] 实现渲染目标视图
|
||||
|
||||
---
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [D3D12学习Wiki](../wiki/D3D12学习Wiki.md)
|
||||
@@ -16,6 +16,7 @@ changelogs/
|
||||
|
||||
| 日期 | 提交 | 变更内容 |
|
||||
|------|------|----------|
|
||||
| 2026-03-30 | [描述符堆实现](./2026-03/20260330-d3d12-descriptor-heap.md) | D3D12 描述符堆管理和线程安全分配 |
|
||||
| 2026-03-27 | [Fence同步机制](./2026-03/20260327-d3d12-fence-sync.md) | D3D12 Fence CPU-GPU 帧同步实现 |
|
||||
| 2026-03-26 | [命令队列与多帧缓冲](./2026-03/20260326-d3d12-command-queue.md) | D3D12 命令队列和多帧渲染架构 |
|
||||
| 2026-03-26 | [D3D12设备初始化](./2026-03/20260326-d3d12-device-init.md) | D3D12 设备创建与调试层实现 |
|
||||
|
||||
Reference in New Issue
Block a user