window 显示驱动开发-将虚拟地址映射到内存段(二)

news2025/7/14 12:53:51

在将虚拟地址映射到段的一部分之前,视频内存管理器调用显示微型端口驱动程序的 DxgkDdiAcquireSwizzlingRange 函数,以便驱动程序可以设置用于访问可能重排的分配位的光圈。 驱动程序既不能将偏移量更改为访问分配的 PCI 光圈,也不能更改分配在光圈中占用的空间量。 例如,如果驱动程序无法在给定这些约束 (的情况下使分配 CPU 可访问,则硬件可能耗尽) 不显眼的光圈,则视频内存管理器会将分配逐出到系统内存,并允许应用程序访问其中的位。

如果在用户模式显示驱动程序调用 pfnLockCb 函数以请求直接访问内存时,以前创建的分配的内容位于系统内存中,则视频内存管理器会将系统内存缓冲区返回到用户模式显示驱动程序,并且显示微型端口驱动程序不涉及访问分配。 因此,显示微型端口驱动程序不会修改分配的内容,并且保持为未重排格式。 这意味着,当从视频内存中逐出 CPU 可访问的分配时,显示微型端口驱动程序必须取消重排分配,以便应用程序可以直接访问生成的系统内存位。

如果逐出与当前映射用于直接应用程序访问的分配关联的 GPU 资源,则分配的内容将传输到系统内存,以便应用程序可以继续访问同一虚拟地址但不同的物理介质上的内容。 为了设置传输,视频内存管理器调用显示微型端口驱动程序的 DxgkDdiBuildPagingBuffer 函数来创建分页缓冲区,GPU 计划程序调用驱动程序的 DxgkDdiSubmitCommand 函数将分页缓冲区排队到 GPU 执行单元。 特定于硬件的传输命令位于分页缓冲区中。 有关详细信息,请参阅 提交命令缓冲区。 视频内存管理器可确保视频到系统内存的转换对应用程序不可见。 但是,驱动程序必须确保通过 PCI 光圈对分配的字节排序与逐出分配时分配的字节顺序完全匹配。

对于光圈空间段,分配的基础位已位于系统内存中,因此无需传输 (逐出过程中取消重排) 数据。 因此,如果应用程序直接访问位于光圈空间段中的 CPU 可访问分配,则无法重排该分配。

如果某个表面可由应用程序直接通过 CPU 访问,但将在光圈空间段中重排,则显示驱动程序应将图面实现为两个不同的分配。 当用户模式显示驱动程序创建此类图面时,它可以调用 pfnAllocateCb 函数,并将 D3DDDICB_ALLOCATE 结构的 NumAllocations 成员设置为 2,并将 D3DDDICB_ALLOCATE 的pAllocationInfo 数组中D3DDDI_ALLOCATIONINFO结构的 pPrivateDriverData 成员设置为指向有关分配 (的私有数据,例如其重排格式和未重排格式) 。 GPU 将使用的分配包含重排格式的位,应用程序将访问的分配包含未重排格式的位。 视频内存管理器调用显示微型端口驱动程序的 DxgkDdiCreateAllocation 函数来创建分配。 对于从用户模式显示驱动程序传递的每个分配) ,显示微型端口驱动程序解释DXGK_ALLOCATIONINFO结构的 pPrivateDriverData 成员中的专用数据 (。 视频内存管理器不知道分配的格式;它只是为分配分配分配特定大小和对齐方式的内存块。 调用用户模式显示驱动程序的 Lock 函数以锁定图面进行处理会导致以下操作:

  1. 用户模式显示驱动程序调用 pfnRenderCb 函数,将命令缓冲区中的取消重排操作提交到 Direct3D 运行时和显示微型端口驱动程序。
  2. 用户模式显示驱动程序调用 pfnLockCb 函数来锁定未重排的分配。 请注意,用户模式显示驱动程序不得在 D3DDDICB_LOCK 结构的 Flags 成员中设置D3DDDILOCKCB_DONOTWAIT标志。
  3. pfnLockCb 函数将等待传输 (在分配之间展开) 。
  4. pfnLockCb 函数请求显示微型端口驱动程序获取未重排分配的虚拟地址,并将虚拟地址返回到 D3DDDICB_LOCKpData 成员中的用户模式显示驱动程序。
  5. 用户模式显示驱动程序将未重排分配的虚拟地址返回到 D3DDDIARG_LOCK 的 pSurfData 成员中的应用程序。

 下图演示了如何将虚拟地址映射到线性光圈空间段的基础页面。

1. 重排分配与 CPU 访问的冲突

问题背景:
某些图形分配(如纹理)可能被硬件“重排”(swizzled)以优化 GPU 访问性能,但这种格式对 CPU 不友好。如果应用程序需要直接通过 CPU 访问这些分配(如 Lock 操作),则需要取消重排(unswizzle)。

约束条件:

  • 显示微型端口驱动程序(Display Miniport Driver)在 DxgkDdiAcquireSwizzlingRange 中不能修改 PCI 光圈的偏移或大小。
  • 若硬件无法满足 CPU 访问的约束(如光圈空间不足),视频内存管理器(VidMM)会将分配逐出(evict)到系统内存,并取消重排。

2. 系统内存中的分配访问

直接访问系统内存:如果分配已被逐出到系统内存,用户模式显示驱动(UMD)通过 pfnLockCb 直接获取系统内存指针,微型端口驱动不参与,内容保持未重排格式。

关键要求:在逐出时,驱动程序必须确保取消重排,使系统内存中的数据是 CPU 可读的线性格式。

3. GPU 资源逐出与分页机制

动态逐出处理:
若 GPU 正在使用的分配被逐出(如因内存压力),VidMM 会通过以下步骤透明迁移数据:

  1. 调用 DxgkDdiBuildPagingBuffer 创建分页缓冲区(包含硬件特定的传输命令)。
  2. 通过 DxgkDdiSubmitCommand 提交到 GPU 执行。
  3. 确保迁移对应用程序透明(虚拟地址不变,物理介质变化)。

数据一致性:驱动程序必须保证 PCI 光圈中的字节顺序与逐出时的系统内存完全一致。

4. 光圈空间段的特殊处理

无重排需求:光圈空间段(Aperture Segment)的分配本身位于系统内存,无需重排。若应用程序直接访问此类分配,驱动程序必须禁止重排。

5. 双分配策略(重排与非重排共存)

适用场景:
若一个表面需要同时满足:

  • GPU 访问(重排格式优化性能)。
  • CPU 访问(未重排格式保证兼容性)。

实现方式:

  • UMD 调用 pfnAllocateCb 创建 两个分配(NumAllocations=2),分别存储重排和未重排数据。
  • 通过 pPrivateDriverData 传递格式信息(如重排参数)。
  • 微型端口驱动在 DxgkDdiCreateAllocation 中解析私有数据,管理两种格式。

Lock 操作流程:

  • UMD 提交命令缓冲区(pfnRenderCb)取消重排(GPU 执行格式转换)。
  • 调用 pfnLockCb 锁定未重排的分配(等待转换完成)。
  • 返回未重排分配的虚拟地址给应用程序。

六、关键驱动责任

  1. 格式转换:在逐出或 Lock 时,确保重排数据转换为线性格式。
  2. 双分配管理:维护重排/未重排副本的一致性(如通过 GPU 命令同步)。
  3. 透明性:确保应用程序无感知(虚拟地址不变,物理介质可能变化)。

总结
这段描述揭示了 WDDM 如何平衡 GPU 性能(重排)与 CPU 可访问性,通过动态逐出、分页缓冲区、双分配等机制实现高效内存管理。驱动程序需正确处理重排/取消重排、分页操作及多副本同步,以满足图形和计算应用的多样化需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2374487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【文心智能体】使用文心一言来给智能体设计一段稳定调用工作流的提示词

🌹欢迎来到《小5讲堂》🌹 🌹这是《文心智能体》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正&#xff0…

K8S中构建双架构镜像-从零到成功

背景介绍 公司一个客户的项目使用的全信创的环境,服务器采用arm64的机器,而我们的应用全部是amd64的,于是需要对现在公司流水线进行arm64版本的同步镜像生成。本文介绍从最开始到最终生成双架构的全部过程,以及其中使用的相关配置…

c语言第一个小游戏:贪吃蛇小游戏03

我们为贪吃蛇的节点设置为一个结构体,构成贪吃蛇的身子的话我们使用链表,链表的每一个节点是一个结构体 显示贪吃蛇身子的一个节点 我们这边node就表示一个蛇的身体 就是一小节 输出结果如下 显示贪吃蛇完整身子 效果如下 代码实现 这个hasSnakeNode(…

​​​​​​​大规模预训练范式(Large-scale Pre-training)

大规模预训练指在巨量无标注数据上,通过自监督学习训练大参数量的基础模型,使其具备通用的表征与推理能力。其重要作用如下: 一 跨任务泛化 单一模型可在微调后处理多种NLP(自然语言处理)、CV(计算机视觉…

WPF之高级绑定技术

文章目录 引言多重绑定(MultiBinding)基本概念实现自定义IMultiValueConverterMultiBinding在XAML中的应用示例使用StringFormat简化MultiBinding 优先级绑定(PriorityBinding)基本概念PriorityBinding示例实现PriorityBinding的后…

调出事件查看器界面的4种方法

方法1. 方法2. 方法3. 方法4.

使用vite重构vue-cli的vue3项目

一、修改依赖 首先修改 package.json,修改启动方式与相应依赖 移除vue-cli并下载vite相关依赖,注意一些peerDependency如fast-glob需要手动下载 # 移除 vue-cli 相关依赖 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…

数据治理域——数据治理体系建设

摘要 本文主要介绍了数据治理系统的建设。数据治理对企业至关重要,其动因包括应对数据爆炸增长、提升内部管理效率、支撑复杂业务需求、加强风险防控与合规管理以及实现数字化转型战略。其核心目的是提升数据质量、统一数据标准、优化数据资产管理、支撑业务发展和…

onGAU:简化的生成式 AI UI界面,一个非常简单的 AI 图像生成器 UI 界面,使用 Dear PyGui 和 Diffusers 构建。

​一、软件介绍 文末提供程序和源码下载 onGAU:简化的生成式 AI UI界面开源程序,一个非常简单的 AI 图像生成器 UI 界面,使用 Dear PyGui 和 Diffusers 构建。 二、Installation 安装 文末下载后解压缩 Run install.py with python to setup…

【第52节】Windows编程必学之从零手写C++调试器下篇(仿ollydbg)

目录 一、引言 二、调试器核心功能设计与实现 三、断点功能 四、高级功能 五、附加功能 六、开发环境与实现概要 七、项目展示及完整代码参考 八、总结 一、引言 在软件开发领域,调试器是开发者不可或缺的工具。它不仅能帮助定位代码中的逻辑错误&#xff0…

uni-app学习笔记五--vue3插值表达式的使用

vue3快速上手导航&#xff1a;简介 | Vue.js 模板语法 插值表达式 最基本的数据绑定形式是文本插值&#xff0c;它使用的是“Mustache”语法 (即双大括号)&#xff1a; <span>Message: {{ msg }}</span> 双大括号标签会被替换为相应组件实例中 msg 属性的值。同…

C++类与对象(二):六个默认构造函数(一)

在学C语言时&#xff0c;实现栈和队列时容易忘记初始化和销毁&#xff0c;就会造成内存泄漏。而在C的类中我们忘记写初始化和销毁函数时&#xff0c;编译器会自动生成构造函数和析构函数&#xff0c;对应的初始化和在对象生命周期结束时清理资源。那是什么是默认构造函数呢&…

从逻辑学视角探索数学在数据科学中的系统应用:一个整合框架

声明&#xff1a;一家之言&#xff0c;看个乐子就行。 图表采用了两个维度组织知识结构&#xff1a; 垂直维度&#xff1a;从上到下展示了知识的抽象到具体的演进过程&#xff0c;分为四个主要层级&#xff1a; 逻辑学基础 - 包括数理逻辑框架和证明理论数学基础结构 - 涵盖…

Matplotlib 完全指南:从入门到精通

前言 Matplotlib 是 Python 中最基础、最强大的数据可视化库之一。无论你是数据分析师、数据科学家还是研究人员&#xff0c;掌握 Matplotlib 都是必不可少的技能。本文将带你从零开始学习 Matplotlib&#xff0c;帮助你掌握各种图表的绘制方法和高级技巧。 目录 Matplotli…

如何有效追踪需求的实现情况

有效追踪需求实现情况&#xff0c;需要清晰的需求定义、高效的需求跟踪工具、持续的沟通反馈机制&#xff0c;其中高效的需求跟踪工具尤为关键。 使用需求跟踪工具能确保需求实现进度可视化、提高团队协作效率&#xff0c;并帮助识别和管理潜在风险。例如&#xff0c;使用专业的…

自动驾驶技术栈——DoIP通信协议

一、DoIP协议简介 DoIP&#xff0c;英文全称是Diagnostic communication over Internet Protocol&#xff0c;是一种基于因特网的诊断通信协议。 DoIP协议基于TCP/IP等网络协议实现了车辆电子控制单元(ECU)与诊断应用程序之间的通信&#xff0c;常用于汽车行业的远程诊断、远…

C++ 与 Go、Rust、C#:基于实践场景的语言特性对比

目录 ​编辑 一、语法特性对比 1.1 变量声明与数据类型 1.2 函数与控制流 1.3 面向对象特性 二、性能表现对比​编辑 2.1 基准测试数据 在计算密集型任务&#xff08;如 10⁷ 次加法运算&#xff09;中&#xff1a; 在内存分配测试&#xff08;10⁵ 次对象创建&#xf…

如何更改默认字体:ONLYOFFICE 协作空间、桌面编辑器、文档测试示例

在处理办公文件时&#xff0c;字体对提升用户体验至关重要。本文将逐步指导您如何在 ONLYOFFICE 协作空间、桌面应用及文档测试示例中自定义默认字体&#xff0c;以满足个性化需求&#xff0c;更好地掌控文档样式。 关于 ONLYOFFICE ONLYOFFICE 是一个国际开源项目&#xff0c…

设计模式之工厂模式(二):实际案例

设计模式之工厂模式(一) 在阅读Qt网络部分源码时候&#xff0c;发现在某处运用了工厂模式&#xff0c;而且编程技巧也用的好&#xff0c;于是就想分享出来&#xff0c;供大家参考&#xff0c;理解的不对的地方请多多指点。 以下是我整理出来的类图&#xff1a; 关键说明&#x…

基于VeRL源码深度拆解字节Seed的DAPO

1. 背景与现状&#xff1a;从PPO到GRPO的技术演进 1.1 PPO算法的基础与局限 Proximal Policy Optimization&#xff08;PPO&#xff09;作为当前强化学习领域的主流算法&#xff0c;通过重要性采样比率剪裁机制将策略更新限制在先前策略的近端区域内&#xff0c;构建了稳定的…