window 显示驱动开发-处理内存段(一)

视频内存管理器 (VidMm) 负责管理 GPU 的地址空间。 在此之前,内核模式显示微型端口驱动程序 (KMD) 必须通过使用内存段将 GPU 的地址空间描述为 VidMm。

KMD 创建内存段以概括和虚拟化视频内存资源。 它可以根据硬件支持的存储器类型(例如,帧缓冲区内存或系统内存光圈)配置内存段。

在驱动程序初始化期间,KMD 必须返回描述 VidMm 如何管理内存资源的段类型列表。 KMD 指定了它支持的段类型的数量,并通过响应对其 DxgkDdiQueryAdapterInfo 函数的调用来描述每种段类型。 驱动程序使用 DXGK_SEGMENTDESCRIPTOR 结构描述每个段。 有关详细信息,请参阅初始化内存段的使用。

此后,段的数量和类型保持不变。 VidMm:

  • 确保每个进程在任何特定段中都能获得公平的资源份额,
  • 独立管理所有段。

段不重叠。 因此,VidMm 可以从一个段分配相当数量的视频内存资源,而不管应用程序从另一个段持有多少资源。

KMD 为每个内存段分配一个段标识符。 稍后,当 VidMm 请求为视频资源创建分配并呈现这些资源时,KMD:

  • 标识支持请求的段。
  • 按顺序指定驱动程序希望 VidMm 使用的段。

1. 内存段(Memory Segments)的核心概念

(1) 内存段的作用
硬件资源抽象:

  • KMD 通过内存段将 GPU 的物理内存(如显存、系统内存光圈)虚拟化为逻辑段,供 VidMm 统一管理。

例如:

  • 帧缓冲区段(DXGK_SEGMENT_VIDEO_MEMORY):GPU 专用显存。
  • 系统内存光圈段(DXGK_SEGMENT_SYSTEM_MEMORY):CPU 可访问的共享内存。
  • 重排范围段(DXGK_SEGMENT_SWIZZLING):用于优化内存布局的特定区域。

资源隔离性:

  • 每个段 不重叠,VidMm 可独立管理不同段的内存分配。
  • 例如:应用程序占用显存段不影响系统内存段的可用性。

(2) 段的静态性
初始化时确定:

  • KMD 在驱动初始化阶段(响应 DxgkDdiQueryAdapterInfo)通过 DXGK_SEGMENTDESCRIPTOR 结构定义所有支持的段类型。
  • 段的数量和属性 后续不可更改(除非驱动重启)。

2. KMD 的职责:段配置

(1) 段描述符(DXGK_SEGMENTDESCRIPTOR)
KMD 需为每个段填充以下关键字段:

字段描述
BaseAddress段的起始物理地址(GPU 视角)。
Size段的总大小(字节)。
Flags段属性(如可缓存、可写、CPU 可见等)。
SegmentId段的唯一标识符(由 KMD 分配)。

(2) 示例:多段配置

// KMD 在 DxgkDdiQueryAdapterInfo 中返回的段列表示例
DXGK_SEGMENTDESCRIPTOR Segments[2] = {
    // 显存段(专用 VRAM)
    {
        .BaseAddress = 0x80000000,
        .Size        = 0x40000000, // 1GB
        .Flags       = DXGK_SEGMENT_FLAGS_VIDEO_MEMORY,
        .SegmentId   = 0x1,
    },
    // 系统内存光圈段(共享内存)
    {
        .BaseAddress = 0x00000000, // CPU 物理地址
        .Size        = 0x20000000, // 512MB
        .Flags       = DXGK_SEGMENT_FLAGS_SYSTEM_MEMORY,
        .SegmentId   = 0x2,
    }
};

3. VidMm 的职责:段管理

(1) 公平分配与隔离
进程级配额:

  • VidMm 确保每个进程在任意段中 公平共享资源(如限制单个进程占用显存的比例)。

段独立性:

  • 从段 A 分配内存时,不受段 B 的占用情况影响(避免资源竞争)。

(2) 分配策略
当应用程序请求内存时(如创建纹理):

VidMm 选择候选段:

  • 根据资源需求(如 GPU 专用或 CPU 可访问)筛选匹配的段。

KMD 指定优先级:

  • 驱动通过 DxgkDdiCreateAllocation 的 PreferredSegment 参数建议优先段。

VidMm 最终决策:

  • 结合段剩余空间、进程配额等条件分配内存。

4. 内存分配的实际流程

(1) 用户模式请求

  • 应用程序调用 ID3D12Device::CreateResource。
  • UMD(用户模式驱动)通过 D3DKMTCreateAllocation 向内核发起请求。

(2) VidMm 与 KMD 交互
VidMm 选择段:

  • 检查资源属性(如 D3D12_RESOURCE_FLAGS)匹配的段。

调用 KMD 确认:

  • 触发 DxgkDdiCreateAllocation,KMD 验证硬件支持性。

分配 GPU 虚拟地址:

  • VidMm 在选定段中分配虚拟地址范围(GPU VA)。

返回资源句柄:

  • UMD 获得可操作的资源句柄。

(3) 示例:显存分配

5. 高级场景与优化

(1) 多 GPU 系统
跨设备段:

  • KMD 可为每个 GPU 定义独立段,VidMm 协调跨设备内存迁移(如 dxgmms1.sys 处理)。

(2) 内存压缩
驱动支持:

  • KMD 可通过段标志声明支持压缩(如 DXGK_SEGMENT_FLAGS_COMPRESSIBLE),VidMm 据此优化分配。

(3) 动态资源升降级
分页策略:

  • VidMm 可自动将闲置资源从显存段迁移到系统内存段(调用 DxgkDdiBuildPagingBuffer)。

6. 调试与问题排查

(1) 常见问题

(2) 关键 ETW 事件

  • DXGK_VIRTUALADDRESS:跟踪 GPU VA 分配。
  • DXGK_SEGMENT:监控段的使用情况。

7. 总结

设计优势:

  • 硬件无关性:VidMm 通过抽象段统一管理不同 GPU 的内存。
  • 多进程安全:段隔离避免应用程序相互干扰。
  • 灵活扩展:支持未来内存技术(如 CXL 共享内存)。

通过内存段机制,WDDM 实现了高效的 GPU 内存虚拟化和资源共享,为复杂图形与计算负载奠定基础。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值