Windows 显示驱动程序模型 (WDDM) 1.2 及更高版本用户模式显示驱动程序必须使用内存套餐和回收功能(从Windows 8开始提供),以减少本地内存和系统内存中临时表面所需的内存开销。
最低 WDDM 版本:1.2
最低 Windows 版本:8
驱动程序实现 - 完整图形和仅呈现:必需
WHCK 要求和测试: Device.Graphics...OfferReclaim
特别是在移动方案中,需要硬件加速的图形密集型应用可能会大量使用 GPU 资源。 此外,在许多移动设备中,GPU 集成到 CPU 芯片集中,GPU 使用部分系统内存作为视频内存。 为了确保在多个应用大量使用 GPU 进而对系统内存提出大量需求时提供合理的系统性能,应尽量减少显示驱动程序的内存占用。 提供/回收设备驱动程序接口 (DDI) 提供执行此操作的机制。
1. 核心目标
减少内存开销:通过动态回收临时表面(Temporary Surfaces)的内存,优化 集成GPU(如移动设备)的 系统内存利用率。
适用场景:
- GPU 共享系统内存(如 Intel HD Graphics、AMD APU、移动 SoC)。
- 多应用高负载时避免内存耗尽导致的性能下降。
2. 关键机制
(1) 内存套餐(Offer)
作用:驱动程序标记不再需要的内存分配为“可回收”,允许 OS 临时将其分配给其他进程或系统使用。
触发条件:
- 应用释放资源(如 Direct3D 纹理销毁)。
- 驱动程序检测到闲置表面(如后台应用的交换链缓冲区)。
(2) 内存回收(Reclaim)
作用:当原始需求恢复时(如应用重新激活),驱动程序尝试收回之前“Offer”的内存。
可能结果:
- 成功:内存内容可能保留(依赖 DXGI_RECLAIM_RESOURCE_FLAGS)
- 失败:需重新分配内存并初始化(内容丢失)。
3. 驱动程序实现要求
(1) 必需接口
DDI 函数 | 描述 |
---|---|
OfferResources |
标记资源为可回收(调用 DXGK_OFFER_ALLOCATION_LIST )。 |
ReclaimResources |
尝试收回资源(返回 DXGK_RECLAIM_RESULT 状态)。 |
(2) 数据结构
DXGKARGCB_OFFER_ALLOCATION:
包含要 Offer 的分配句柄列表及优先级(DXGK_OFFER_PRIORITY)。
DXGK_RECLAIM_ALLOCATION_LIST:
指定需回收的资源列表及回收标志(如 Discarded 状态)。
4. 用户模式驱动(UMD)与内核模式驱动(KMD)协作
- UMD 触发 Offer:调用 IDXGIDevice2::OfferResources(Direct3D 11+)或 vkOfferResources(Vulkan)。
- KMD 处理:通过 DxgkCbOfferAllocation 回调通知图形内核。
- OS 决策:根据内存压力决定是否实际释放物理内存。
- UMD 触发 Reclaim:调用 IDXGIDevice2::ReclaimResources。
- KMD 验证:返回资源是否可重用(如 DXGK_RECLAIM_RESULT_OK)。
5. 优先级与策略
Offer 优先级(DXGK_OFFER_PRIORITY):
- Low:缓存数据(可优先回收)。
- Normal:常规资源。
- High:关键资源(尽量避免回收)。
回收策略:若 ReclaimResources 返回 DXGK_RECLAIM_RESULT_DISCARDED,UMD 需重建资源内容。
6. 代码示例(KMD 侧)
// Offer 资源处理(在 DxgkDdiOfferAllocations 中)
NTSTATUS DxgkDdiOfferAllocations(
DXGKARG_OFFER_ALLOCATIONS* pOfferArgs
) {
for (UINT i = 0; i < pOfferArgs->NumAllocations; i++) {
DXGK_ALLOCATION_HANDLE hAlloc = pOfferArgs->pAllocationList[i];
MarkAsOfferable(hAlloc, pOfferArgs->Priority);
}
return STATUS_SUCCESS;
}
// Reclaim 资源处理(在 DxgkDdiReclaimAllocations 中)
NTSTATUS DxgkDdiReclaimAllocations(
DXGKARG_RECLAIM_ALLOCATIONS* pReclaimArgs
) {
for (UINT i = 0; i < pReclaimArgs->NumAllocations; i++) {
if (IsResourceValid(pReclaimArgs->pAllocationList[i])) {
pReclaimArgs->pResults[i] = DXGK_RECLAIM_RESULT_OK;
} else {
pReclaimArgs->pResults[i] = DXGK_RECLAIM_RESULT_DISCARDED;
}
}
return STATUS_SUCCESS;
}
7. 应用层兼容性(DXGI 1.2+)
API 使用示例:
// Direct3D 11 应用示例
IDXGIDevice2* pDXGIDevice;
pD3DDevice->QueryInterface(IID_PPV_ARGS(&pDXGIDevice));
pDXGIDevice->OfferResources(1, &pTexture, DXGI_OFFER_RESOURCE_PRIORITY_NORMAL);
// ... 后续可能需要回收 ...
HRESULT hr = pDXGIDevice->ReclaimResources(1, &pTexture, &bDiscarded);
8. WHCK 测试要求
测试项:Device.Graphics.WDDM12.Render.OfferReclaim
验证点:
- Offer 后内存压力缓解。
- Reclaim 后资源功能正常。
- 正确处理 DISCARDED 状态。
9. 性能与调试建议
日志记录:跟踪 Offer/Reclaim 调用频率及结果。
内存分析:使用 ETW 事件(如 Microsoft-Windows-DxgKrnl)监控内存回收效率。
Fallback 处理:确保资源回收失败时能优雅重建(如重新上传纹理数据)。
10. 总结
必要性:WDDM 1.2+ 驱动必须实现 Offer/Reclaim 以通过 WHQL 认证。
优势:显著降低集成 GPU 的内存占用,提升多任务性能。
注意:正确处理 DISCARDED 状态是健壮性关键。