HellowTriangle
1. 管线初始化 (LoadPipeline)
这一步主要是建立 GPU 与应用程序之间的通信桥梁,准备好绘制所需的基础基础设施。
- 开启调试层 (Debug Layer): 在 Debug 模式下,开启 D3D12 的调试控制台,帮助捕获后续运行时的错误(必须在创建设备前完成)。
- 创建设备 (Device): 通过
DXGIFactory枚举硬件显卡(或 WARP 软件光栅化器),创建代表虚拟 GPU 的ID3D12Device对象。这是后续所有 D3D12 对象创建的核心工厂。 - 创建命令队列 (Command Queue): 创建一个直接类型的队列(Direct Queue),用于后续向 GPU 提交渲染指令。
- 创建交换链 (Swap Chain): 配置缓冲区数量(通常为双缓冲)、分辨率、像素格式等,并将交换链绑定到窗口句柄和命令队列上。
- 创建描述符堆 (Descriptor Heap) 与渲染目标视图 (RTV): * 创建一个用于存放渲染目标视图(RTV)的描述符堆。
- 遍历交换链的每一个后台缓冲区,为它们分别创建 RTV,并将句柄存放在描述符堆中。 - 创建命令分配器 (Command Allocator): 为后续的命令列表分配底层内存。
2. 资产加载 (LoadAssets)
在这个阶段,程序会准备渲染三角形具体需要的显存资源和状态设置。
- 创建根签名 (Root Signature): 定义着色器所需的外部资源布局。因为只是简单的三角形,所以这里创建了一个空的根签名。
- 编译着色器与创建管线状态对象 (PSO):
- 读取并编译顶点着色器(VS)和像素着色器(PS)。
- 定义顶点输入布局(包含位置和颜色信息)。
- 将着色器、根签名、输入布局、光栅化状态、混合状态等打包,创建一个统一的图形管线状态对象 (Graphics Pipeline State Object)。 - 创建并初始化命令列表 (Command List): 关联之前的命令分配器和 PSO 创建命令列表,并立刻将其闭合(因为初始化阶段暂无指令需录制)。
- 创建顶点缓冲区 (Vertex Buffer):
- 定义三角形三个顶点的局部坐标和颜色数据。
- 在上传堆 (Upload Heap) 中创建显存资源,并将 CPU 中的顶点数据拷贝到该缓冲区中。
- 初始化一个顶点缓冲区视图(View),以便稍后绑定到管线上。 - 同步与等待: 创建围栏(Fence)和事件(Event),强制 CPU 等待 GPU 完成上述所有初始化操作后,再继续往下执行。
3. 渲染循环 (OnRender & PopulateCommandList)
这是每帧都会重复调用的核心循环。
- 重置指令录制状态: 重置命令分配器和命令列表,准备录制新一帧的指令。
- 设置管线状态: 绑定根签名、视口(Viewport)和裁剪矩形(Scissor Rect)。
- 资源状态转换 (Resource Barrier): 发出指令,将当前帧的后台缓冲区状态从“呈现状态 (Present)”转换为“渲染目标状态 (Render Target)”。
- 执行渲染:
- 绑定 RTV 到输出合并阶段 (OM)。
- 用纯色清空背景。
- 设置图元拓扑类型为三角形列表 (Triangle List)。
- 绑定顶点缓冲区视图。
- 调用DrawInstanced发出绘制三角形的指令。 - 还原资源状态: 将后台缓冲区的状态从“渲染目标”转回“呈现状态”,并闭合命令列表。
- 提交与呈现:
- 将录制好的命令列表提交给命令队列执行 (ExecuteCommandLists)。
- 调用交换链的Present方法将画面翻转到屏幕上。 - 等待帧完成: 插入 Fence 信号,强制 CPU 等待 GPU 渲染完这一帧(同步)。
4. 清理销毁 (OnDestroy)
- 等待 GPU 闲置: 在析构或退出前,必须调用
WaitForPreviousFrame()确保 GPU 已经完成了所有队列中的任务,防止 CPU 提前释放 GPU 正在使用的资源。 - 关闭句柄: 关闭系统事件句柄。