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

6.0 KiB
Raw Blame History

变更记录:渲染目标纹理与深度缓冲区实现

提交日期: 2026-04-01
提交哈希: 57afd12
变更类型: 功能新增


变更概述

本次提交实现了 d3d12_render_texture(渲染目标纹理)和 d3d12_depth_buffer(深度缓冲区)类,为纹理资源类添加了析构函数。

修改文件

文件 变更说明
D3D12Resources.h 为纹理类添加析构函数,完善 d3d12_render_textured3d12_depth_buffer 类定义
D3D12Resource.cpp 实现 d3d12_render_textured3d12_depth_buffer 构造与释放逻辑

d3d12_render_texture 类

功能说明

渲染目标纹理类,支持多 Mip 级别的渲染目标视图RTV

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};
};

构造流程

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

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{};
};

构造流程

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 格式允许同一资源创建不同格式的视图

析构函数添加

为所有纹理类添加了析构函数,确保资源自动释放:

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(); }
    // ...
};

后续工作

  • 实现根签名和管线状态对象
  • 渲染第一个三角形
  • 实现常量缓冲区

相关文档