Linux图形显示系统之DRM
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux图形显⽰系统之DRM
最近在研究Linux下的显卡驱动,先从图形显⽰系统着⼿学习,搬运翻译了wiki词条。
⼀、Overview
Direct Rendering Manager(DRM)是linux内核⼦系统,负责与显卡交互。
DRM提供⼀组API,⽤户空间程序可以使⽤该API将命令和数据发送到GPU并执⾏诸如配置显⽰器的模式设置之类的操作。
DRM最初是作为X server Direct Rendering基础结构的内核空间组件开发的,但从那以后它被其他图形系统(例如Wayland)所使⽤。
⽤户空间程序可以使⽤DRM API命令GPU执⾏硬件加速的3D渲染和视频解码以及GPU计算。
Linux内核已经有⼀个fbdev的API,⽤于管理图形适配器的帧缓存区,但不能⽤于满⾜基于3D加速的现代基于GPU的视频硬件的需求。
这些设备通常需要在⾃⼰的内存中设置和管理命令队列,以将命令分派给GPU,并且还需要管理该内存中的缓冲区和可⽤空间。
最初,⽤户空间程序(例如X server)直接管理这些资源,但通常它们的⾏为就像它们是唯⼀可以访问GPU的程序⼀样。
当两个或多个程序试图同时控制相同的硬件,并以⾃⼰的⽅式设置每个资源时,⼤多数情况下,它们都是灾难性。
DRM的创建是为了允许多个程序同时使⽤视频硬件资源。
DRM获得对GPU的独占访问权,并负责初始化和维护命令队列、内存和任何其他资源。
希望使⽤GPU的程序将请求发送到DRM,DRM充当仲裁程序,并注意规避可能的冲突。
多年来,DRM的范围已得到扩展,以涵盖以前由⽤户空间程序处理的多重功能,例如framebuffer管理和模式设置,内存共享对象和内存同步。
这些扩展中的某些被赋予了特定的名称,例如图形执⾏管理器(GEM)或内核模式设置(KMS),并且当特别提及它们提供的功能时,该术语将占上风,但它们仍然属于整个内核DRM⼦系统的⼀部分。
⼆、Software architecture
DRM驻留在内核空间中,因此⽤户空间程序必须使⽤内核系统调⽤来请求其服务。
但是DRM没有定义⾃⼰的⾃定义调⽤。
相反,它遵循Unix原则“⼀切皆⽂件”,使⽤/dev层次结构下的设备⽂件通过⽂件系统名称空间公开GPU。
DRM检测到的每个GPU都称为DRM设备,并创建了⼀个设备⽂件/dev/dri/cardX(X是⼀个序列号)与之连接,并使⽤ioctl调⽤与DRM进⾏通信。
不同的ioctl对应于DRM API的不同功能。
创建了⼀个名为libdrm的库,以⽅便⽤户空间程序与DRM⼦系统的接⼝。
该库只是⼀个包装器,它为DRM API的每个ioctl提供⽤C编写的函数,以及常量、结构和其他辅助元素。
使⽤libdrm不仅避免将内核接⼝直接暴露给应⽤程序,⽽且还提供了在程序之间重⽤和共享代码的优点。
DRM由两部分组成:通⽤“DRM core”和每种受⽀持的特定部分(“DRM Driver”)。
DRM core提供了可以注册不同DRM驱动程序的基本框架,还为⽤户空间提供了具有通⽤的,独⽴于硬件的,功能的最少ioctl集。
另⼀⽅⾯,DRM Driver实现API的硬件相关部分,具体取决于它所⽀持的GPU类型,它应提供DRM核⼼未涵盖的其余ioctl的实现。
DRM驱动也可以扩展API,提供特定GPU上可⽤的具有附加功能的附加ioctl。
当特定的DRM驱动程序提供增强的API时,⽤户空间libdrm也将通过⼀个额外的库libdrm-driver扩展,这个扩展库可以被⽤户空间⽤来调⽤其他ioctl接⼝。
2.1 API
DRM Core将⼏个接⼝导出到⽤户空间应⽤程序,让相应的libdrm包装成函数后来使⽤。
DRM Driver通过ioctl和sysfs⽂件导出设备专⽤的接⼝,供⽤户空间驱动程序和⽀持设备的应⽤程序使⽤。
外部接⼝包括:内存映射,上下⽂管理,DMA操作,AGP管
理,vblank控制,fence管理,内存管理和输出管理。
2.2 DRM-Master 和 DRM-Auth
DRM API 中有⼏个 ioctl 由于并发问题仅限于⽤户空间单个进程使⽤。
为了实现这种限制,将 DRM 设备分为 Master 和 Auth。
上述的那些 ioctl 只能被 DRM-Master 的进程调⽤。
打开了 /dev/dri/cardX 的进程的⽂件句柄会被标志为 master,特别是第⼀个调⽤该 SET_MASTER ioctl 的进程。
如果不是 DRM-Master 的进程在使⽤这些限制 ioctl 的时候会返回错误。
进程也可以通过 DROP_MASTER ioctl 放弃 Master ⾓⾊,来让其他进程变成 Master。
X Server 或者其他的 Display Server 通常会是他们所管理的 DRM 设备的 DRM-Master 进程。
当 DRM 设备启动的时候,这些 Display Server 打开设备节点,获取 DRM-Master 权限,直到关闭设备。
对于其他的⽤户空间进程,还有⼀种办法可以获得 DRM 设备的这些受限权限,这就是 DRM-Auth。
它是⼀种针对 DRM 设备的验证⽅式,⽤来证明该进程已经获得了 DRM-Master 对于他们去访问受限 ioctls 的许可。
步骤:
l DRM Client 使⽤ GET_MAGIC ioctl 从 DRM 设备获取⼀个 32bit 整型的 token。
并通过任何⽅式(通常是 IPC)传递给 DRM-Master。
l DRM-Master 进程使⽤ AUTH-MAGIC ioctl 返回 token 给 DRM 设备。
l 设备将 DRM-Master 所给的 token 和 Auth 的进⾏对⽐。
通过的话就赋予进程⽂件句柄特殊的权限。
2.3 GEM
Graphics Execution Manager(GEM)是⼀种内存管理⽅法。
由于视频存储器的⼤⼩增加以及诸如OpenGL之类的图形API的⽇益复杂性,从性能⾓度看,在每个上下⽂切换处重新初始化图形卡状态的策略过于低效。
另外,现代linux桌⾯还需要⼀种最佳⽅式与合成管理器(compositing manager)共享屏幕外缓冲区。
这些要求诞⽣开发了⽤于管理内核内部图形缓冲区的新⽅法,图形执⾏管理⽅法(GEM)是其中⼀种。
GEM为API提供了显式的内存管理原语。
通过GEM,⽤户空间程序可以创建,处理和销魂GPU视频内存中的内存对象(Bo)。
从⽤户空间程序的⾓度看,这些被称为“GEM对象”的对象是持久性的,不需要在程序每次重新获得对GPU的控制时对重新加载它们。
当⽤户空间程序需要⼤量的视频内存(以存储framebuffer,纹理或者GPU所需的任何其他数据)时,它将使⽤GEM API请求分配给DRM驱动程序。
DRM驱动程序会跟踪已使⽤的视频内存,如果有可⽤的空闲内存,则能够满⾜请求,将“句柄”返回给⽤户空间,以在以后的操作中进⼀步引⽤分配的内存。
GEM API还提供了⼀些操作,以填充缓冲区并在不再需要时释放缓冲区。
当⽤户空间进程有意或由于终⽌⽽关闭了DRM设备⽂件描述符时,未释放的GEM句柄中的内存将恢复。
GEM还允许使⽤同⼀DRM设备(因此使⽤相同的DRM驱动程序)的两个或多个⽤户空间进程共享GEM对象。
GEM句柄时是某个进程唯⼀的局部32位整数,但在其他进程中可重复,因此不适合共享。
所需要的是⼀个全局命名空间,GEM通过使⽤称为GEM names的全局句柄来提供⼀个命名空间。
GEM名称是指使⽤相同的DRM驱动程序在同⼀个DRM 设备中通过使⽤唯⼀的32位整数创建的⼀个GEM对象,并且仅是⼀个GEM对象。
GEM提供了⼀个操作flink来从GEM句柄获取GEM名称。
然后,该进程可以使⽤任何可⽤的IPC 机制将该GEM名称(32位整数)传递给⼀个进程。
接收⽅进程可以通过GEM名称来获取原始GEM对象的本地GEM句柄。
不幸的是,使⽤GEM名称共享缓冲区并不安全。
⼀个恶意的第三⽅进程访问同⼀DRM设备可以会试图通过探查32位整数来猜测其他两个进程共享的缓冲区的GEM名称。
⼀旦找到GEM名称,就可以访问和修改其内容,从⽽违反了缓冲区信息的机密性和完整性。
后来通过在DRM中引⼊了DMA-BUF⽀持来克服此缺点,因为DMA-BUF将⽤户空间中的缓冲区表⽰为⽂件描述符,可以安全的共享它们。
除了管理视频内存空间外,任何视频内存管理系统的另⼀个重要任务是处理GPU和CPU之间的内存同步。
当前的存储器架构⾮常复杂,并且通常涉及⽤于系统存储器以及有时也⽤于视频存储器的各种级别的⾼速缓存。
因此,视频内存管理器还应处理缓存⼀致性,以确保CPU和GPU之间共享的数据⼀致。
这意味着视频内存管理内部结构通常⾼度依赖于GPU和存储体系结构的硬件细节,因此取决于驱动程序。
GEM最初是由英特尔⼯程师开发的,旨在为其i915驱动程序提供视频存储管理器。
英特尔GMA 9xx家族是具有统⼀内存架构(UMA)的集成GPU,其中GPU和CPU共享物理内存,并且没有专⽤的VRAM。
GEM定义了⽤于内存同步的“内存域”,尽管这些内存域与GPU⽆关,但它们在设计时特别考虑了UMA内存架构,这使其不适⽤与其他内存架构,例如具有单独VRAM的内存架构。
因此,其他的DRM驱动程序已决定向⽤户空间程序公开GEM API,但在内部它们实现了更适合其特定硬件和内存体系结构的其他内存管理器。
GEM API还提供了⽤于控制执⾏流(命令缓冲区)的ioctl,但它们是Intel特定的,可与Intel i915和更⾼版本的GPU⼀起使⽤。
除了特定于内存管理的ioctl,没有DRM驱动程序试图去实现GEM API的其他任何部分。
2.4 Translation Table Maps
Translation Table Maps(TTM)是在GEM之前开发的⽤于GPU的通⽤内存管理器名称。
它专门⽤于管理GPU可能访问的不同类型的内存,包括专⽤的Video RAM(通常安装在显卡中)与可通过称为Graphics Address Remapping Table(GART)的I/O内存管理单元访问的系统内存。
考虑到⽤户空间图形应⽤程序通常会处理⼤量视频数据,TTM还应处理CPU⽆法直接寻址的Video RAM部分,并以最佳性能来实现。
另⼀个重要的事情是保持所涉及的不同内存和缓存之间的⼀致性。
TTM的主要概念是“缓冲对象”,即在某些时刻GPU是可寻址的视频内存。
当⽤户空间图形应⽤程序想要访问某个缓冲对象(通常是⽤内容填充它)时,TTM可能需要将其重新定位为CPU可以寻址的⼀种存储器。
当GPU需要访问的缓冲区对象还不在GPU的地址空间中时,可能会发⽣进⼀步的重定位或GART映射操作。
这些重定位操作中的每⼀个都必须处理任何相关的数据和缓存⼀致性问题。
TTM的另⼀个重要概念是围栏(fences)。
围栏本质上是⼀种管理CPU和GPU之间并发性的机制。
围栏跟踪GPU何时不再使⽤缓冲区对象,通常⽤于通知任何具有访问权限的⽤户空间进程。
TTM试图以合适的⽅式管理所有类型的内存体系结构,包括有和没有专⽤VRAM的体系结构,并在内存管理器中提供所有可想到的功能,以便与任何类型的硬件⼀起使⽤,这导致了过于复杂的情况。
API远远超出所需的解决⽅案。
⼀些DRM开发⼈员认为它不适⽤于任何特定的驱动程序,尤其是API。
当GEM成为⼀种更简单的内存管理器时,它的API优于TTM。
但是⼀些驱动程序开发⼈员认为TTM所采⽤的⽅法更适合于具有专⽤Video RAM和IOMMU的分⽴显卡,因此他们决定在内部使⽤TTM,同时将其缓冲区对象公开为GEM对象,从⽽⽀持GEM API。
当前使⽤TTM作为内部内存管理器但提供GEM API的驱动程序实例包括AMD显卡的radeon驱动程序和NVIDIA显卡的nouveau驱动程序。
2.5 DMA Buffer Sharing and PRIME
DMA缓冲区共享API(通常缩写为DMA-BUF)是⼀种Linux内核内部API,旨在提供⼀种通⽤机制来在多个设备之间共享DMA缓冲区,并可能由不同类型的设备驱动进⾏管理。
例如,Vdieo4Linux设备和图形适配器设备可以通过DMA-BUF共享缓冲区,以实现前者产⽣并由后者消耗的视频流数据的零复制。
任何Linux设备驱动程序都可以将此API实现为导出器、⽤户(消费者)或者⼆者兼⽽有之。
在DRM中⾸次利⽤此功能来实现PRIME(擎天柱,显卡交⽕),这是⼀种⽤于GPU卸载的的解决⽅案,它使⽤DMA-BUF在独⽴显卡和集成显卡的DRM驱动程序之间共享⽣成的framebuffer。
DMA-BUF的⼀项重要功能是为了将共享缓冲区作为⽂件描述符提供给⽤户空间。
为了开发PRIME,在DRM API中添加了两个新的ioctl,⼀个将本地GEM句柄转换为DMA-BUF⽂件描述符,另⼀个⽤于相反的操作。
后来这两个新的ioctl被⽤作解决GEM缓冲区共享固有的不安全性的⼀种⽅法。
与GEM名称不同,⽆法猜测到⽂件描述符(它们不是全局命名空间),并且Unix操作系统提供了⼀种安全的⽅法来传递Unix域套接字,通过使⽤SCM_RIGHTS语义。
⼀个想要与另⼀个进程共享GEM对象的进程可以将本地GEM句柄转换为DMA-BUF⽂件描述符,然后将其传递给接收者,后者可以从接收的⽂件描述符中获得⾃⼰的GEM句柄。
DRI3使⽤这种⽅法在客户端和X Server或者Wayland之间共享缓冲区。
2.6 Kernel Mode Setting
为了正常⼯作,显卡或者图形适配器必须设置⼀种模式(屏幕分辨率、颜⾊深度和刷新率的组合),该模式应在其⾃⾝和所连接的显⽰屏所⽀持的值的范围内。
此操作称为mode-setting。
通常需要对图形硬件进⾏原始访问,写⼊视频卡某些寄存器的能⼒。
在开始使⽤framebuffer之前,以及在应⽤程序或者⽤户要求更改模式时,都必须执⾏模式设置操作。
在早期,希望使⽤图形framebuffer的⽤户空间程序还负责提供模式设置操作,因此它们需要在对视频硬件进⾏特权访问的情况下运⾏。
在Unix类型的操作系统中,X Server是最突出的⽰例,其模式设置实现存在于每种特定类型的显卡的DDX驱动程序中。
这种⽅法(以后称为⽤户空间模式设置或UMS)带来了⼏个问题。
这不仅打破了操作系统应在程序和硬件之间提供的隔离性,从⽽提⾼稳定性和安全性,⽽如果两个或多个⽤户空间程序尝试在操作系统上进⾏模式设置,可能会使图形硬件处于不⼀致的状态。
同时,为了避免这种冲突,实际上X Server成为了唯⼀执⾏模式设置操作的⽤户空间程序。
其余的⽤户空间程序依靠X Server来设置适当的模式并处理涉及模式设置的任何其他操作。
最初,模式设置仅在X Server启动过程中执⾏,但是后来X Server可以在运⾏时进⾏设置。
XFree86 3.1.2中引⼊了XFree-VidModeExtension扩展,以允许X-Client请求对X Server的
modeline(分辨率)更改。
VidModeExtension后来被更加通⽤的XRandR扩展取代。
然⽽,这不是在linux系统中进⾏模式设置的唯⼀代码。
在系统引导过程中,Linux内核必须为虚拟控制台设置最⼩⽂本模式(基于VESA BIOS扩展定义的标准模式)。
Linux内核帧缓冲驱动程序还包含⽤于配置帧缓冲设备的模式代码。
为了避免模式设置冲突,XFree86 Server(以及后来的 Server)在⽤户从图形环境切换到⽂本虚拟控制台时保存模式设置状态,并在切回到X图形环境时还原它。
此过程在过渡中引发了闪烁现象,并且还可能失败,从⽽导致输出显⽰损坏或⽆法使⽤。
⽤户空间模式设置⽅法还引起了其他问题:
Ø 挂起/恢复过程必须依靠⽤户空间⼯具来恢复以前的模式。
由于模式集配置错误,这些程序之⼀的单个故障或崩溃可能会使系统⽆法正常显⽰,因此⽆法使⽤。
Ø 当屏幕处于图形模式时(例如运⾏X),内核也不可能显⽰错误或调试信息,因为内核知道的唯⼀模式是VESA_BIOS标准⽂本模式。
Ø 更为紧迫的问题是绕过X Server的图形应⽤程序的激增以及X的其他图形栈替代⽅案的出现,从⽽进⼀步扩展了模式设置代码在整个系统中的重复。
为了解决这些问题,将模式设置代码移⾄内核中的单个位置,放到了现有的DRM模块中。
然后每个进程(包括X Server)都应该能够命令内核执⾏模式设置操作,并且内核将确保并发操作不会导致不⼀致的状态。
添加到DRM模块以执⾏这些模式设置操作的新内核API和代码称为Kernel Mode-Setting(KMS)。
Kernel Mode-Setting(KMS)有⼏个好处。
最直接是从内核(Linux控制台,fbdev)和⽤户空间(X Server DDX驱动程序)中删除重复的模式设置代码。
KMS还使编写替代图形系统变得更加容易,⽽这些图形系统现在不需要实现⾃⼰的模式设置代码。
通过提供集中的模式管理,KMS解决了在控制台和X之间以及X的不同实例之间切换引起的闪屏问题。
由于它在内核中可⽤,因此也可以在引导过程开始时使⽤它,从⽽避免了由于这些早期阶段的模式更改⽽导致的闪烁。
Kernel Mode-Setting(KMS)是内核的⼀部分,这⼀事实使KMS可以使⽤仅在内核空间可⽤的资源(例如中断)。
例如,挂起/恢复过程后的模式恢复通过由内核本⾝进⾏管理,⼤⼤简化了操作,并附带地提⾼了安全性(不再需要具有root权限的⽤户空间⼯具)。
内核还可以轻松地热拔插新的显⽰设备,从⽽解决了⼀个长期存在的问题。
模式设置也与内存管理密切相关,因为framebuffer基本上是内存缓冲区,因此强烈建议与图形内存管理器紧密集成。
这就是为什么将内核模式设置代码合并到DRM中⽽不是作为⼀个单独的⼦系统的主要原因。
为避免破坏DRM API的向后兼容性,内核模式设置作为某些DRM驱动程序的附件驱动程序功能提供。
任何DRM驱动程序在向DRM内核注册时都可以选择提供
DRIVER_MODESET标志,以指⽰它⽀持KMS API。
那些实现内核模式设置的驱动程序通常被称为KMS驱动程序,以将它们与传统的(⽆KMS)DRM驱动。
KMS驱动已经被接受适配到了这种程度,某些缺少3D加速(或者硬件供应商不希望公开或者实现它)的驱动程序在没有DRM其余API的情况下实现了KMS API。
2.7 KMS device model
KMS将输出设备建模和管理为⼀系列抽象硬件模块,这些模块通常分布在显⽰控制器的显⽰输出管道上。
这些模块是:
Ø CRTC:每个CRTC(来⾃CRT控制器)代表显⽰控制器的扫描引擎,指向扫描缓冲区(framebuffer)。
CRTC的⽬的是读取当前在扫描缓冲区中的像素数据,并借助PLL电路从中⽣成视频模式时序信号。
可⽤的CRTC的数量决定了硬件可以同时处理多少个独⽴的输出设备,因此,要使⽤屏配置,每个显⽰设备⾄少需要⼀个独⽴的CRTC。
两个或更多个CRTC也可以⼯作在克隆模式下,它们从相同的framebuffer中扫描出来,将相同的图像数据发送到多个输出设备。
Ø Connector:连接器代表显⽰控制器从扫描输出中发送视频信号到显⽰的操作。
通常,KMS连接器的概念对应于输出设备(显⽰器,笔记本电脑⾯板等)硬件中的物理连接器(VGA,DVI,FPD-Link,HDMI,DisplayPort,S-Video等),它是永久的,也可以是临时的。
与当前物理连接的输出设备有关的信息(例如连接状态,EDID数据,DPMS状态或受⽀持的视频模式)也存储在连接器内。
Ø Encoder:显⽰控制器必须对来⾃于CRTC视频模式数据编码为适合的符合预期的连接器的格式,以适配连接器。
编码器代表能够执⾏这些编码之⼀的硬件模块。
⽤于数字输出的编码⽰例为TMDS和LVDS;对于VGA和TV输出等模拟输出,通常使⽤特定的DAC模块。
⼀个连接器⼀次只能接受⼀个编码器的信号,并且每种类型的连接器仅⽀持某些编码。
可能还会存在其他物理限制,即并⾮每个CRTC都连接到每个可⽤的编码器,从⽽限制了CRTC-encoder-connector的可能组合。
Ø Plane:Plane不是硬件块,⽽是⼀个包含向CRTC发送数据的缓存块的内存对象。
拥有framebuffer的Plane称为主平⾯(primary plane),每个CRTC必须关联⼀个平⾯,因为它是CRTC决定采⽤哪种视频模式的根据—显⽰分辨率(宽度和⾼度),像素⼤⼩,像素格式,刷新率等。
如果显⽰控制器⽀持硬件光标覆盖,则CRTC可能还与光标平⾯相关联;如果显⽰控制器能够从其他硬件覆盖中扫描,并“即使”合成或混合发送到输出设备的最终图像,则CRTC可能与之关联。
2.8 Atomic Display
近年来,⼈们⼀直在努⼒使与KMS API有关的某些常规操作具有原⼦性,尤其是与模式设置和页⾯翻转操作有关。
这种增强的KMS API就是所谓的“原⼦显⽰”(以前称为“原⼦模式设置”和“原⼦或原⼦页⾯翻转”)。
原⼦模式设置的⽬的是通过避免可能导致视频状态不⼀致或⽆效的中间步骤,确保在具有多个限制的复杂配置中正确更改模式;在必须撤消失败的模式设置过程(“回滚”)时,它还避免了危险的视频状态。
原⼦模式设置通过提供模式测试功能,可以事先知道某些特定的模式配置是否合适。
当测试原⼦模式并确认其有效性时,可以通过单个不可分割的(原⼦)提交操作来应⽤它。
测试和提交操作均由具有不同标志的同⼀新ioctl提供。
另⼀⽅⾯,原⼦页⾯翻转允许在同⼀输出上更新多个平⾯(例如主平⾯,光标平⾯以及可能的某些叠加或辅助平⾯),这些平⾯均在同⼀VBLANK间隔内同步,从⽽确保正确的显⽰⽽不会撕裂。
这项要求特别适⽤于移动和嵌⼊式显⽰控制器,它们倾向于使⽤多个平⾯/叠层以节省功耗。
新的原⼦API是在旧的KMS API的基础上构建的。
它使⽤相同的模型和对象(CRTC,Encoder,Connector,Plane等),但是可以修改的对象属性越来越多。
原⼦过程基于更改相关属性以构建我们要测试或提交的状态。
我们要修改的属性取决于我们是否要进⾏模式设置(主要是CRTC,编码器和连接器属性)或页⾯翻转(通常是平⾯属性)。
这两种情况的ioctl相同,不同之处在于每次传递的属性列表。
2.9 Render nodes
在原始DRM API中,DRM设备“/dev/dri/cardX”⽤于特权(模式设置,其他显⽰控件)和⾮特权(渲染,GPGPU计算)操作。
出于安全原因,打开关联的DRM设备⽂件需要“等同于root特权”的特殊特权。
这导致了⼀种体系结构,其中只有⼀些可靠的⽤户空间程序(X服务器,图形合成器等)可以完全访问DRM API,包括特权部分(如模式集API)。
想要渲染或进⾏GPGPU计算的其余⽤户空间应⽤程序应由DRM设备的所有者(“DRM主设备”)通过使⽤特殊的⾝份验证界⾯来授予。
然后,经过⾝份验证的应⽤程序可以使⽤DRM API的受限版本来呈现或进⾏计算,⽽⽆需特权操作。
这种设计施加了严格的约束:必须始终有运⾏中的图形服务器(X服务器,Wayland合成器,...)充当DRM设备的DRM主设备,以便可以授予其他⽤户空间程序使⽤DRM设备的权限,即使在不涉及任何图形显⽰(如GPGPU计算)的情况下。
“渲染节点(Render nodes)”概念试图通过将DRM⽤户空间API分成两个接⼝(⼀个特权和⼀个⾮特权)并为每个接⼝使⽤单独的设备⽂件(或“节点”)来解决这些情况。
对于找到的每个GPU,其对应的DRM驱动程序(如果它⽀持渲染节点功能)除了主节点/dev /dri/cardX之外,还会创建⼀个设备⽂件/dev/dri/renderDX,称为渲染节点。
使⽤直接渲染模型的客户端和想要利⽤GPU的计算功能的应⽤程序可以通过简单地打开任何现有的渲染节点并使⽤DRM API⽀持的有限⼦集来分派GPU操作,⽽⽆需其他特权即可做到这⼀点--前提是它们具有打开设备⽂件的⽂件系统权限。
显⽰服务器,合成器和任何其他请求模式API或任何其他特权操作的程序,都必须打开授予对完整DRM API的访问权限的标准主节点,并像往常⼀样使⽤它。
渲染节点显式禁⽌GEM flink操作,以防⽌使⽤不安全的GEM全局名称共享缓冲区。
只能通过使⽤PRIME(DMA-BUF)⽂件描述符的⽅式,与包括图形服务器在内的另⼀个客户端共享缓冲区。
三、 Hardware support
如上图所⽰,DRM将由⽤户模式图形设备程序使⽤,例如Mesa 3D。
⽤户空间程序使⽤Linux系统调⽤访问DRM,DRM通过⾃⾝的系统调⽤来响应Linux的系统调⽤。
四、 Development
Direct Rendering Manager是在Linux内核中开发的,其源代码位于Linux源代码的/ drivers/gpu/drm⽬录中。
⼦系统维护者是Dave Airlie,其他维护者则负责特定的驱动程序。
与Linux内核开发⼀样,DRM⼦维护者和贡献者将具有新功能和错误修复的补丁程序发送给主要DRM维护者,后者将它们集成到⾃⼰的Linux存储库中。
DRM维护者依次将所有这些修补程序提交给Linus Torvalds,这些修补程序随时准备发布到Linux新版本中。
作为整个内核的顶级维护者,Torvalds保留了有关补丁是否适合包含在内核中的最后决定。
由于历史原因,libdrm库的源代码保留在Mesa项⽬之下。