window显示驱动开发—UMD 实现的 MPO 函数

本部分包含 WDDM 1.3 及更高版本的 UMD 必须实现的函数才能支持 MPO。

  • Direct3D:UMD 通过调用 UMD 的 CreateDevice 函数中的D3DDDI_DEVICEFUNCS结构的成员提供指向 D3D MPO 函数的指针。
  • DXGI:当调用特定于适配器的 CreateDevice(D3D10)函数时,UMD 通过DXGI1_3_DDI_BASE_FUNCTIONS结构的成员提供指向 DXGI MPO 函数的指针。 

下表列出了 UMD 为了支持 MPO 而必须实现的函数。

功能DESCRIPTION
pfnCheckMultiPlaneOverlaySupport (D3D)由 D3D 运行时调用,以检查 MPO 的硬件支持的详细信息。
pfnCheckMultiPlaneOverlaySupport (DXGI)DirectX 图形基础结构(DXGI)运行时调用,以检查硬件对 MPOs 的支持情况。
pfnPresentMultiplaneOverlay (D3D)由 D3D 运行时调用以通知 UMD 应用程序完成呈现并请求 UMD 显示源图面。 驱动程序应通过复制、翻转或执行颜色填充作来显示此图面。
pfnPresentMultiplaneOverlay (DXGI)DXGI 运行时调用该函数以通知 UMD,应用程序已完成渲染并请求 UMD 显示源表面。 UMD 应通过复制、翻转或执行颜色填充操作来显示表面。

 下表列出了 UMD 可以选择实现的 DXGI DDI 函数。

功能DESCRIPTION
pfnGetMultiPlaneOverlayCapsDXGI 运行时调用以请求 UMD 获取基本覆盖平面功能。
pfnGetMultiplaneOverlayGroupCapsDXGI 运行时调用以请求 UMD 获取一组覆盖平面功能。

1. Direct3D 部分 MPO 函数实现

1.1 通过 D3DDDI_DEVICEFUNCS 结构体暴露
在 CreateDevice 调用中,UMD 必须填充以下 MPO 相关函数指针:

typedef struct _D3DDDI_DEVICEFUNCS {
    // ... 标准 D3D 函数 ...
    
    // MPO 专用函数 (WDDM 1.3+)
    PFND3DDDI_CREATEOVERLAY         pfnCreateOverlay;
    PFND3DDDI_UPDATEOVERLAY         pfnUpdateOverlay;
    PFND3DDDI_FLIPOVERLAY           pfnFlipOverlay;
    PFND3DDDI_DESTROYOVERLAY        pfnDestroyOverlay;
    PFND3DDDI_GETOVERLAYCOLORCONTROLS pfnGetOverlayColorControls;
    PFND3DDDI_SETOVERLAYCOLORCONTROLS pfnSetOverlayColorControls;
} D3DDDI_DEVICEFUNCS;

关键函数实现示例
1. pfnCreateOverlay

HRESULT APIENTRY CreateOverlay(
    D3DDDIARG_CREATEOVERLAY* pCreateData)
{
    // 验证硬件支持
    if (!(pDevice->Caps.OverlayCaps & D3DDDI_OVERLAY_CAPS_HW))
        return E_INVALIDARG;
    
    // 分配 MPO 平面资源
    MPO_PLANE* pPlane = AllocateMpoPlane(pCreateData->VideoDesc);
    pCreateData->hOverlay = (HANDLE)pPlane;
    return S_OK;
}

2. pfnUpdateOverlay

HRESULT APIENTRY UpdateOverlay(
    D3DDDIARG_UPDATEOVERLAY* pUpdateData)
{
    MPO_PLANE* pPlane = (MPO_PLANE*)pUpdateData->hOverlay;
    
    // 硬件原子更新
    HW_MPO_UPDATE update = {
        .SrcRect  = pUpdateData->SrcRect,
        .DstRect  = pUpdateData->DstRect,
        .Rotation = pUpdateData->Rotation
    };
    return HwUpdateMpoPlane(pPlane->hHwPlane, &update);
}

2. DXGI 部分 MPO 函数实现

2.1 通过 DXGI1_3_DDI_BASE_FUNCTIONS 结构体暴露
在 DXGI 设备创建时提供以下函数指针:

typedef struct DXGI1_3_DDI_BASE_FUNCTIONS {
    // ... 基础 DXGI 函数 ...
    
    // MPO 扩展函数
    PFNDDXGI_DDI_PRESENT_MULTIPLANE_OVERLAY  pfnPresentMultiplaneOverlay;
    PFNDDXGI_DDI_GET_MULTIPLANE_OVERLAY_CAPS pfnGetMultiplaneOverlayCaps;
    PFNDDXGI_DDI_CHECK_MULTIPLANE_OVERLAY_SUPPORT pfnCheckMultiplaneOverlaySupport;
} DXGI1_3_DDI_BASE_FUNCTIONS;

关键函数实现示例
1. pfnPresentMultiplaneOverlay

​
HRESULT APIENTRY PresentMultiplaneOverlay(
    DXGI_DDI_ARG_PRESENT_MULTIPLANE_OVERLAY* pPresentData)
{
    // 验证每个平面
    for (UINT i = 0; i < pPresentData->NumPlanes; i++) {
        if (!ValidatePlane(pPresentData->pPlanes[i]))
            return DXGI_DDI_ERR_INVALID_CALL;
    }
    
    // 硬件提交
    return HwPresentMpo(pPresentData->pPlanes, pPresentData->NumPlanes);
}

​

2. pfnGetMultiplaneOverlayCaps

​
HRESULT APIENTRY GetMultiplaneOverlayCaps(
    DXGI_DDI_ARG_GET_MULTIPLANE_OVERLAY_CAPS* pCapsData)
{
    pCapsData->Caps = {
        .MaxPlanes          = 4,    // 硬件支持的最大平面数
        .SupportsRGB        = TRUE,  // 支持 RGB 平面
        .SupportsYCbCr     = TRUE,  // 支持 YUV 平面
        .SupportsRotation  = TRUE   // 支持硬件旋转
    };
    return S_OK;
}

​

3. MPO 功能验证流程

3.1 初始化阶段检查

sequenceDiagram
    UMD->>KMD: GetCaps(D3DDDICAPS_GETD3D9CAPS)
    KMD-->>UMD: 返回D3DCAPS_OVERLAY标志
    UMD->>KMD: QueryInterface(DXGI1_3_DDI)
    KMD-->>UMD: 提供DXGI MPO函数表

3.2 运行时状态管理

// MPO 平面状态机
typedef enum {
    MPO_STATE_FREE,      // 未分配
    MPO_STATE_ACTIVE,    // 正在显示
    MPO_STATE_PENDING,   // 等待VSync
} MPO_PLANE_STATE;

4. WHQL 认证必备实现

测试类别必须通过的项目
Device.Graphics.MPO.BasicCreate/Update/Destroy 平面基本操作
Device.Graphics.MPO.FormatRGB/YUV/HDR 格式支持验证
Device.Graphics.MPO.Power混合操作时的功耗合规性检查

5. 错误处理规范

错误码触发条件
DXGI_DDI_ERR_UNSUPPORTED硬件不支持请求的 MPO 功能
DXGI_DDI_ERR_INVALID_CALL非法的平面属性或状态
E_ACCESSDENIED尝试跨进程访问受保护平面

6. 性能优化技巧

6.1 平面重用池

class MpoPlanePool {
    std::vector<MPO_PLANE_CTX*> m_freePlanes;
public:
    MPO_PLANE_CTX* AllocatePlane(DXGI_FORMAT fmt) {
        // 从池中获取或新建平面
    }
};

6.2 硬件特性利用

  • Intel:使用 Plane Rotation 减少内存拷贝
  • NVIDIA:通过 Overlay Plane 降低视频播放功耗
  • AMD:结合 FreeSync 实现动态刷新率同步

7. 调试与验证工具

DirectX 控制面板:

dxcpl.exe -> MPO 诊断选项卡

ETW 追踪:

logman start MPOTrace -p Microsoft-Windows-DXG-Kernel 0xFFFF -o trace.etl

硬件寄存器检查:

// 读取显示控制器状态
UINT regVal = ReadHwRegister(DISPLAY_ENGINE_MPO_STATUS);

8. 向后兼容性处理

#if (D3D_UMD_INTERFACE_VERSION >= D3D_UMD_INTERFACE_VERSION_WINBLUE)
    // 完整实现 WDDM 1.3 MPO 函数
#else
    // 返回 E_NOTIMPL 并记录警告
    DbgPrint("MPO requires WDDM 1.3+\n");
#endif
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员王马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值