feat(d3d12): 实现渲染目标纹理和深度缓冲区

核心变更:
- 实现 d3d12_render_texture 类,支持多 Mip 级别 RTV
- 实现 d3d12_depth_buffer 类,支持 DSV 和 SRV 双视图
- 为所有纹理类添加析构函数,确保资源自动释放
- 深度缓冲区格式转换处理(D32_FLOAT -> R32_TYPELESS)

文档完善:
- 新增变更记录文档
- 更新 D3D12 学习 Wiki,添加渲染目标纹理和深度缓冲区章节
This commit is contained in:
SpecialX
2026-04-01 17:00:09 +08:00
parent 4d13d8df89
commit 188a8aea2f
4 changed files with 507 additions and 0 deletions

View File

@@ -778,6 +778,143 @@ ID3D12Resource* resource = texture.resource();
descriptor_handle srv = texture.srv();
```
### 7.12 渲染目标纹理d3d12_render_texture
#### 功能说明
渲染目标纹理类,支持多 Mip 级别的渲染目标视图RTV用于离屏渲染
```cpp
class d3d12_render_texture
{
public:
explicit d3d12_render_texture(d3d12_texture_init_info info);
~d3d12_render_texture() { release(); }
void release();
u32 mip_count() const;
D3D12_CPU_DESCRIPTOR_HANDLE rtv(u32 mip) const; // 获取指定 Mip 的 RTV
descriptor_handle srv() const; // 获取 SRV
ID3D12Resource* resource() const;
private:
d3d12_texture _texture{};
descriptor_handle _rtv[d3d12_texture::max_mips]{}; // 每个 Mip 一个 RTV
u32 _mip_count{0};
};
```
#### 多 Mip RTV 创建
```cpp
d3d12_render_texture::d3d12_render_texture(d3d12_texture_init_info info)
: _texture(info)
{
_mip_count = resource()->GetDesc().MipLevels;
D3D12_RENDER_TARGET_VIEW_DESC desc{};
desc.Format = info.desc->Format;
desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = 0;
for(u32 i = 0; i < _mip_count; ++i)
{
_rtv[i] = rtv_heap.allocate();
device->CreateRenderTargetView(resource(), &desc, _rtv[i].cpu);
++desc.Texture2D.MipSlice;
}
}
```
#### 使用场景
| 场景 | 说明 |
|------|------|
| 离屏渲染 | 将场景渲染到纹理而非屏幕 |
| 多级渐远纹理 | 生成 Mip Chain |
| 后处理 | 渲染结果作为后处理输入 |
### 7.13 深度缓冲区d3d12_depth_buffer
#### 功能说明
深度缓冲区类同时提供深度模板视图DSV和着色器资源视图SRV
```cpp
class d3d12_depth_buffer
{
public:
explicit d3d12_depth_buffer(d3d12_texture_init_info info);
~d3d12_depth_buffer() { release(); }
void release();
D3D12_CPU_DESCRIPTOR_HANDLE dsv() const; // 深度模板视图
descriptor_handle srv() const; // 着色器资源视图
ID3D12Resource* resource() const;
private:
d3d12_texture _texture{};
descriptor_handle _dsv{};
};
```
#### 格式转换处理
深度缓冲区需要特殊处理格式,以支持同时作为 DSV 和 SRV 使用:
```
┌─────────────────────────────────────────────────────────────┐
│ 深度缓冲区格式处理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户指定格式DXGI_FORMAT_D32_FLOAT │
│ │ │
│ ▼ │
│ 资源格式DXGI_FORMAT_R32_TYPELESS无类型
│ │ │
│ ┌──────────┴──────────┐ │
│ ▼ ▼ │
│ DSV 格式D32_FLOAT SRV 格式R32_FLOAT │
│ (深度测试用) (着色器采样用) │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### 构造实现
```cpp
d3d12_depth_buffer::d3d12_depth_buffer(d3d12_texture_init_info info)
{
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc{};
if(info.desc->Format == DXGI_FORMAT_D32_FLOAT)
{
info.desc->Format = DXGI_FORMAT_R32_TYPELESS;
srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
}
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MipLevels = 1;
info.srv_desc = &srv_desc;
_texture = d3d12_texture(info);
D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc{};
dsv_desc.Format = DXGI_FORMAT_D32_FLOAT;
dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
_dsv = dsv_heap.allocate();
device->CreateDepthStencilView(resource(), &dsv_desc, _dsv.cpu);
}
```
#### 使用场景
| 场景 | 说明 |
|------|------|
| 深度测试 | 作为 DSV 用于深度缓冲 |
| 阴影映射 | 作为 SRV 采样深度值 |
| SSAO | 采样深度重建位置 |
## 8. 交换链Swap Chain
### 8.1 什么是交换链?