锁定重排分配

视频内存管理器为直接 CPU 访问重排分配提供特殊支持 (即显示微型端口驱动程序的 DxgkDdiCreateAllocation 函数在DXGK_ALLOCATIONINFO结构的 Flags 成员) 设置重排标志的分配。

当视频内存管理器逐出驱动程序未标记为从内存段重排的 CPU 可访问的分配时,显示微型端口驱动程序必须始终以线性格式存储这些分配。 因此,当此类分配位于光圈段时不能重排,并且驱动程序的 DxgkDdiBuildPagingBuffer 函数必须始终重排或取消重排。

另一方面,从内存段逐出时,不需要始终以线性格式存储标记为重排的分配。 对于此类分配,视频内存管理器跟踪这些分配的重排状态,并且仅需要驱动程序的 DxgkDdiBuildPagingBuffer 函数在某些传输操作期间取消重排分配。

在用户模式显示驱动程序调用 Microsoft Direct3D 运行时的 pfnLockCb 函数后,视频内存管理器和显示微型端口驱动程序的行为方式如下,具体取决于分配的状态:

  1. 位于内存段中的分配

    视频内存管理器尝试获取 CPU 光圈,以提供对分配的线性访问。 如果视频内存管理器无法获取光圈,则视频内存管理器会将分配逐回系统内存 (,除非驱动程序将 D3DDDICB_LOCKFLAGS 结构的 DonotEvict 成员设置为) 。 当视频内存管理器调用显示微型端口驱动程序的 DxgkDdiBuildPagingBuffer 函数来转移分配时,显示微型端口驱动程序应取消重排分配。

  2. 分配逐出 (重排) 或位于光圈段

    必须先取消重排分配,CPU 才能访问它。 因此,视频内存管理器首先尝试在分配中分页到内存段。 分配位于内存段后,视频内存管理器和显示微型端口驱动程序的行为与数字 1 相同。

  3. 分配已逐出 (未重排)

    如果分配已取消重排到系统内存,则视频内存管理器将返回现有的分配指针,而无需进一步处理。

    为了使 GPU 能够使用以前未重排的分配,必须在 GPU 使用它之前重新重排分配。 因此,在表面故障时,视频内存管理器和显示微型端口驱动程序的行为方式如下:

    • 内存段中的分配 (CPU 光圈动态取消重排)

      分配已采用 GPU 可以处理的重排格式。 因此,视频内存管理器无需进一步处理。

    • 已逐出到系统内存的分配 (未重排)

      分配的页面包含未重排的数据,不能映射到光圈段。 因此,必须在内存段中对分配进行分页。 当视频内存管理器调用显示微型端口驱动程序的 DxgkDdiBuildPagingBuffer 函数在分配中分页时,视频内存管理器请求显示微型端口驱动程序重排分配。

注意 在重排分配通过 CPU 光圈访问 CPU 后,仍可以在用户模式显示驱动程序终止 CPU 访问之前将其逐出。 这种情况在数字 2 中处理。 逐出以对应用程序和用户模式显示驱动程序不可见的方式执行。 此外,无覆盖锁 (即不允许在重排分配中通过设置D3DDDICB_LOCKFLAGS) 的 IgnoreSync 成员获取锁。 只有 CPU 或 GPU 可以在任何给定时间访问此类分配。