本部分介绍用户模式显示驱动程序 DLL 提供给 Microsoft Direct3D 版本 10 运行时的 Microsoft DirectX 图形基础结构 (DXGI) 函数。 驱动程序在调用用户模式显示驱动程序的 CreateDevice (D3D10 ) 函数时,通过 DXGI_DDI_BASE_FUNCTIONS 结构的成员提供指向 DXGI 函数的指针。
BltDXGI:GetGammaCapsDXGI
PresentDXGI:QueryResourceResidencyDXGI
ResolveSharedResourceDXGI:RotateResourceIdentitiesDXGI
SetDisplayModeDXGI:SetResourcePriorityDXGI
以下是驱动必须实现的DXGI DDI函数列表及其核心职责:
函数名称 | 功能描述 | 调用频率 |
---|---|---|
BltDXGI |
执行块传输(如颜色空间转换/缩放) | 中(视频处理场景) |
GetGammaCapsDXGI |
报告显示设备的伽玛控制能力(如支持独立RGB通道调整) | 低(初始化时) |
PresentDXGI |
提交帧到显示输出或DWM(桌面窗口管理器) | 高(每帧) |
QueryResourceResidencyDXGI |
查询资源当前是否驻留在显存 | 中(资源管理) |
ResolveSharedResourceDXGI |
同步跨进程共享资源的访问(配合D3D10_DDI_RESOURCE_MISC_SHARED 标志使用) |
低(共享纹理时) |
RotateResourceIdentitiesDXGI |
处理显示旋转时资源的重新配置(如移动设备屏幕旋转) | 低(旋转事件时) |
SetDisplayModeDXGI |
切换显示模式(分辨率/刷新率) | 低(模式切换时) |
SetResourcePriorityDXGI |
设置资源在显存中的优先级(影响LRU淘汰策略) | 中(资源加载时) |
(1) PresentDXGI - 帧提交核心函数
输入结构:
typedef struct DXGI_DDI_ARG_PRESENT {
DXGI_DDI_HDEVICE hDevice;
DXGI_DDI_HSURFACE hSurface; // 要呈现的资源
UINT SubResourceIndex; // 子资源索引
DXGI_DDI_HDEVICE hDstDevice; // 目标设备(跨设备时有效)
UINT DstSubResourceIndex;
DXGI_DDI_PRESENT_FLAGS Flags; // 如DXGI_DDI_PRESENT_STEREO
} DXGI_DDI_ARG_PRESENT;
驱动实现要点:
HRESULT APIENTRY PresentDXGI(DXGI_DDI_ARG_PRESENT* pPresentData) {
// 1. 验证资源有效性
MySurface* pSurface = (MySurface*)pPresentData->hSurface.pDrvPrivate;
if (!pSurface) return E_INVALIDARG;
// 2. 处理立体呈现(3D Stereo)
if (pPresentData->Flags.Stereo) {
SubmitStereoFrame(pSurface);
} else {
SubmitMonoFrame(pSurface);
}
// 3. 触发Flip或Copy操作
if (UseHardwareFlip()) {
QueueFlipCommand(pSurface->hKMSurface);
} else {
CopyToBackBuffer(pSurface);
}
return S_OK;
}
(2) SetResourcePriorityDXGI - 资源优先级管理
典型场景:游戏动态加载纹理时提升前景物体优先级。
实现示例:
void APIENTRY SetResourcePriorityDXGI(
DXGI_DDI_ARG_SETRESOURCEPRIORITY* pPriorityData
) {
MyResource* pRes = (MyResource*)pPriorityData->hResource.pDrvPrivate;
pRes->currentPriority = pPriorityData->Priority;
// 更新GPU内存管理器(如NVIDIA的PTE分组)
UpdateGPUMemoryPriority(pRes->videoAddress, pPriorityData->Priority);
}
(3) ResolveSharedResourceDXGI - 共享资源同步
跨进程共享流程:
Process A创建共享资源 → 驱动生成GDI句柄 →
Process B通过OpenResource获取 → ResolveSharedResource同步数据
Process A创建共享资源 → 驱动生成GDI句柄 →
Process B通过OpenResource获取 → ResolveSharedResource同步数据
驱动关键操作:
HRESULT APIENTRY ResolveSharedResourceDXGI(
DXGI_DDI_ARG_RESOLVESHAREDRESOURCE* pResolveData
) {
// 1. 获取共享资源元数据
MySharedResource* pShared = (MySharedResource*)pResolveData->hResource.pDrvPrivate;
// 2. 执行GPU端同步(如刷新缓存)
FlushGPUWriteCache(pShared->gpuAddress);
// 3. 通知内核模式驱动
pCtx->pKMCallbacks->pfnSyncSharedResource(pShared->hKMHandle);
return S_OK;
}
当驱动运行在软件模拟模式时(如WARP驱动),需:
禁用硬件加速路径:返回 DXGI_STATUS_NO_REDIRECTION。
实现CPU端Present:
HRESULT APIENTRY SoftwarePresentDXGI(DXGI_DDI_ARG_PRESENT* pData) {
// CPU内存拷贝到DWM兼容缓冲区
BYTE* pSrc = LockSoftwareSurface(pData->hSurface);
BYTE* pDst = GetDWMBuffer();
memcpy(pDst, pSrc, pData->pPresentInfo->BufferDesc.Width * pData->pPresentInfo->BufferDesc.Height * 4);
UnlockSoftwareSurface(pData->hSurface);
return S_OK;
}
(1) SetDisplayModeDXGI 扩展
HRESULT APIENTRY SetDisplayModeDXGI(
DXGI_DDI_ARG_SETDISPLAYMODE* pModeData
) {
// HDR元数据传递(DXGI 1.4+)
if (pModeData->Flags.HDR) {
ConfigureHDRMetadata(pModeData->hMonitor, &pModeData->HDRMetaData);
}
// 切换显示模式
return ChangeDisplayMode(pModeData->hMonitor, pModeData->Mode);
}
(2) 伽玛控制 (GetGammaCapsDXGI)
void APIENTRY GetGammaCapsDXGI(
DXGI_DDI_ARG_GETGAMMACAPS* pCapsData
) {
pCapsData->GammaCaps->ScaleAndOffsetSupported = FALSE; // 是否支持scRGB
pCapsData->GammaCaps->MaxConvertedValue = 1.0f; // 传统Gamma范围
pCapsData->GammaCaps->NumLUTEntries = 256; // 硬件LUT精度
}
优化点 | 具体措施 |
---|---|
异步Present | 支持 DXGI_DDI_PRESENT_DO_NOT_WAIT 标志避免CPU阻塞 |
资源驻留查询批处理 | 缓存 QueryResourceResidencyDXGI 结果,减少GPU同步 |
旋转优化 | 在 RotateResourceIdentitiesDXGI 中预旋转纹理以减少运行时开销 |
PIX工具:捕获 PresentDXGI 调用链,分析帧间隔和资源状态。
Direct3D调试层:启用 D3D10_DEBUG_DDI 检测参数错误。