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:
SpecialX
2026-03-30 14:03:16 +08:00
parent f1584ec3c6
commit 54916b0ac6
10 changed files with 495 additions and 13 deletions

View File

@@ -238,9 +238,76 @@ _cmd_queue->Signal(_fence, _fence_value);
**围栏值溢出**64位无符号整数每秒1000帧需要5.8亿年才回绕,无需担心。
## 7. 渲染表面与窗口
## 7. 描述符堆
### 7.1 render_surface 结构
### 7.1 什么是描述符堆?
描述符堆是一块连续内存用于存储描述符Descriptor。描述符是告诉 GPU 如何访问资源的数据结构。
### 7.2 描述符堆类型
| 类型 | 用途 | 着色器可见 |
|------|------|------------|
| `CBV_SRV_UAV` | 常量缓冲区、着色器资源、无序访问 | 可选 |
| `SAMPLER` | 采样器 | 可选 |
| `RTV` | 渲染目标视图 | 否 |
| `DSV` | 深度模板视图 | 否 |
### 7.3 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; }
};
```
### 7.4 descriptor_heap 类
```cpp
class descriptor_heap
{
bool initialize(u32 capacity, bool is_shader_visible);
descriptor_handle allocate(); // 分配描述符
void free(descriptor_handle); // 释放描述符
private:
ID3D12DescriptorHeap* _heap;
std::unique_ptr<u32[]> _free_handles{}; // 空闲索引池
std::mutex _mutex; // 线程安全
};
```
### 7.5 内存模型
```
描述符堆内存布局:
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │...│ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
_cpu_start / _gpu_start
_free_handles[] = [0, 1, 2, 3, ...] // 空闲索引池
```
### 7.6 线程安全
描述符堆可能被多线程并发访问,使用互斥锁保护:
```cpp
std::lock_guard lock(_mutex);
```
## 8. 渲染表面与窗口
### 8.1 render_surface 结构
```cpp
struct render_surface {
@@ -249,7 +316,7 @@ struct render_surface {
};
```
### 7.2 多窗口支持
### 8.2 多窗口支持
TestRenderer 测试展示了多窗口渲染:
@@ -262,7 +329,7 @@ for (u32 i{0}; i < _countof(_surfaces); ++i) {
}
```
### 7.3 全屏切换
### 8.3 全屏切换
通过 `WM_SYSCHAR` 消息处理 Alt+Enter
@@ -272,42 +339,42 @@ if (wparam == VK_RETURN && (HIWORD(lparam) & KF_ALTDOWN)) {
}
```
## 8. 后续学习路径
## 9. 后续学习路径
### 8.1 基础阶段
### 9.1 基础阶段
- [x] 完成设备创建和适配器枚举
- [x] 创建命令队列和命令列表
- [x] 描述符堆管理
- [ ] 实现交换链和后台缓冲区
- [ ] 渲染第一个三角形
### 8.2 进阶阶段
### 9.2 进阶阶段
- [ ] 描述符堆管理
- [ ] 根签名和管线状态对象
- [ ] 资源屏障和同步
- [ ] 常量缓冲区和着色器资源
### 8.3 高级阶段
### 9.3 高级阶段
- [ ] 多线程渲染
- [ ] 资源绑定策略
- [ ] 动态资源管理
- [ ] 性能优化
## 9. 参考资源
## 10. 参考资源
### 9.1 官方文档
### 10.1 官方文档
- [Microsoft D3D12 文档](https://docs.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-graphics)
- [DXGI 文档](https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/dx-graphics-dxgi)
### 9.2 推荐书籍
### 10.2 推荐书籍
- 《Introduction to 3D Game Programming with DirectX 12》
- 《Real-Time 3D Rendering with DirectX and HLSL》
### 9.3 项目相关文档
### 10.3 项目相关文档
- [Graphics渲染架构分析](./Graphics渲染架构分析.md)
- [项目约定规范](./项目约定规范.md)