Files
DX12/docs/changelogs/2026-04/20260401-render-texture-depth-buffer.md
SpecialX 188a8aea2f feat(d3d12): 实现渲染目标纹理和深度缓冲区
核心变更:
- 实现 d3d12_render_texture 类,支持多 Mip 级别 RTV
- 实现 d3d12_depth_buffer 类,支持 DSV 和 SRV 双视图
- 为所有纹理类添加析构函数,确保资源自动释放
- 深度缓冲区格式转换处理(D32_FLOAT -> R32_TYPELESS)

文档完善:
- 新增变更记录文档
- 更新 D3D12 学习 Wiki,添加渲染目标纹理和深度缓冲区章节
2026-04-01 17:01:18 +08:00

213 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 变更记录:渲染目标纹理与深度缓冲区实现
**提交日期**: 2026-04-01
**提交哈希**: `57afd12`
**变更类型**: 功能新增
---
## 变更概述
本次提交实现了 `d3d12_render_texture`(渲染目标纹理)和 `d3d12_depth_buffer`(深度缓冲区)类,为纹理资源类添加了析构函数。
## 修改文件
| 文件 | 变更说明 |
|------|----------|
| `D3D12Resources.h` | 为纹理类添加析构函数,完善 `d3d12_render_texture``d3d12_depth_buffer` 类定义 |
| `D3D12Resource.cpp` | 实现 `d3d12_render_texture``d3d12_depth_buffer` 构造与释放逻辑 |
---
## d3d12_render_texture 类
### 功能说明
渲染目标纹理类,支持多 Mip 级别的渲染目标视图RTV
```cpp
class d3d12_render_texture
{
public:
d3d12_render_texture() = default;
explicit d3d12_render_texture(d3d12_texture_init_info info);
~d3d12_render_texture() { release(); }
// 移动语义
d3d12_render_texture(d3d12_render_texture&& o);
d3d12_render_texture& operator=(d3d12_render_texture&& o);
// 禁用拷贝
DISABLE_COPY(d3d12_render_texture);
void release();
u32 mip_count() const;
D3D12_CPU_DESCRIPTOR_HANDLE rtv(u32 mip) const;
descriptor_handle srv() const;
ID3D12Resource* resource() const;
private:
d3d12_texture _texture{};
descriptor_handle _rtv[d3d12_texture::max_mips]{}; // 每个 Mip 一个 RTV
u32 _mip_count{0};
};
```
### 构造流程
```cpp
d3d12_render_texture::d3d12_render_texture(d3d12_texture_init_info info)
: _texture(info) // 先创建基础纹理
{
// 获取 Mip 级别数
_mip_count = resource()->GetDesc().MipLevels;
// 为每个 Mip 级别创建 RTV
D3D12_RENDER_TARGET_VIEW_DESC desc{};
desc.Format = info.desc->Format;
desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
for(u32 i = 0; i < _mip_count; ++i)
{
_rtv[i] = rtv_heap.allocate();
device->CreateRenderTargetView(resource(), &desc, _rtv[i].cpu);
++desc.Texture2D.MipSlice; // 下一个 Mip 切片
}
}
```
### 使用场景
- 离屏渲染Render-to-Texture
- 多级渐远纹理生成
- 后处理效果
---
## d3d12_depth_buffer 类
### 功能说明
深度缓冲区类封装深度模板视图DSV和着色器资源视图SRV
```cpp
class d3d12_depth_buffer
{
public:
d3d12_depth_buffer() = default;
explicit d3d12_depth_buffer(d3d12_texture_init_info info);
~d3d12_depth_buffer() { release(); }
// 移动语义
d3d12_depth_buffer(d3d12_depth_buffer&& o);
d3d12_depth_buffer& operator=(d3d12_depth_buffer&& o);
// 禁用拷贝
DISABLE_COPY(d3d12_depth_buffer);
void release();
D3D12_CPU_DESCRIPTOR_HANDLE dsv() const;
descriptor_handle srv() const;
ID3D12Resource* resource() const;
private:
d3d12_texture _texture{};
descriptor_handle _dsv{};
};
```
### 构造流程
```cpp
d3d12_depth_buffer::d3d12_depth_buffer(d3d12_texture_init_info info)
{
// 深度缓冲区需要特殊处理格式
// DSV 使用 D32_FLOATSRV 使用 R32_FLOAT
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 使用浮点格式
}
// 创建纹理和 SRV
info.srv_desc = &srv_desc;
_texture = d3d12_texture(info);
// 创建 DSV
D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc{};
dsv_desc.Format = DXGI_FORMAT_D32_FLOAT; // DSV 使用深度格式
dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
_dsv = dsv_heap.allocate();
device->CreateDepthStencilView(resource(), &dsv_desc, _dsv.cpu);
}
```
### 格式转换说明
```
┌─────────────────────────────────────────────────────────────┐
│ 深度缓冲区格式处理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户指定格式DXGI_FORMAT_D32_FLOAT │
│ │ │
│ ▼ │
│ 资源格式DXGI_FORMAT_R32_TYPELESS无类型
│ │ │
│ ┌──────────┴──────────┐ │
│ ▼ ▼ │
│ DSV 格式D32_FLOAT SRV 格式R32_FLOAT │
│ (深度测试用) (着色器采样用) │
│ │
└─────────────────────────────────────────────────────────────┘
```
**为什么要这样处理?**
- 深度缓冲区需要作为着色器资源被采样如阴影映射、SSAO
- DSV 格式D32_FLOAT不能直接用于 SRV
- 使用 TYPELESS 格式允许同一资源创建不同格式的视图
---
## 析构函数添加
为所有纹理类添加了析构函数,确保资源自动释放:
```cpp
class d3d12_texture {
public:
~d3d12_texture() { release(); }
// ...
};
class d3d12_render_texture {
public:
~d3d12_render_texture() { release(); }
// ...
};
class d3d12_depth_buffer {
public:
~d3d12_depth_buffer() { release(); }
// ...
};
```
---
## 后续工作
- [ ] 实现根签名和管线状态对象
- [ ] 渲染第一个三角形
- [ ] 实现常量缓冲区
---
## 相关文档
- [D3D12学习Wiki](../wiki/D3D12学习Wiki.md)