DRI是包含现代 Linux 图形堆栈的框架,它允许非特权用户空间程序向图形硬件发出命令,而不会与其他程序发生冲突。DRI 的主要用途是为 OpenGL 实现的 Mesa 提供硬件加速,也适用于为没有图形界面的framebuffer console提供OpenGL加速。
DRI实现分散在X Server及其关联的clients库、Mesa 3D和DRM中。所有的源代码都是开源免费的。

概述

在经典的 X Window 系统架构中,X Server 是唯一能够独占访问图形硬件的进程,因此也是在framebuffer进行实际渲染的进程。X clients所做的就是与 X Server通信以分派渲染命令。这些命令是独立于硬件的,这意味着 X11 协议提供了一个提取图形设备的 API,因此 X clients不需要担心底层硬件的细节。任何依赖硬件的代码都位于设备相关 X 中,X Server 中管理video card或显卡驱动的部分,通常也称为视频或图形驱动程序。
3D渲染的兴起把这种框架的缺点暴露了出来。3D图形应用程序倾向于生成大量的命令和数据,这些命令和数据都必须发送到X Server进行渲染。随着 X client和 X Server 之间的进程间通信 (IPC) 数量的增加,3D 渲染性能受到了影响。X 驱动程序开发人员为了利用最新显卡的 3D 硬件功能,需要新的无 IPC 架构。Xclients应该直接访问图形硬件,而不是依赖第三方进程来执行此操作,从而节省所有 IPC 开销,这种方法称为“direct rendering”。DRI最初是为了允许任何X clients使用这种“direct rendering”方法执行3D渲染。

架构

DRI基础架构包含3个主要组件:

  • DRI client是一个可以直接执行’direct rendering’的X client - 需要一个硬件特定的驱动程序来管理video card或者显卡驱动以便可以在其上可以渲染。这些 DRI 驱动程序通常作为客户端动态链接共享库提供。
  • X Server提供了一个X11扩展协议(DRI扩展),DRI 客户端使用该扩展与窗口系统和 DDX 驱动程序进行协调。作为 DDX 驱动程序的一部分,X Server进程也同样动态链接到与DRI client相同的DRI驱动程序,但是会使用GLX扩展为X clients提供硬件3D加速渲染以进行间接渲染(如远程X clients不能直接使用渲染)。对于2D渲染,DDX 驱动程序还必须考虑使用相同图形设备的 DRI 客户端。
  • 对video card或显卡驱动的访问由DRM内核模块管理。但是X Server DDX驱动和每个X Client DRI驱动必须使用DRM来访问显卡。 DRM 为显卡的共享资源(例如命令队列、卡寄存器、视频内存、DMA 引擎等资源)提供同步,确保多个用户空间进程的并发访问不会互相干扰。 DRM还有安全保护的作用,它不允许任何X客户端访问执行3D渲染所需的硬件。

DRI1阶段

在最初的 DRI 架构中,由于当时video card的内存大小,屏幕back-buffer和front-buffer的单例被DRI client和X Server所共享。渲染的数据会被先写入back-buffer,然后在v-blank间隔时间会与front-buffer进行交换。为了把数据渲染到back-buffer,DRI进程应该确保裁剪渲染数据只保留可视窗口大小。
与 X Server的同步是通过信号和称为 SAREA 的共享内存缓冲区完成的。对 DRM 设备的访问通道是唯一的,因此任何 DRI clients都必须在渲染操作开始时锁定它,其他client期间无法访问,必须等到当前渲染操作结束时释放锁。另一个缺点是在当前 DRI 进程在设备上释放锁后,操作涉及的内存不会常驻,因此上传到显存的任何数据(如纹理)都会丢失,以供即将进行的操作使用,从而对图形性能产生重大影响。

DRI2阶段

由于像 Compiz 这样的合成窗口管理器越来越受欢迎,DRI 必须重新设计以便X client在进行直接渲染时也同样支持重定向到"offscreen-pixmaps"。常规的 X client已经将 X 服务器提供的单独像素图作为渲染目标(所谓的"offscreen-pixmaps"),但 DRI client继续直接在共享的back-buffer中进行渲染,有效地绕过了合成窗口管理器。最终的解决方案是改变DRI处理渲染buffer的方式,这会导致具有一组完全不同的DRI扩展接口,并且DRM也发生了巨大变化。新的扩展名为“DRI2”,虽然它不是更高版本,而是一个不同的扩展,甚至与原始 DRI 不兼容——事实上,两者在 X Server 中共存了很长时间。
在DRI2中,每个DRI client都拥有自己私有的 back-buffer来通过硬件加速渲染器窗口内容,而不是共享back-buffer。然而,DRI client将其与一个假的"front-buffer"进行交换。假的"front-buffer"是合成窗口管理器最终合成屏幕缓冲区的buffer之一,,在 VBLANK 间隔与实际的front-buffer进行交换。
为了处理所有这些新的buffer,DRM必须必须要有新功能,特别是显存管理器。DRI2最初使用的是还不成熟的TTM内存管理器,但是DRM内存管理器还是最终选择了GEM。新的DRI2内部buffer管理模型还解决了最初 DRI 中存在的两个主要性能瓶颈:

  • DRI2 clinet在使用它进行渲染的时候不再锁住整个DRM设备,因为现在每个client都获得了一个独立于其他进程的单独渲染buffer.
  • DRI2 client可以在显存中分配自己的buffer(带有纹理、顶点列表等),并且根据需要可以常驻,从而减少显存带宽消耗。

在DRI2中,为窗口分配私有offscreen-buffers(back-buffer、fake-front-buffer、 depth-buffer、stencil-buffer等)由X Server自己完成。DRI client通过调用 DRI2 扩展中 DRI2GetBuffers 和 DRI2GetBuffersWithFormat 等接口来检索这些buffers以便渲染到窗口中。在内部,DRI2 使用 GEM 名称——一种由 GEM API 提供的全局句柄,允许访问 DRM 设备的两个进程引用同一个缓冲区。
X Server 负责窗口渲染buffer分配的原因是 GLX 扩展允许多个 X client在同一个窗口中协同进行 OpenGL 渲染。 这样,X Server在整个渲染过程中管理渲染buffer的整个生命周期,并知道何时可以安全地回收它们。当调整窗口大小时,X server负责分配新的渲染buffer来匹配新的窗口大小,并使用 InvalidateBuffers 事件通知DRI clinet渲染到窗口中的更改,以便他们检索 GEM新缓冲区的名称。
DRI2 扩展为 DRI client提供了其他核心操作,如DRI2Connect接口可以找出他们应该使用哪个 DRM 设备和驱动程序 或DRI2Authenticate接口通过 X Server进行身份验证以便能够使用 DRM 设备的渲染和缓冲设施。使用 DRI2CopyRegion 和 DRI2SwapBuffers 请求在屏幕中呈现渲染buffer。DRI2CopyRegion 可用于在fake-front-buffer和real-front-buffer之间进行复制,但它不提供与v-black间隔的任何同步,因此会导致撕裂。 另一方面,DRI2SwapBuffers在back-buffer和front-buffer之间执行v-blank同步交换。

DRI3阶段

虽然 DRI2 比DRI 有了显着的改进,不过扩展也引入了一些新的问题。2013年,为了解决新的问题,DRI3作为DRI的第3次迭代被开发了。
DRI3 与 DRI2 相比的主要区别在于:

  • DRI3 client为自己分配渲染缓冲区,而不是依赖 X Server进行分配(这是DRI2 支持的方法)。
  • DRI3 摆脱了旧的基于 GEM 名称(全局 GEM 句柄)的不安全 GEM buffer共享机制(用于在 DRI client和 X Server之间传递buffer对象),转而采用基于 PRIME DMA-BUF(使用文件描述符) 的更安全和通用的机制。

client的缓冲区分配打破了 GLX 的假设,因为多个 GLX 应用程序不再可能在同一个窗口中协同渲染。 从好的方面来说,DRI client在其生命周期内负责自己的缓冲区这一事实带来了许多优势,例如DRI3 client很容易确保渲染buffer的大小始终与窗口的当前大小相匹配,从而消除由于client和server之间缺乏缓冲区大小同步而困扰窗口大小调整。还实现了更好的性能,因为 DRI3 client节省了等待 X server发送渲染buffer的额外耗时。DRI3 client(尤其是合成器窗口管理器)可以利用保留前一帧的buffer区并重用它们仅对渲染窗口中变化的部分进行重绘。DRI3 扩展不再需要修改以支持新的特定缓冲区格式,因为现在直接在 DRI client驱动程序和 DRM kernel驱动程序之间处理。另一方面,文件描述符的使用允许kernel对任何未使用的 GEM buffer对象执行安全清理。
从技术上将,DRI3包含2个扩展:“DRI3”扩展和“Present”扩展。DRI3 扩展的主要目的是实现在 DRI client和 X Server之间共享直接渲染buffer的机制。DRI client分配和使用 GEM buffer对象作为渲染目标,而 X server使用一种称为“pixmap”的 X11 对象表示这些渲染缓冲区。DRI3 提供了两种接口:DRI3PixmapFromBuffer 和 DRI3BufferFromPixmap,前者是从 GEM buffer对象(在“DRI client空间”中)创建pixmap (在“X server空间”中),后者是反向操作。在这些 DRI3 接口中,GEM buffer对象作为 DMA-BUF 文件描述符而不是 GEM 名称传递。DRI3 还提供了一种在 DRI client和 X server之间共享同步对象的方法,允许对共享buffer进行序列化访问。和 DRI2不同,DRI3Open(每个 DRI 客户端必须请求知道要使用哪个 DRM 设备的操作)将已打开的文件描述符返回到设备节点而不是设备节点文件名,并且任何所需的身份验证过程已经提前执行 X sever。
DRI3 没有提供在屏幕上显示渲染缓冲区的机制,而是依赖另一个扩展,即 Present 扩展来做到这一点。Present 之所以如此命名,是因为它的主要任务是在屏幕上“Present ”缓冲区,这意味着它使用client应用程序提供的渲染缓冲区的内容来处理帧缓冲区的更新。屏幕更新必须在适当的时间完成,通常是在 VBLANK 间隔期间,以避免出现撕裂等显示问题。Present 还处理屏幕更新到 VBLANK 间隔的同步。它还使用事件让 X client知道每个缓冲区真正显示在屏幕上的时刻,因此client可以将其渲染过程与当前屏幕刷新率同步。

Present 接受任何 X pixmap 作为屏幕更新的来源.由于pixmap 是标准的 X 对象,Present 不仅可以由执行直接渲染的 DRI3 客户端使用,而且可以由任何 X 客户端以任何方式在pixmap 上渲染。例如大多数基于非 GL 的 GTK+ 和 Qt 应用程序过去使用 XRender 进行双缓冲pixmap 渲染。这些应用程序也可以使用 Present 扩展来实现高效且无撕裂的屏幕更新。这就是 Present 作为独立扩展而不是 DRI3 的一部分的原因。
除了允许非 GL X client与 VBLANK 同步之外,Present 还有其他优势。DRI3 图形性能更好,因为 Present 在交换缓冲区方面比​​ DRI2 更有效。基于 Present 提供的新功能, DRI2 中许多不可用的 OpenGL 扩展被支持。
Present 为 X client提供了两个主要接口:PresentPixmap:使用pixmap 的部分或全部内容更新窗口的区域;PresentSelectInput :设置与client想要通知的窗口的Present事件的类型 。窗口可以通知 X client的三个Present事件:1、当PresentPixmap 的调用完成时(PresentCompleteNotify); 2、当 PresentPixmap 使用的pixmap 准备好被重用时(PresentIdleNotify ); 3、当窗口配置(主要是窗口大小)发生变化时 (PresentConfigureNotify)。PresentPixmap 执行直接复制 (blit) 到front-buffer还是整个back-buffer与front-buffer的交换是 Present 扩展实现的内部细节,而不是 像DRI2那样X cleint的显式选择。

采用

几个开源 DRI 驱动程序,包括用于 ATI Mach64、ATI Rage128、ATI Radeon、3dfx Voodoo3 到 Voodoo5、Matrox G200 到 G400、SiS 300 系列、Intel i810 到 i965、S3 Savage、VIA UniChrome 图形芯片组和 Nvidia的nouveau。一些图形供应商使用的闭源 DRI 驱动程序,包括 ATI 和 PowerVR Kyro。
各种版本的 DRI 已由各种操作系统实现,其中包括 Linux kernel、FreeBSD、NetBSD、OpenBSD 和 OpenSolaris。

历史

该项目由 Precision Insight(由 Silicon Graphics 和 Red Hat 资助)的 Jens Owen 和 Kevin E. Martin 发起,它最初是作为 XFree86 4.0的一部分广泛使用的,现在是 X.Org Server 的一部分。它目前由自由软件社区维护。
DRI2 的工作始于 2007 年 X 开发者峰会,由 Kristian Høgsberg 提出。Høgsberg 自己编写了新的 DRI2 扩展以及对 Mesa 和 GLX 的修改。2008 年 3 月,DRI2 基本完成,但它无法进入 X.Org Server 版本 1.5,不得不从 2009 年 2 月开始等到版本 1.6。DRI2 扩展正式包含在 2009 年 10 月的 X11R7.5 版本中。 DRI2 协议 (2.0) 的第一个公共版本于 2009 年 4 月发布。从那以后进行了多次修订,最近的版本是 2012 年 7 月的 2.8 版。
由于 DRI2 的一些限制,Keith Packard 和 Emma Anholt 在 2012 年 X.Org 开发者大会上提出了一个名为 DRI-Next 的新扩展,该扩展在 Linux.conf.au 2013 上再次被提议为 DRI3000,DRI3 和 Present 扩展是在 2013 年开发的,并于 2013 年 12 月合并到 X.Org Server 1.15 版本中。DRI3 协议 (1.0) 的第一个也是唯一一个版本于 2013 年 11 月发布。下面5个图是DRI框架变化过程:

图1:2D drivers在X Server

图2:通过GLX间接渲染

图3:早期DRI:由X-display-server以root身份执行mode-setting

图4:所有访问都通过DRM进行

图5:在Linux内核3.12中引入了渲染节点;DRM 和 KMS 驱动程序被拆分。Wayland 通过 EGL 实现直接渲染

drm学习笔记3-DRI介绍相关推荐

  1. Hadoop学习笔记一 简要介绍

    Hadoop学习笔记一 简要介绍 这里先大致介绍一下Hadoop.     本文大部分内容都是从官网Hadoop上来的.其中有一篇介绍HDFS的pdf文档,里面对Hadoop介绍的比较全面了.我的这一 ...

  2. MongoDB学习笔记(一) MongoDB介绍及安装

    系列目录 MongoDB学习笔记(一) MongoDB介绍及安装     MongoDB学习笔记(二) 通过samus驱动实现基本数据操作     MongoDB学习笔记(三) 在MVC模式下通过Jq ...

  3. Typescript 学习笔记一:介绍、安装、编译

    前言 整理了一下 Typescript 的学习笔记,方便后期遗忘某个知识点的时候,快速回忆. 为了避免凌乱,用 gitbook 结合 marketdown 整理的. github地址是:ts-gitb ...

  4. Ui学习笔记---EasyUI的介绍

    Ui学习笔记---EasyUI的介绍 -------------------------- 1.组织:   a.EasyUI官方:http://www.jeasyui.com     EasyUI是一 ...

  5. vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍

    这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...

  6. MeayunDB学习笔记(一) MeayunDB介绍及安装

    系列目录 MeayunDB介绍-高性能分布式内存数据库 MeayunDB学习笔记(一)MeayunDB介绍及安装 MeayunDB学习笔记(二)批量导入数据 MeayunDB学习笔记(三)索引应用 一 ...

  7. 变分推断(variational inference)学习笔记(1)——概念介绍

    ref:http://www.crescentmoon.info/?p=709#more-709 问题描述 变分推断是一类用于贝叶斯估计和机器学习领域中近似计算复杂(intractable)积分的技术 ...

  8. Opencv学习笔记之OpenCV介绍

    一.  OpenCV介绍 OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效--由一系列 ...

  9. Unity 3D学习笔记之一 界面介绍

    因为学校的课程,本学期对Unity 3D有学习的要求,在博客中记录下自己的Unity学习之路(内容摘录自书本和视频,书本为Unity 4.x从入门到精通) 一.Unity界面介绍      首先进入U ...

最新文章

  1. NO.7:别让异常逃离析构函数
  2. shardingjdbc全局表_Sharding-JDBC动态分表实现
  3. URAL 1635 Mnemonics and Palindromes
  4. 范围for语句的整理
  5. Java 接口和抽象类可以被new么?——顺便总结内部类
  6. HttpClientFactory 结合 Polly 轻松实现重试机制
  7. 2017《Java技术》预备作业 杨阳
  8. 为你揭秘小程序音视频背后的故事......
  9. yarn install命令运行报错:无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
  10. 软件使用,Microsoft Visual C++运行库合集包
  11. 光缆弹性模量计算_光缆的基本常识
  12. Python代码制作“恐龙跳一跳“小游戏
  13. 屏幕种类有哪些,特点,怎么挑?TFT、LCD、OLED、IPS、TN的含义与区别?高色域、刷新率、广视角、雾面屏又是什么?
  14. 给出某个时间段,要求以三十分钟为分割,统计出每三十分钟内数据的数量
  15. JDBC SSL连接MySQL
  16. “数字江豚”背后的最严禁渔令!华为云助力武汉打响生态保卫战
  17. React Hooks Ant table 显示/隐藏特定的列
  18. 《Effective Modern C++》笔记
  19. C#开发Active控件
  20. 北京科技大学871计算机真题,(NEW)北京科技大学871计算机综合一(含计算机组成原理、数据结构)历年考研真题汇编(350页)-原创力文档...

热门文章

  1. android 视频转表情包,视频转gif动图怎么转?一款能制作表情包的软件,年轻人很爱用...
  2. 步进电机基础(7.1)-步进电机的选择方法-电机种类的选择(各种步进电机的优缺点)
  3. Latex 符号上加符号的方式
  4. 二叉树的非递归遍历(C语言实现)
  5. 睡眠剥夺后皮层微结构的广泛变化
  6. 电脑文件如何自动备份到移动硬盘
  7. 高校计算机教研室工作计划,高校教研室工作计划
  8. 2021校园照片芯片岗位笔试题知识点(华为,OPPO,紫光,大疆)
  9. JAVA有什么办法让定时停止,java通过接口开启和停止定时任务
  10. 第17集 ​ 间接问句