当前位置: 首页 > 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.dtcms.com/a/329751.html

相关文章:

  • MVCC底层实现原理
  • Flask入门:从零搭建Web服务器
  • 雅思大作文笔记
  • iOS 签名证书在版本迭代和iOS上架中的全流程应用
  • Docker 在 Linux 中的额外资源占用分析
  • 智汇河套,量子“风暴”:量子科技未来产业发展论坛深度研讨加速产业成果转化
  • 信息学奥林匹克竞赛(NOI/NOIP/CSP) 学习进度自查表
  • 使用 Python Selenium 和 Requests 实现歌曲网站批量下载实战
  • 嵌入式学习 day50 IMX6ULL裸机开发 - 时钟
  • Linux 5.15.189-rt87 实时内核安装 NVIDIA 显卡驱动
  • 手机充电线贴标机如何使用
  • 内存可见性和伪共享问题
  • php7 太空船运算符
  • 在实验室连接地下车库工控机及其数据采集设备
  • 《零基础入门AI:深度学习中的视觉处理(卷积神经网络(CNN)学习)》
  • Github desktop介绍(GitHub官方推出的一款图形化桌面工具,旨在简化Git和GitHub的使用流程)
  • SpringMVC 6+源码分析(六)参数处理
  • 18. parseInt 的参数有几个
  • C语言——深入理解指针(三)
  • 【LeetCode】6. Z 字形变换
  • 美团搜索推荐统一Agent之性能优化与系统集成
  • Linux小白加油站,第二周
  • 云手机未来的发展趋势如何?
  • docker load镜像后 名字和标签异常解决
  • Centos 用户管理
  • [Oracle数据库] Oracle的表维护
  • 使用dify搭建hr简历助手-上传简历-对接飞书ai表格
  • .NET 应用程序 Linux下守护进程脚本编写
  • 集成电路学习:什么是Image Processing图像处理
  • GIS 常用的矢量与栅格分析工具