从Windows 8.1开始,Microsoft Direct3D 运行时更高效地处理内部交换缓冲区,从而减少 GPU 上的处理负载。 为了支持这种更好的性能,Windows 显示驱动程序模型 (WDDM) 1.3 及更高版本驱动程序必须支持新的现有设备驱动程序接口, (DDI) 和新纹理格式作为共享图面:
WDDM 1.3 提供 DDI
这些参考主题介绍如何在显示微型端口驱动程序和用户模式显示驱动程序中实现此功能:
- pfnPresent1 (D3D)
- pfnPresent1 (DXGI)
- D3DDDIARG_PRESENT1
- D3DDDIARG_PRESENTSURFACE
- D3DKMT_COMPOSITION_PRESENTHISTORYTOKEN
- DXGI_DDI_ARG_PRESENT1
- DXGI_DDI_ARG_PRESENTSURFACE
- D3DDDI_DEVICEFUNCS (新的 pfnPresent1 函数指针)
- D3DDDIFORMAT (新的 D3DDDIFMT_G8R8 和 D3DDDIFMT_R8 常量值)
- D3DKMT_PRESENT_MODEL (新的 D3DKMT_PM_REDIRECTED_COMPOSITION 常量值)
- D3DKMT_PRESENTHISTORYTOKEN (新的 Composition 成员)
- DXGI_DDI_BASE_ARGS (新的 pDXGIDDIBaseFunctions4 成员)
- DXGI1_3_DDI_BASE_FUNCTIONS (新的 pfnPresent1 函数指针)
1. 核心功能概述
WDDM 1.3 引入 pfnPresent1 系列函数,优化了传统的呈现路径,主要改进包括:
- 更高效的交换链管理:减少 DWM(桌面窗口管理器)合成开销。
- 支持新的呈现模型:如 D3DKMT_PM_REDIRECTED_COMPOSITION(重定向合成)。
- 扩展的格式支持:新增 D3DDDIFMT_G8R8 和 D3DDDIFMT_R8 像素格式。
- 呈现历史记录:通过 D3DKMT_PRESENTHISTORYTOKEN 跟踪呈现操作。
2. 关键数据结构与枚举
(1) 呈现参数结构体
结构体 | 作用 |
---|---|
D3DDDIARG_PRESENT1 | 包含 Direct3D 9/10/11 的扩展呈现参数(如脏矩形、旋转标志)。 |
DXGI_DDI_ARG_PRESENT1 | DXGI 路径的扩展呈现参数(支持低延迟模式、部分更新)。 |
D3DKMT_PRESENTHISTORYTOKEN | 记录呈现操作的令牌(新增 Composition 成员标识合成路径)。 |
(2) 新增像素格式
typedef enum _D3DDDIFORMAT {
D3DDDIFMT_G8R8 = 50, // 16-bit 灰度+红色通道
D3DDDIFMT_R8 = 51, // 8-bit 单通道
} D3DDDIFORMAT;
(3) 呈现模型枚举
typedef enum _D3DKMT_PRESENT_MODEL {
D3DKMT_PM_REDIRECTED_COMPOSITION = 4, // 重定向合成(DWM 优化路径)
} D3DKMT_PRESENT_MODEL;
3. 驱动实现步骤
(1) 用户模式驱动(UMD)
注册 pfnPresent1 回调:
// Direct3D 路径(D3D9/10/11)
D3DDDI_DEVICEFUNCS DeviceFuncs = {0};
DeviceFuncs.pfnPresent1 = YourD3DPresent1Handler;
// DXGI 路径
DXGI1_3_DDI_BASE_FUNCTIONS DXGIFuncs = {0};
DXGIFuncs.pfnPresent1 = YourDXGIPresent1Handler;
处理 D3DDDIARG_PRESENT1:
(2) 内核模式驱动(KMD)
处理重定向合成:
NTSTATUS DxgkDdiPresent(
CONST DXGKARG_PRESENT* pPresent
) {
if (pPresent->PresentModel == D3DKMT_PM_REDIRECTED_COMPOSITION) {
// 跳过传统合成路径,直接扫描输出
ProgramScanout(pPresent->hAllocation);
}
return STATUS_SUCCESS;
}
更新呈现历史令牌:
void UpdatePresentHistory(
D3DKMT_PRESENTHISTORYTOKEN* pToken,
BOOL IsComposition
) {
pToken->Composition = IsComposition; // 标记是否经 DWM 合成
}
4. WHCK 认证要求
测试项 | 验证目标 | 工具依赖 |
---|---|---|
Device.Graphics.WDDM13.Present1 | pfnPresent1 的功能正确性(如脏矩形处理)。 | HLK Present 测试套件。 |
Device.Graphics.WDDM13.RedirectedComposition | 重定向合成路径的功耗和性能优势。 | GPUView + 功耗分析仪。 |
Device.Graphics.WDDM13.FormatSupport | 新增像素格式(如 D3DDDIFMT_R8 )的渲染正确性。 | PIX 捕获工具。 |
5. 调试与优化建议
- ETW 事件:监控 Microsoft-Windows-DxgKrnl 的 Present1_* 事件。
- 脏矩形优化:仅更新屏幕变化区域(通过 pDirtyRects),降低带宽占用。
- 低延迟模式:在 DXGI_DDI_ARG_PRESENT1 中处理 DXGI_DDI_PRESENT_FLAG_LOW_LATENCY 标志。
6. 示例:处理 DXGI Present1
HRESULT APIENTRY DXGIPresent1(
DXGI_DDI_ARG_PRESENT1* pArgs
) {
if (pArgs->Flags & DXGI_DDI_PRESENT_FLAG_LOW_LATENCY) {
BypassComposition(); // 绕过 DWM 合成
}
SubmitFrame(pArgs->pSurfaces, pArgs->NumSurfaces);
return S_OK;
}
7. 总结
必要性:WDDM 1.3+ 驱动需实现 pfnPresent1 以支持现代合成优化。
关键改进:
- 重定向合成降低 DWM 开销。
- 新增像素格式支持更多应用场景(如灰度渲染)。
- 呈现历史记录助力调试工具。
性能收益:全屏应用(如游戏)可减少 20-30% 的呈现延迟