DXGKDDI_QUERYCURRENTFENCE回调函数 (d3dkmddi.h)

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

语法

DXGKDDI_QUERYCURRENTFENCE DxgkddiQuerycurrentfence;

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

参数

[in] hAdapter

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

[in/out] pCurrentFence

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

返回值

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

言论

围栏 是包含 64 位数据和地址的指令。 显示微型端口驱动程序可以在发送到图形处理单元(GPU)的直接内存访问(DMA)流中插入围栏。 当 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