核心变更: - 实现 d3d12_render_texture 类,支持多 Mip 级别 RTV - 实现 d3d12_depth_buffer 类,支持 DSV 和 SRV 双视图 - 为所有纹理类添加析构函数,确保资源自动释放 - 深度缓冲区格式转换处理(D32_FLOAT -> R32_TYPELESS) 文档完善: - 新增变更记录文档 - 更新 D3D12 学习 Wiki,添加渲染目标纹理和深度缓冲区章节
213 lines
6.0 KiB
Markdown
213 lines
6.0 KiB
Markdown
# 变更记录:渲染目标纹理与深度缓冲区实现
|
||
|
||
**提交日期**: 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_FLOAT,SRV 使用 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)
|