在 Direct3D 12 中,查询分组到称为查询堆的查询数组中。 查询堆的类型定义可用于该堆的有效查询类型。
从 Direct3D 11 到 Direct3D 12 的查询差异
Direct3D 12 中不再存在以下查询类型,其功能将合并到其他进程中:
- 事件查询 - 事件功能上现在由围栏处理。
- 不连续时间戳查询 - GPU 时钟可以设置为 Direct3D 12 中的稳定状态(请参阅 计时 部分)。 如果 GPU 在时间戳之间完全空闲(称为不连续查询),则 GPU 时钟比较没有意义。 从不同命令列表发出的稳定电源两个时间戳查询可以可靠地进行比较。 同一命令列表中的两个时间戳始终可以可靠地进行比较。
- 流输出统计信息查询 - 在 Direct3D 12 中,没有针对所有输出流的单个流输出 (SO) 溢出查询。 应用需要发出多个单流查询,然后关联结果。
- 流输出统计信息谓词和遮挡谓词查询 - 查询(写入内存)和 谓词(内存读取)不再耦合,因此不需要这些查询类型。
已将新的二进制遮挡查询类型添加到 Direct3D 12。 这允许仅考虑对象是否完全遮挡(而不是遮挡了多少像素)的谓词策略来向设备指示这一点,这可能会更有效地执行查询。
查询堆
查询可以是多种类型(D3D12_QUERY_HEAP_TYPE)中的一个,在提交到 GPU 之前会分组到查询堆中。
新的查询类型D3D12_QUERY_TYPE_BINARY_OCCLUSION可用,其行为类似于D3D12_QUERY_TYPE_OCCLUSION,只不过它返回二进制 0/1 结果:0 表示没有样本通过深度和模具测试,1 表示至少有一个样本通过深度和模具测试。 这样,封闭查询就不会干扰与深度/模具测试关联的任何 GPU 性能优化。
创建查询堆
与创建查询堆相关的 API 是枚举 D3D12_QUERY_HEAP_TYPE、结构 D3D12_QUERY_HEAP_DESC,以及 createQueryHeap方法。
核心运行时将验证查询堆类型是否为 D3D12_HEAP_TYPE 枚举的有效成员,并且计数是否大于 0。
可以单独启动和停止查询堆中的每个查询元素。
使用查询堆的 API 是枚举 D3D12_QUERY_TYPE,方法 BeginQuery 和 EndQuery。
D3D12_QUERY_TYPE_TIMESTAMP是仅支持 EndQuery 的唯一查询。 所有其他查询类型都需要 BeginQuery 和 EndQuery。
调试层将验证以下内容:
- 开始时间戳查询是非法的 — 你只能结束它
- 开始查询两次而不结束查询是非法的(对于给定元素)。 对于需要开始和结束的查询,在相应开始之前结束查询是非法的(对于给定元素)。
- 传递给 BeginQuery 的查询类型必须与传递给 EndQuery的查询类型匹配。
核心运行时将验证以下内容:
无法对时间戳查询调用 BeginQuery。
对于支持 BeginQuery 和 EndQuery(时间戳除外)的查询类型,给定元素的查询不得跨越命令列表边界。
ElementIndex 必须位于范围内。
查询类型是 D3D12_QUERY_TYPE 枚举的有效成员。
查询类型必须与查询堆兼容。 下表显示了每个查询类型所需的查询堆类型:
查询类型 查询堆类型 D3D12_QUERY_TYPE_OCCLUSION D3D12_QUERY_HEAP_TYPE_OCCLUSION D3D12_QUERY_TYPE_BINARY_OCCLUSION D3D12_QUERY_HEAP_TYPE_OCCLUSION D3D12_QUERY_TYPE_TIMESTAMP D3D12_QUERY_HEAP_TYPE_TIMESTAMP D3D12_QUERY_TYPE_PIPELINE_STATISTICS D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS D3D12_QUERY_TYPE_SO_STATISTICS_STREAM1 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS D3D12_QUERY_TYPE_SO_STATISTICS_STREAM2 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS 命令列表类型支持查询类型。 下表显示了哪些命令列表类型支持哪些查询。
查询类型 支持的命令列表类型 D3D12_QUERY_TYPE_OCCLUSION 直接 D3D12_QUERY_TYPE_BINARY_OCCLUSION 直接 D3D12_QUERY_TYPE_TIMESTAMP 直接、计算和(可选)复制 D3D12_QUERY_TYPE_PIPELINE_STATISTICS 直接 D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 直接 D3D12_QUERY_TYPE_SO_STATISTICS_STREAM1 直接 D3D12_QUERY_TYPE_SO_STATISTICS_STREAM2 直接 D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3 直接
从查询中提取数据
从查询中提取数据的方法是使用 ResolveQueryData 方法。 ResolveQueryData 适用于所有内存类型(无论是系统内存还是设备本地内存),但需要目标资源 D3D12_RESOURCE_STATE_COPY_DEST。