|
|
@@ -595,6 +595,35 @@ D3D 除了创建交换链、设备外还会创建上下文(`Context`),用于
|
|
|
|
|
|
这种设计允许高度的并行和效率,因为可以同时记录多个命令列表,而这些命令列表又可以在不同的线程中被创建和管理。此外,通过独立控制命令的记录和执行,DirectX 12 能够提供比以往更精细的控制和更优的性能
|
|
|
|
|
|
+#### Fence 围栏
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+模型资源 R
|
|
|
+
|
|
|
+1. CPU 一开始设置了 R 的位置信息 P1
|
|
|
+2. 添加命令 C 给 GPU 绘制模型 R
|
|
|
+3. CPU 继续计算,重新设置模型 R 的位置信息 P2
|
|
|
+
|
|
|
+在进行到第三步的时候,如果 GPU 此时并没有执行完命令 C (可能还没执行,也可能在执行中),所以模型的坐标不会被绘制到 P1 上,这与期待的命令不合
|
|
|
+
|
|
|
+这种情况的一种解决方案是强制 CPU 等待,知道 GPU 完成所有的命令处理,达到某个指定的围栏点(`Fence Point`)
|
|
|
+
|
|
|
+这种方法称为**刷新命令队列**,可以通过**围栏**(`Fence`) 来实现
|
|
|
+
|
|
|
+```cpp
|
|
|
+HRESULT CreateFence(
|
|
|
+ UINT64 InitialValue, // 围栏的初始值
|
|
|
+ D3D12_FENCE_FLAGS Flags,
|
|
|
+ REFIID riid,
|
|
|
+ [out] void **ppFence
|
|
|
+);
|
|
|
+```
|
|
|
+
|
|
|
+围栏对象维护着一个 UINT64 类型的值,这是用来表示围栏点的整数,每当需要标记新的围栏点时就将其加1
|
|
|
+
|
|
|
+这样做并不完美,因为在等待 GPU 执行命令时 CPU 会进入空闲状态
|
|
|
+
|
|
|
#### 资源、描述符、描述符堆
|
|
|
|
|
|
通过 `D3D12_DESCRIPTOR_HEAP_DESC` 堆描述结构体,来描述一个堆,然后通过 `device` 来创建这个描述符堆,例如:`rtvHeapDesc` 和 `dsvHeapDesc`
|
|
|
@@ -638,6 +667,18 @@ D3D 除了创建交换链、设备外还会创建上下文(`Context`),用于
|
|
|
|
|
|
使用描述符来表示资源是因为 GPU 资源实际上都是一些普通的内存块,很多时候只希望将部分数据绑定到渲染流水线,那么从整个资源中将其选出?或者内存块如何使用?这些都是记录在描述符中的
|
|
|
|
|
|
+#### 资源驻留
|
|
|
+
|
|
|
+对于复杂场景,一些资源并不需要一开始就加载在显存中
|
|
|
+
|
|
|
+一般来说,资源在创建时就会驻留在现存中,而当被销毁时清出。但是 DirectX 提供两种方法来主动控制资源的驻留
|
|
|
+
|
|
|
+```cpp
|
|
|
+HRESULT ID3D12Device::MakeResident
|
|
|
+
|
|
|
+HRESULT ID3D12Device::Evict
|
|
|
+```
|
|
|
+
|
|
|
### 初始化项目
|
|
|
|
|
|
封装报错宏
|