window显示驱动开发—DirectX 图形基础结构 DDI
DirectX 图形基础结构 (DXGI) 是在意识到某些图形部分比其他部分发展得慢的情况下开发的。 DXGI 为将来的图形组件提供了通用框架。 第一个利用 DXGI 的 Direct3D 运行时版本是 Direct3D 版本 10。 在早期版本的 Direct3D 运行时中,Direct3D 运行时中包含对低级别任务的访问。 DXGI 定义了一个 DDI,该 DDI 独立于 Direct3D 运行时管理低级别共享任务。 现在,以下任务是使用 DXGI 实现的,你可以使用 DXGI DDI 来处理这些任务:
-
呈现
-
伽玛校正控制
-
资源驻留
-
资源优先级
1. DXGI 的设计目标与演进背景
DXGI 是微软为解耦图形管线中的稳定基础设施与高频演进特性而设计的中间层,其核心价值包括:
- 统一低级管理:将呈现、资源管理等跨版本通用功能从Direct3D运行时剥离。
- 多API支持:为Direct3D 10+、Direct2D等提供共享基础服务。
- 未来扩展性:独立演进不影响上层图形API。
历史对比:
Direct3D 9 及之前 | Direct3D 10+ (DXGI) |
---|---|
呈现、资源管理内嵌在D3D运行时 | 通过DXGI DDI处理低级任务 |
硬编码伽玛/分辨率控制 | 标准化交换链与显示管理 |
2. DXGI DDI 的四大核心功能
(1) 呈现 (Present)
交换链管理:控制帧缓冲区翻转/复制。
同步模型:支持垂直同步(VSync)、撕裂控制(Tearing)。
驱动实现:
// DXGI_DDI_PRESENT_DESC 结构示例
typedef struct DXGI_DDI_PRESENT_DESC {DXGI_DDI_ARG_PRESENT* pPresentArgs;UINT DirtyRectsCount;RECT* pDirtyRects;
} DXGI_DDI_PRESENT_DESC;
(2) 伽玛校正控制
- 硬件LUT配置:驱动需支持伽马 ramps (RGB 1D纹理)。
- HDR适配:扩展为scRGB色彩空间(DXGI 1.1+)。
驱动接口:
HRESULT SetGammaRamp(DXGI_DDI_ARG_SETGAMMARAMP* pGammaRamp);
(3) 资源驻留 (Residency)
显存管理:按优先级动态加载/驱逐资源。
驱动响应:
HRESULT EvictResources(DXGI_DDI_ARG_EVICT* pEvictArgs);
(4) 资源优先级
- 层级划分:从 DXGI_RESOURCE_PRIORITY_MINIMUM 到 MAXIMUM。
- 驱动优化:影响GPU调度与内存压缩策略。
3. 驱动集成关键步骤
(1) 支持 DXGI DDI
实现 DXGI_DDI_BASE_FUNCTIONS 表:
DXGI_DDI_BASE_FUNCTIONS DxgDdiFuncs = {.pfnPresent = MyDxgDdiPresent,.pfnGetGammaCaps = MyDxgDdiGetGammaCaps,.pfnSetDisplayMode = MyDxgDdiSetDisplayMode,// ...其他必要函数
};
注册到Direct3D DDI:
- 在 OpenAdapter10 中通过 DXGIBaseDDI 参数传递函数表。
(2) 资源创建时的DXGI信息
- 资源标志传递:在 D3D10DDIARG_CREATERESOURCE 中包含 DXGI_DDI_RESOURCE_FLAGS。
- 共享资源支持:处理 DXGI_DDI_RESOURCE_SHARED 和 KEYED_MUTEX。
(3) DXGI 呈现路径
交换链初始化:
DXGI_DDI_ARG_CREATESWAPCHAIN swapchainDesc = {.hDevice = hDevice,.pPresentArgs = &presentArgs,.BufferCount = 2, // 双缓冲.SwapEffect = DXGI_DDI_SWAP_EFFECT_FLIP_SEQUENTIAL
};
Present调用流:
D3D Runtime → DXGI Runtime → DXGI DDI (驱动) → 显示微型端口驱动
(4) 注册表配置
启用特性:在 INF 中设置 HKR, DXGI 相关键值:
[DDI.Registry]
HKR,"DXGI","EnableHDRSupport",0x00010001,1
适配器标识:指定 DXGI_ADAPTER_DESC 的 VendorId/DeviceId。
4. 驱动实现示例
(1) Present 函数实现
HRESULT APIENTRY MyDxgDdiPresent(DXGI_DDI_ARG_PRESENT* pPresentData
) {// 1. 获取当前交换链状态MySwapChain* pSC = (MySwapChain*)pPresentData->hSwapChain.pDrvPrivate;// 2. 处理脏矩形(部分更新)if (pPresentData->DirtyRectsCount > 0) {UpdatePartialRects(pSC, pPresentData->pDirtyRects, pPresentData->DirtyRectsCount);}// 3. 提交Present命令到GPUSubmitPresentCommand(pSC->hKMSwapChain);return S_OK;
}
(2) 伽玛控制
HRESULT APIENTRY MyDxgDdiSetGammaRamp(DXGI_DDI_ARG_SETGAMMARAMP* pGammaRamp
) {// 转换RAMPs到硬件LUT格式HW_GAMMA_LUT lut;ConvertDDIGammaToHW(&pGammaRamp->Ramp, &lut);// 写入显示器寄存器WriteGammaLUT(pGammaRamp->hDevice.pDrvPrivate, &lut);return S_OK;
}
5. 多平台适配与调试
平台 | 关键差异 | 驱动适配要点 |
---|---|---|
Windows 7 | DXGI 1.0,基础功能 | 确保兼容性模式支持 |
Windows 10 | DXGI 1.5,支持HDR、可变刷新率 | 实现 SetHDRMetaData 等新接口 |
Xbox | DXGI 1.4,专用优化路径 | 处理 IsSupported 查询的特殊返回值 |
调试工具:
PIX on Windows:捕获DXGI Present调用链。
GPUView:分析帧翻转与VSync事件。
6. 性能优化建议
- 异步Present:利用 DXGI_PRESENT_DO_NOT_WAIT 减少CPU阻塞。
- 资源优先级分级:高频访问资源标记为 DXGI_RESOURCE_PRIORITY_HIGH。
- HDR元数据批处理:合并 SetHDRMetaData 调用避免频繁更新。
总结
DXGI DDI 是现代DirectX驱动的基石,其核心实现要求包括:
- 严格接口合规:完整实现 DXGI_DDI_BASE_FUNCTIONS 函数表。
- 资源生命周期管理:正确处理驻留与优先级。
- 多版本兼容:从DXGI 1.0到最新标准的渐进增强。