描述符表的高级使用
以下部分提供有关描述符表的高级使用的信息。
- 在呈现调用 之间更改描述符表项
- 边界外索引编制
- 着色器衍生和分化索引
- 相关主题
在呈现调用之间更改描述符表项
在将设置描述符表集的命令列表提交到队列以供执行后,应用程序不得从 CPU 中编辑 GPU 可能引用的描述符堆部分,直到应用程序知道 GPU 已使用引用完成。
可以使用 API 围栏确定工作完成情况,以跟踪 GPU 进度,或者更粗糙的机制,例如等待呈现已发送到显示-无论适合应用程序。 如果应用程序知道只会访问描述符表指向的区域子集(例如,由于着色器中的流控制),其他未引用的描述符仍可以自由更改。 如果应用程序需要在呈现调用之间切换不同的描述符表,则应用程序可以选择以下几种方法:
- 描述符表版本控制:为要由命令列表引用的每个唯一描述符集合创建一个单独的描述符表(或重复使用)。 在编辑和重用前面填充的描述符堆区域时,应用程序必须首先确保 GPU 已使用将回收的描述符堆的任何部分完成。
- 动态索引编制:应用程序可以在描述符堆范围内排列因绘图/调度而变化的对象(甚至在绘图范围内有所不同),定义跨越所有这些描述符的描述符表,并在着色器执行期间使用表的动态索引来选择要使用的对象。
- 直接将描述符置于根签名中。 只有极少数的描述符可以这样管理,因为根签名空间有限。
使用描述符表版本控制的含义是,对于每个命令列表的图形管道引用的每个唯一描述符集,必须对描述符堆中的描述符内存进行烧毁,这些描述符可以执行、排队执行或在任何给定时间记录。
D3D12 负责管理通过描述符堆和描述符表管理的对象类型的应用程序版本控制。 其一个好处是,应用程序可以选择尽可能多地重用描述符表内容,而不是始终为每个命令列表提交定义新的描述符表版本。 根签名是 D3D12 驱动程序自动版本的空间。
如果需要,应用程序能够将多个描述符表绑定到根签名(从而绑定到管道),从而允许应用程序按不同的频率对描述符引用集进行分组和切换。 例如,应用程序可以使用很少更改的大型静态描述符表(可能只有一个),或者根据需要填充基础描述符堆内存中的区域,并使用着色器中的动态索引来选择纹理。 同时,应用程序可以维护另一类资源,其中每个绘图调用引用的集使用描述符表版本控制技术从 CPU 切换。
边界外索引
从着色器中对任何描述符表进行边界索引会导致基本上未定义的内存访问,包括读取任意进程内内存的可能性,就好像它是硬件状态描述符一样,并具有硬件对此执行的作的结果。 这可能会生成设备重置,但不会使 Windows 崩溃。
着色器派生和分化索引
如果在 2x2 标记(以支持派生计算)中执行的像素着色器调用从描述符表中选择不同的纹理索引进行采样,并且任何给定像素的所选采样器配置和纹理都需要来自纹理坐标派生器的 LOD 计算,则 LOD 计算和纹理采样过程由硬件独立地完成,以便 2x2 标记中的每个纹理查找独立完成, 这将影响性能。
相关主题