fix(d3d12): 修复 Surface 重复释放问题,完善容器文档

- 改用 utl::free_list 管理 surface,避免 vector 扩容导致的资源重复释放
- 为 d3d12_surface 添加移动语义,禁用拷贝构造
- 添加撕裂检测支持(DXGI_PRESENT_ALLOW_TEARING)
- 为 FreeList.h 和 Vector.h 添加完整的 Doxygen 中文注释
- 更新 D3D12 学习 Wiki,添加 free_list 章节
This commit is contained in:
SpecialX
2026-03-31 16:48:33 +08:00
parent 95d8893182
commit 80cb696a3c
16 changed files with 1141 additions and 228 deletions

View File

@@ -69,7 +69,58 @@ public:
* @details
* 调用 release() 清理交换链和渲染目标资源。
*/
~d3d12_surface(){release();}
~d3d12_surface(){ release(); }
#if USE_STL_VECTOR
DISABLE_COPY(d3d12_surface)
/**
* @brief 移动构造函数
*
* @param o 要移动的源对象
*
* @details
* 转移所有资源所有权,将源对象置为空状态。
* 用于 vector 扩容时安全转移资源。
*/
constexpr d3d12_surface(d3d12_surface&& o) noexcept
: _swap_chain{o._swap_chain}, _window{o._window}, _current_bb_index{o._current_bb_index}
, _viewport{o._viewport}, _scissor_rect{o._scissor_rect}
, _allow_tearing{o._allow_tearing}, _present_flags{o._present_flags}
{
for (u32 i = 0; i < frame_buffer_count; ++i)
{
_render_target_data[i].resource = o._render_target_data[i].resource;
_render_target_data[i].rtv = o._render_target_data[i].rtv;
}
o.reset();
}
/**
* @brief 移动赋值运算符
*
* @param o 要移动的源对象
* @return 当前对象引用
*
* @details
* 先释放当前资源,再转移所有权。
*/
constexpr d3d12_surface& operator=(d3d12_surface&& o) noexcept
{
assert(this != &o);
if (this != &o)
{
release();
move(o);
}
return *this;
}
#else
DISABLE_COPY_AND_MOVE(d3d12_surface);
#endif
/**
* @brief 创建交换链和渲染目标视图
@@ -167,6 +218,43 @@ public:
constexpr const D3D12_RECT& scissor_rect() const {return _scissor_rect;}
private:
#if USE_STL_VECTOR
constexpr void move(d3d12_surface& o)
{
_swap_chain = o._swap_chain;
for (u32 i = 0; i < frame_buffer_count; ++i)
{
_render_target_data[i] = o._render_target_data[i];
}
_window = o._window;
_current_bb_index = o._current_bb_index;
_viewport = o._viewport;
_scissor_rect = o._scissor_rect;
_allow_tearing = o._allow_tearing;
_present_flags = o._present_flags;
o.reset();
}
constexpr void reset()
{
_swap_chain = nullptr;
for (u32 i = 0; i < frame_buffer_count; ++i)
{
_render_target_data[i] = {};
}
_window = {};
_current_bb_index = 0;
_viewport = {};
_scissor_rect = {};
_allow_tearing = 0;
_present_flags = 0;
}
#endif
/**
* @brief 释放所有资源
*
@@ -205,6 +293,8 @@ private:
mutable u32 _current_bb_index{0}; ///< 当前后台缓冲区索引
D3D12_VIEWPORT _viewport{}; ///< 视口描述
D3D12_RECT _scissor_rect{}; ///< 裁剪矩形
u32 _allow_tearing{ 0 }; ///< 是否允许撕裂
u32 _present_flags{ 0 }; ///< 呈现标志位
};
}