当前位置: 首页 > news >正文

window显示驱动开发—多平面覆盖 VidPN 呈现

使用多平面覆盖时,这些要求适用于用于在视频呈现网络 (VidPNs) 的多个表面上显示的功能:

DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay

  • 如果 DXGK_MULTIPLANE_OVERLAY_PLANE。Enabled 为 false,显示微型端口驱动程序应禁用指定的平面。
  • 如果在上一次调用 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay 时启用了平面,但当前调用中不存在某个平面,则驱动程序应继续显示平面而不翻转平面。
  • 在同一 VSync 期间,驱动程序可能会收到对 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay 的多个调用, (一个调用翻转一个平面,另一个调用) 翻转其他平面。 在这种情况下,驱动程序应处理这两个调用。
  • 传递的数据应在用户模式下由受信任的源进行验证。 但是,显示微型端口驱动程序仍应检查数据,以确保它不会导致问题。 如果数据不正确,驱动程序可能会使调用失败并 出现STATUS_INVALID_PARAMETER 错误代码,但此类故障可能无法正常处理,并且意味着操作系统或用户模式驱动程序中存在 bug。

DxgkDdiSetVidPnSourceVisibility
DXGKARG_SETVIDPNSOURCEVISIBILITY时。在调用此函数时,在给定源上,Visible 设置为 FALSE,必须禁用所有硬件平面,包括用于主表面的层。 当 Visible 设置为 TRUE 时,必须仅启用用于主图面的平面,并且所有其他平面必须保持禁用状态。

DxgkDdiSetVidPnSourceAddress
调用此函数时,驱动程序应禁用所有非主覆盖平面。 在多平面覆盖模式下,主图面使用 DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay 翻转。

1. DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay 实现规范

1.1 平面启用/禁用控制

NTSTATUS APIENTRY DxgkDdiSetVidPnSourceAddressWithMultiPlaneOverlay(_In_ const DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY* pArgs)
{// 处理每个平面for (UINT i = 0; i < pArgs->PlaneCount; i++) {const DXGK_MULTIPLANE_OVERLAY_PLANE* pPlane = &pArgs->PlaneList[i];if (!pPlane->Enabled) {// 禁用指定平面DisableHwPlane(pPlane->PlaneId);} else {// 配置平面属性ProgramPlaneAttributes(pPlane);}}// 处理未包含但之前启用的平面for (UINT id : g_ActivePlanes) {if (!IsPlaneInCurrentRequest(id, pArgs)) {// 保持显示但不翻转内容MaintainPlaneWithoutFlip(id);}}return STATUS_SUCCESS;
}

1.2 多VSync调用处理

sequenceDiagramUMD->>KMD: SetVidPnSourceAddress(PlaneA Flip)KMD->>Hardware: 更新PlaneA缓冲区UMD->>KMD: SetVidPnSourceAddress(PlaneB Flip)KMD->>Hardware: 更新PlaneB缓冲区Hardware-->>Display: 同一VSync周期内提交AB平面

关键要求:

  • 必须支持同一VSync周期内的多次调用
  • 各平面更新需原子化提交

2. 可见性控制函数

2.1 DxgkDdiSetVidPnSourceVisibility 实现

NTSTATUS APIENTRY DxgkDdiSetVidPnSourceVisibility(_In_ const DXGKARG_SETVIDPNSOURCEVISIBILITY* pArgs)
{if (!pArgs->Visible) {// 禁用所有平面(包括主平面)for (UINT i = 0; i < MAX_PLANES; i++) {DisableHwPlane(i);}} else {// 仅启用主平面EnablePrimaryPlane(pArgs->VidPnSourceId);// 保持其他平面禁用for (UINT i = 1; i < MAX_PLANES; i++) {DisableHwPlane(i);}}return STATUS_SUCCESS;
}


2.2 状态转换规则

当前状态新Visible值操作要求
全部启用FALSE立即禁用所有平面
部分启用FALSE禁用剩余平面
全部禁用TRUE仅启用主平面
主平面启用TRUE无操作(维持状态)

3. 传统模式兼容性

3.1 DxgkDdiSetVidPnSourceAddress 行为

NTSTATUS APIENTRY DxgkDdiSetVidPnSourceAddress(_In_ const DXGKARG_SETVIDPNSOURCEADDRESS* pArgs)
{// 在非MPO模式下禁用所有叠加平面if (!IsInMpoMode()) {for (UINT i = 1; i < MAX_PLANES; i++) {DisableHwPlane(i);}}// 标准处理流程return OriginalSetVidPnSourceAddress(pArgs);
}

向后兼容要求:

  • 必须保持与非MPO显示模式的兼容性
  • 在传统模式下自动禁用叠加平面

4. 安全验证与错误处理

4.1 参数验证清单

BOOL ValidateMpoParams(const DXGKARG_SETVIDPNSOURCEADDRESSWITHMULTIPLANEOVERLAY* pArgs)
{// 基础检查if (pArgs->VidPnSourceId >= MAX_SOURCES || pArgs->PlaneCount > MAX_PLANES) {return FALSE;}// 平面属性验证for (UINT i = 0; i < pArgs->PlaneCount; i++) {const DXGK_MULTIPLANE_OVERLAY_PLANE* pPlane = &pArgs->PlaneList[i];if (pPlane->PlaneId >= MAX_PLANES ||!ValidateRect(&pPlane->SrcRect) ||!ValidateRect(&pPlane->DstRect)) {return FALSE;}}return TRUE;
}

4.2 错误处理规范

错误类型处理方式
无效VidPnSourceId返回STATUS_GRAPHICS_INVALID_VIDPN_SOURCEID
非法矩形坐标返回STATUS_INVALID_PARAMETER
硬件资源冲突返回STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE

5. 性能优化建议

5.1 平面状态缓存

typedef struct _PLANE_STATE_CACHE {BOOL Enabled;RECT SrcRect;RECT DstRect;FLOAT Alpha;
} PLANE_STATE_CACHE;// 全局缓存数组
PLANE_STATE_CACHE g_PlaneCache[MAX_PLANES];

5.2 差异更新机制

void SmartPlaneUpdate(UINT PlaneId, const DXGK_MULTIPLANE_OVERLAY_PLANE* pNewState)
{if (memcmp(&g_PlaneCache[PlaneId], pNewState, sizeof(PLANE_STATE_CACHE)) != 0) {// 仅当状态变化时更新硬件ProgramHwPlane(PlaneId, pNewState);g_PlaneCache[PlaneId] = *pNewState;}
}

6. WHQL 认证要求

6.1 必须通过的测试
Device.Graphics.WDDM.MPO.Visibility

  • 验证Visible=FALSE时的平面禁用
  • 测试主平面独占模式

Device.Graphics.WDDM.MPO.LegacyCompatibility

  • 传统SetVidPnSourceAddress调用时的行为

6.2 认证检查清单

  • 正确处理Enabled=false的平面
  • 实现VSync周期内的多调用支持
  • 完备的参数验证逻辑
  • 与传统模式的正确交互

7. 调试与诊断

7.1 注册表调试键

Windows Registry Editor Version 5.00[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WSD]
"LogMpoVisibilityChanges"=dword:00000001
"MpoParamValidationLevel"=dword:00000002

7.2 事件日志分析

# 查看MPO可见性变更记录
Get-WinEvent -ProviderName Microsoft-Windows-Win32k |
Where-Object {$_.Id -eq 300} |
Format-Table -Property TimeCreated, Message

 

http://www.lryc.cn/news/620324.html

相关文章:

  • 看懂 Linux 硬件信息查看与故障排查
  • 力扣42:接雨水
  • 人工智能入门①:AI基础知识(上)
  • Python图像处理基础(十三)
  • 《工程封装》(Python)
  • 网络安全合规6--服务器安全检测和防御技术
  • 3.Ansible编写和运行playbook
  • 3DM游戏运行库合集离线安装包下载, msvcp140.dll丢失等问题修复
  • ESP32_STM32_DHT20
  • 三极管的基极为什么需要下拉电阻
  • Vue3从入门到精通:4.1 Vue Router 4深度解析与实战应用
  • vue实现模拟 ai 对话功能
  • JS的学习5
  • vue修改element的css属性
  • 决策树回归:用“分而治之”的智慧,搞定非线性回归难题(附3D可视化)
  • 北京JAVA基础面试30天打卡09
  • uniapp授权登录
  • 硬件工程师八月实战项目分享
  • 8.13迎来联动:PUBG布加迪,新版本37.1内容资讯!低配置也能飙车吃鸡!
  • 谈一些iOS组件化相关的东西
  • 【Golang】 Context.WithCancel 全面解析与实战指南
  • CAN仲裁机制的原理
  • 【CV 目标检测】③——目标检测方法
  • 玳瑁的嵌入式日记D17-08013(linux文件编程)
  • 深度学习(5):激活函数
  • Linux 桌面到工作站的“性能炼金术”——开发者效率的 6 个隐形瓶颈与破解方案
  • Celery+RabbitMQ+Redis
  • AR展厅在文化展示与传承领域的应用​
  • 嵌入式学习(day26)frambuffer帧缓冲
  • 嵌入式|VNC实现开发板远程Debian桌面