初始化内存段的使用
第二次调用中,驱动程序应填充 DXGK_QUERYSEGMENTOUT 或 DXGK_QUERYSEGMENTOUT3的所有成员。 第二次调用中,驱动程序应使用驱动程序支持的段的相关信息填充DXGK_QUERYSEGMENTOUT或DXGK_QUERYSEGMENTOUT3的 pSegmentDescriptor 成员中DXGK_SEGMENTDESCRIPTOR或DXGK_SEGMENTDESCRIPTOR3结构 NbSegment 大小的数组。
在对 DxgkDdiQueryAdapterInfo 的两次调用中,DXGKARG_QUERYADAPTERINFO 的 pInputData 成员指向包含有关 AGP 光圈位置和属性信息的DXGK_QUERYSEGMENTIN结构。 如果没有 AGP 光圈可用,或者存在但未安装适当的 GART 驱动程序,则有关 AGP 光圈的信息设置为零。 如果没有 AGP 光圈,则显示微型端口驱动程序不应在DXGK_QUERYSEGMENTOUT或DXGK_QUERYSEGMENTOUT3的 pSegmentDescriptor 数组中指示它支持 AGP 类型的光圈段。 如果在这种情况下指示 AGP 类型的光圈段,适配器将无法初始化。
在初始化期间,由于内存充足,因此可以从特定段分配分页缓冲区的内存。 视频内存管理器从 DXGK_QUERYSEGMENTOUT 或 DXGK_QUERYSEGMENTOUT3 的 PagingBufferSegmentId 成员中指定的段为分页缓冲区分配内存。 驱动程序指示第二次调用 DxgkDdiQueryAdapterInfo 时分页缓冲区段的标识符。 驱动程序还应指定应在 DXGK_QUERYSEGMENTOUT 或 DXGK_QUERYSEGMENTOUT3 的 PagingBufferSize 成员中为分页缓冲区分配的大小(以字节为单位)。
一、驱动实现规范
1.1 分页缓冲区配置
段选择原则:
- 优先选择DXGK_MEMORY_VIDEO类型段
- 备选方案:DXGK_MEMORY_SYSTEM(需设置CACHED标志)
大小计算:
// 示例:根据GPU能力动态计算
PagingBufferSize = max(4MB, ScreenWidth * ScreenHeight * 4 * 2);
1.2 多适配器场景处理
1.AGP段共享:
if (AgpApertureSize > 0) {
desc[0].Flags |= DXGK_SEGMENT_SHARED_ACROSS_ADAPTERS;
}
2.原子性保证:对共享段的操作必须使用InterlockedCompareExchange指令
二、错误处理与验证
2.1 常见初始化失败原因
误代码 | 根本原因 | 解决方案 |
---|---|---|
STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER | 分页缓冲区尺寸不足 | 增大PagingBufferSize |
STATUS_GRAPHICS_DRIVER_MISMATCH | 段标志冲突 | 校验WDDM版本兼容性 |
2.2 调试技巧
使用WinDbg验证段布局
dxgkrnl!DXGKRNL_QUERY_SEGMENT_INFO
!d3dcaps -segments
性能计数器监控
Get-Counter "\GPU Memory(*)\*" -Continuous
三、性能优化指南
3.1 段分配策略
离散GPU:
descriptors[0].Flags = DXGK_SEGMENT_FLAGS_VIDEO;
descriptors[1].Flags = DXGK_SEGMENT_FLAGS_SYSTEM;
集成GPU(UMA):
descriptors[0].Flags =
DXGK_SEGMENT_FLAGS_SYSTEM |
DXGK_SEGMENT_FLAGS_CACHED;
3.2 缓存控制最佳实践
写合并优化
movntq [edi], mm0 ; 使用非临时存储指令
预取策略:
_mm_prefetch((char*)pMem, _MM_HINT_T0);