尽管 DRI2 比原始 DRI 有了显着改进,但新扩展也引入了一些新问题。 2013 年,为了解决这些问题,开发了第三次迭代的直接渲染基础设施(称为 DRI3)。
DRI3 与 DRI2 相比的主要区别是:
DRI3 客户端分配其渲染缓冲区,而不是依赖 X Server 进行分配,这是 DRI2 支持的方法。
DRI3 摆脱了基于 GEM 名称(全局 GEM 句柄)的旧的不安全 GEM 缓冲区共享机制,用于在 DRI 客户端和 X Server 之间传递缓冲区对象,转而采用基于 PRIME DMA-BUF 的更安全和通用的机制,该机制使用文件描述符代替。
客户端的缓冲区分配打破了 GLX 假设,因为多个 GLX 应用程序不再可能在同一窗口中协作渲染。从好的方面来说,DRI 客户端在其整个生命周期中负责自己的缓冲区这一事实带来了许多优势。例如,DRI3 客户端很容易确保渲染缓冲区的大小始终与窗口的当前大小匹配,从而消除由于客户端和服务器之间缓冲区大小不同步而困扰窗口大小调整的伪影在 DRI2 中。由于现在 DRI3 客户端节省了等待 X 服务器发送渲染缓冲区的额外往返时间,因此还实现了更好的性能。 DRI3 客户端,尤其是合成器窗口管理器,可以利用保留先前帧的较旧缓冲区并重用它们作为仅渲染窗口损坏部分的基础,作为另一种性能优化。[15][16] DRI3 扩展不再需要修改以支持新的特定缓冲区格式,因为它们现在直接在 DRI 客户端驱动程序和 DRM 内核驱动程序之间处理。 [15]另一方面,使用文件描述符允许内核对任何未使用的 GEM 缓冲区对象执行安全清理——没有引用它的对象。
从技术上讲,DRI3 由两个不同的扩展组成,“DRI3”扩展和“Present”扩展。[17][19] DRI3 扩展的主要目的是实现在 DRI 客户端和 X Server 之间共享直接渲染缓冲区的机制。[18][19][20] DRI 客户端分配并使用 GEM 缓冲区对象作为渲染目标,而 X 服务器使用称为“pixmap”的 X11 对象类型来表示这些渲染缓冲区。 DRI3 提供了两种操作,DRI3PixmapFromBuffer 和 DRI3BufferFromPixmap,一种是从 GEM 缓冲区对象(在“DRI 客户端空间”中)创建像素图(在“X 服务器空间”中),另一种是执行相反的操作并从中获取 GEM 缓冲区对象X 像素图。[18][19][20]在这些 DRI3 操作中,GEM 缓冲区对象作为 DMA-BUF 文件描述符而不是 GEM 名称传递。 DRI3 还提供了一种在 DRI 客户端和 X Server 之间共享同步对象的方法,允许对共享缓冲区进行序列化访问。 [19]与 DRI2 不同,初始 DRI3Open 操作(每个 DRI 客户端必须首先请求知道要使用哪个 DRM 设备)将一个已打开的文件描述符返回到设备节点而不是设备节点文件名,并且任何所需的身份验证过程已提前执行X服务器.
DRI3 没有提供在屏幕上显示渲染缓冲区的机制,而是依赖另一个扩展(Present 扩展)来执行此操作。 Present 之所以如此命名,是因为它的主要任务是在屏幕上“呈现”缓冲区,这意味着它使用客户端应用程序提供的渲染缓冲区的内容来处理帧缓冲区的更新。屏幕更新必须在适当的时间完成,通常是在 VBLANK 间隔期间,以避免出现撕裂等显示伪像。 Present 还处理屏幕更新与 VBLANK 间隔的同步。它还使用事件让 X 客户端了解每个缓冲区真正显示在屏幕上的时刻,以便客户端可以将其渲染过程与当前屏幕刷新率同步。
DRI3 是基于 DMA-BUF 实现在 DRI client和 X Server 之间共享直接渲染 buffer 的机制。
DRI3 与 DRI2 相比的主要区别在于:
1. DRI3 client 自己分配渲染缓冲区,而不是依赖 X Server进行分配。
2. DRI3 采用基于 PRIME DMA-BUF(使用文件描述符) 的更安全和通用的机制,完成多进程间buffer共享。
DRI3 分为两个扩展
1. DRI3 扩展
支持 DMA-BUF 机制,可以实现同一块显存在 client 与 server 之间的传递。
2. present 扩展
支持将 client 渲染的 pixmap 当作窗口内容显示。
Linux kernel引入了 DMA-BUF 这个框架(或者说是子系统),来解决CPU和各种不同外设驱动之间buffer共享的问题。
1. DMA buffer是一块允许在 CPU 和其他子系统或各种IO外设间共享的buffer。
2. DMA-BUF 是这个 buffer 的描述和使用框架。框架提供了对 dma-buffer 的描述结构体和使用接口。
利用 DMA-BUF 可以完成不同进程之间的 buffer 共享。
https://www.kernel.org/doc/html/latest/driver-api/dma-buf.html
进程间纹理共享:服务端创建纹理共享给客户端
https://blaztinn.gitlab.io/post/dmabuf-texture-sharing/
https://gitlab.freedesktop.org/mesa/demos/-/commit/03ede3f56612b999e404c8752c9135059551e11b
在 DMA-BUF 框架中有两个很重要的概念,一个是exporter,另一个是importer。
DMA buffer 本身由 DMA-BUF exporter 创建,DMA-BUF exporter 是一个驱动程序,它可以分配特定类型的内存, 相当于一个buffer的生产者或者说是提供者。
DMA-BUF importer则对应dma buffer的使用者,比如上层应用,而因为dma buffer是一种共享内存,所以同一个buffer的importer可以有多个。
DRI3 实现中,应用端是exporter, Xorg是Importer
https://blog.csdn.net/hexiaolong2009/article/details/102596744