feat(d3d12): 实现渲染目标纹理和深度缓冲区
核心变更: - 实现 d3d12_render_texture 类,支持多 Mip 级别 RTV - 实现 d3d12_depth_buffer 类,支持 DSV 和 SRV 双视图 - 为所有纹理类添加析构函数,确保资源自动释放 - 深度缓冲区格式转换处理(D32_FLOAT -> R32_TYPELESS) 文档完善: - 新增变更记录文档 - 更新 D3D12 学习 Wiki,添加渲染目标纹理和深度缓冲区章节
This commit is contained in:
@@ -194,6 +194,83 @@ d3d12_texture::release()
|
||||
}
|
||||
|
||||
//////////// D3D12 RENDER TEXTURE ////////////
|
||||
d3d12_render_texture::d3d12_render_texture(d3d12_texture_init_info info)
|
||||
: _texture(info)
|
||||
{
|
||||
assert(info.desc);
|
||||
_mip_count = resource()->GetDesc().MipLevels;
|
||||
assert(_mip_count && _mip_count <= d3d12_texture::max_mips);
|
||||
|
||||
descriptor_heap& rtv_heap {core::rtv_heap()};
|
||||
D3D12_RENDER_TARGET_VIEW_DESC desc{};
|
||||
desc.Format = info.desc->Format;
|
||||
desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MipSlice = 0;
|
||||
|
||||
auto *const device {core::device()};
|
||||
assert(device);
|
||||
for(u32 i{0}; i<_mip_count;++i)
|
||||
{
|
||||
_rtv[i] = rtv_heap.allocate();
|
||||
device->CreateRenderTargetView(resource(), &desc, _rtv[i].cpu);
|
||||
++desc.Texture2D.MipSlice;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_render_texture::release()
|
||||
{
|
||||
for(u32 i{0}; i<_mip_count;++i) core::srv_heap().free(_rtv[i]);
|
||||
_texture.release();
|
||||
_mip_count = 0;
|
||||
}
|
||||
|
||||
//////////// D3D12 DEPTH TEXTURE ////////////
|
||||
d3d12_depth_buffer::d3d12_depth_buffer(d3d12_texture_init_info info)
|
||||
: _texture(info)
|
||||
{
|
||||
assert(info.desc);
|
||||
const DXGI_FORMAT dsv_format {info.desc->Format};
|
||||
|
||||
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.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Texture2D.MipLevels = 1;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
srv_desc.Texture2D.PlaneSlice = 0;
|
||||
srv_desc.Texture2D.ResourceMinLODClamp = 0.f;
|
||||
|
||||
assert(!info.srv_desc && !info.resource);
|
||||
info.srv_desc = &srv_desc;
|
||||
_texture = d3d12_texture(info);
|
||||
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc{};
|
||||
dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||
dsv_desc.Flags = D3D12_DSV_FLAG_NONE;
|
||||
dsv_desc.Format = dsv_format;
|
||||
dsv_desc.Texture2D.MipSlice = 0;
|
||||
|
||||
_dsv = core::dsv_heap().allocate();
|
||||
auto *const device {core::device()};
|
||||
assert(device);
|
||||
device->CreateDepthStencilView(resource(), &dsv_desc, _dsv.cpu);
|
||||
|
||||
|
||||
}
|
||||
void
|
||||
d3d12_depth_buffer::release()
|
||||
{
|
||||
core::dsv_heap().free(_dsv);
|
||||
_texture.release();
|
||||
_dsv = {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
} //XEngine::graphics::d3d12
|
||||
@@ -435,6 +435,7 @@ public:
|
||||
constexpr static u32 max_mips{ 14 };
|
||||
d3d12_texture() = default;
|
||||
explicit d3d12_texture(d3d12_texture_init_info info);
|
||||
~d3d12_texture() { release(); }
|
||||
DISABLE_COPY(d3d12_texture);
|
||||
constexpr d3d12_texture(d3d12_texture&& o)
|
||||
: _resource(o._resource), _srv(o._srv) //这些值只是指针和句柄,不需要move
|
||||
@@ -475,6 +476,86 @@ private:
|
||||
descriptor_handle _srv;
|
||||
};
|
||||
|
||||
class d3d12_render_texture
|
||||
{
|
||||
public:
|
||||
d3d12_render_texture() = default;
|
||||
explicit d3d12_render_texture(d3d12_texture_init_info info);
|
||||
DISABLE_COPY(d3d12_render_texture);
|
||||
~d3d12_render_texture() { release(); }
|
||||
constexpr d3d12_render_texture(d3d12_render_texture&& o)
|
||||
: _texture{std::move(o._texture)}, _mip_count{o._mip_count}
|
||||
{
|
||||
for(u32 i = 0; i < o._mip_count; ++i) _rtv[i] = o._rtv[i];
|
||||
o.reset();
|
||||
}
|
||||
|
||||
constexpr d3d12_render_texture& operator=(d3d12_render_texture&& o)
|
||||
{
|
||||
assert(this != &o);
|
||||
if(this != &o)
|
||||
{
|
||||
reset();
|
||||
move(o);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void release();
|
||||
constexpr u32 mip_count() const { return _mip_count; }
|
||||
constexpr D3D12_CPU_DESCRIPTOR_HANDLE rtv(u32 mip) const { assert(mip < _mip_count); return _rtv[mip].cpu; }
|
||||
constexpr descriptor_handle srv() const { return _texture.srv(); }
|
||||
constexpr ID3D12Resource *const resource() const { return _texture.resource(); }
|
||||
private:
|
||||
constexpr void move(d3d12_render_texture& o)
|
||||
{
|
||||
_texture = std::move(o._texture);
|
||||
for(u32 i = 0; i < o._mip_count; ++i) _rtv[i] = o._rtv[i];
|
||||
o.reset();
|
||||
}
|
||||
|
||||
constexpr void reset()
|
||||
{
|
||||
for(u32 i = 0; i < _mip_count; ++i) _rtv[i] = {};
|
||||
_mip_count = 0;
|
||||
}
|
||||
|
||||
d3d12_texture _texture{};
|
||||
descriptor_handle _rtv[d3d12_texture::max_mips]{};
|
||||
u32 _mip_count{0};
|
||||
};
|
||||
|
||||
class d3d12_depth_buffer
|
||||
{
|
||||
public :
|
||||
d3d12_depth_buffer() = default;
|
||||
explicit d3d12_depth_buffer(d3d12_texture_init_info info);
|
||||
DISABLE_COPY(d3d12_depth_buffer);
|
||||
~d3d12_depth_buffer() { release(); }
|
||||
constexpr d3d12_depth_buffer(d3d12_depth_buffer&& o)
|
||||
: _texture{std::move(o._texture)}, _dsv(o._dsv)
|
||||
{
|
||||
o._dsv = {};
|
||||
}
|
||||
constexpr d3d12_depth_buffer& operator=(d3d12_depth_buffer&& o)
|
||||
{
|
||||
assert(this != &o);
|
||||
if(this != &o)
|
||||
{
|
||||
_texture = std::move(o._texture);
|
||||
_dsv = o._dsv;
|
||||
o._dsv = {};
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void release();
|
||||
constexpr D3D12_CPU_DESCRIPTOR_HANDLE dsv() const { return _dsv.cpu; }
|
||||
constexpr descriptor_handle srv() const { return _texture.srv(); }
|
||||
constexpr ID3D12Resource *const resource() const { return _texture.resource(); }
|
||||
private:
|
||||
d3d12_texture _texture{};
|
||||
descriptor_handle _dsv{};
|
||||
};
|
||||
|
||||
} // namespace XEngine::graphics::d3d12
|
||||
|
||||
Reference in New Issue
Block a user