DXGKDDI_QUERYCURRENTFENCE回调函数 (d3dkmddi.h)

DxgkDdiQueryCurrentFence 函数查询硬件命令执行单元中最新完成的提交围栏标识符。

语法

DXGKDDI_QUERYCURRENTFENCE DxgkddiQuerycurrentfence;

NTSTATUS DxgkddiQuerycurrentfence(
  [in]     IN_CONST_HANDLE hAdapter,
  [in/out] INOUT_PDXGKARG_QUERYCURRENTFENCE pCurrentFence
)
{...}

参数

[in] hAdapter

与显示适配器关联的上下文块的句柄。 显示微型端口驱动程序之前在 DxgkDdiAddDevice 函数的 MiniportDeviceContext 输出参数中向 Microsoft DirectX 图形内核子系统提供了此句柄。

[in/out] pCurrentFence

指向包含当前围栏数据相关信息 的DXGKARG_QUERYCURRENTFENCE 结构的指针。

返回值

如果未成功检索围栏数据,DxgkDdiQueryCurrentFence 将返回STATUS_SUCCESS或适当的错误结果。

注解

围栏是包含 64 位数据和地址的指令。 显示微型端口驱动程序可以在直接内存访问 (DMA) 流中插入围栏,该流 (GPU) 发送到图形处理单元。 当 GPU 读取围栏时,GPU 会在指定的围栏地址处写入围栏数据。 但是,在 GPU 可以将围栏数据写入内存之前,它必须确保已停用隔离指令前面的基元中的所有像素并正确写入内存。

注意 GPU 无需在等待隔离指令前基元的最后一个像素停用时停止整个管道;GPU 可以改为运行遵循围栏指令的基元。
 
支持每个 GPU 上下文虚拟地址空间的硬件必须支持以下类型的围栏:
  • 常规围栏 是可以在用户模式下创建的 DMA 缓冲区中插入的围栏。 由于用户模式下的 DMA 缓冲区的内容不受信任,因此此类 DMA 缓冲区中的围栏必须引用 GPU 上下文地址空间中的虚拟地址,而不是物理地址。 对此类虚拟地址的访问受与 GPU 访问的任何其他虚拟地址相同的内存验证机制约束。
  • 特权围栏 是只能在 (创建的 DMA 缓冲区中插入的围栏,并且只能在内核模式下访问) 。 此类 DMA 缓冲区中的围栏是指内存中的物理地址。

    请注意,如果在用户模式下可访问围栏目标地址,则恶意软件可能会对围栏的内存位置执行图形操作,从而覆盖内核预期接收的内容。

请注意,特权 DMA 缓冲区可以包含常规和特权围栏。 但是,如果特权 DMA 缓冲区包含常规围栏,则生成此类 DMA 缓冲区的内核组件知道,内部的常规围栏可能永远不可访问。

如果显示微型端口驱动程序错过了 DMA 缓冲区的最后一个围栏,则可以调用驱动程序的 DxgkDdiQueryCurrentFence 函数来报告错过的围栏。 例如,如果硬件生成内存围栏,则会触发驱动程序的 DxgkDdiInterruptRoutine 函数来读取内存。 但是,如果在驱动程序尝试读取数据 (时围栏的数据不可用,例如,如果芯片集) 有缺陷,则通常会在下一次中断时报告围栏,除非中断已停止。 如果中断已停止,并且 DirectX 图形内核子系统等待围栏的时间过长,则子系统会调用驱动程序的 DxgkDdiQueryCurrentFence 函数来验证当前围栏并确定它可能错过的任何挂起围栏。

在显示微型端口驱动程序从对 DxgkDdiQueryCurrentFence 的调用返回之前,如果尚未报告最新的硬件完成提交围栏标识符,驱动程序必须调用 DxgkCbNotifyInterrupt 函数来报告围栏。 若要实现此功能,驱动程序:

  1. 跟踪上次向操作系统报告的围栏。
  2. 将 IRQL 引发到设备中断。 若要将 IRQL 提高到中断级别,驱动程序可以调用 DxgkCbSynchronizeExecution 函数,以与其 DxgkDdiInterruptRoutine 函数同步。
  3. 在设备中断 IRQL 时,将上次报告的围栏与最新的硬件完成围栏进行比较。
  4. 在设备中断 IRQL 时,仅当最新硬件完成的围栏比上次报告的围栏更新时,才调用 DxgkCbNotifyInterrupt
应使 DxgkDdiQueryCurrentFence 可分页。

要求

要求
最低受支持的客户端 Windows Vista
目标平台 桌面
标头 d3dkmddi.h (包括 D3dkmddi.h)
IRQL PASSIVE_LEVEL

另请参阅

DXGKARG_QUERYCURRENTFENCE

DxgkCbNotifyInterrupt

DxgkCbSynchronizeExecution

DxgkDdiAddDevice

DxgkDdiInterruptRoutine