Linux图形显示系统之Mesa
2021-04-04 22:15:53 阿炯

Mesa,也称为Mesa3D和Mesa 3D图形库,是OpenGL,Vulkan和其他图形API规范的开源软件实现。其根据规范转换特定供应商的图形硬件驱动程序。

它最重要的用户是两个图形驱动程序,这些图形驱动程序主要由Intel和AMD为各自的硬件开发和资助(AMD在不推荐使用的AMD Catalyst上推广了Mesa驱动程序Radeon和RadeonSI,而Intel仅支持Mesa驱动程序)。专有的图形驱动程序(例如Nvidia GeForce驱动程序和Catalyst)取代了所有的Mesa,提供了自己的图形API实现。社区主要开发用于编写Mesa Nvidia驱动程序Nouveau的开源程序。除了游戏等3D应用程序外,现代显示服务器(X.org的Glamor或Wayland的Weston)还使用OpenGL/EGL;因此,所有图形通常都通过Mesa认证。

Mesa由freedesktop.org维护,最初由仍活跃于该项目的Brian Paul于1993年8月发起。其随后被广泛采用,现在包含来自世界各地的各个个人和公司的众多贡献,包括管理OpenGL规范的Khronos Group的图形硬件制造商的贡献。对于Linux,开发工作也部分由众筹推动。

一、 Overview

图1.1 Linux kernel and OpenGL video games

3D计算机游戏通过OpenGL将渲染计算任务实时派发给GPU。着色器使用OpenGL着色语言或者SPIR-V编写,并在CPU上进行编译。编译后的程序在GPU上执行。


图1-2 The Linux Graphics Stack and glamor


图1-2 Linux图形栈图示:DRM和libDRM,Mesa 3D。Display server属于窗口系统,不是必需的,例如对于游戏。


图1-3 Linux Graphics Stack 2013-1


图1-3 Wayland的自由实现依赖于EGLDE Mase实现。EGL1.5版本应用废弃了称为libWayland-EGL的特殊库,该库旨在容纳对帧缓冲区的访问。在2014年的GDC上,AMD正在探索改变策略,以使用DRM而非内核内的Blob

Mesa被称为图形API的执行外壳。 从历史上看,Mesa实现的主要API是OpenGL,以及其他与Khronos Group相关的规范(例如OpenVG,OpenGL ES或最近的EGL)。但是Mesa可以实现其他API,实际上自2013年7月起,它就已使用Glide(不推荐使用)和Direct3D 9进行了处理。Mesa也不特定于类Unix操作系统:例如,在Windows上,Mesa在DirectX上提供了OpenGL API。

Mesa在图形API(例如OpenGL)和操作系统内核的图形硬件驱动程序之间实现了转换层。 不同图形API的受支持版本取决于驱动程序,因为每个硬件驱动程序都有其自己的实现(因此也具有状态)。 对于“经典”驱动程序尤其如此,而Gallium3D驱动程序共享通用代码,这些代码倾向于使受支持的扩展和版本同质化。

Mesa维护了一个支持矩阵,该矩阵具有在mesamatrix.net上可视化的当前OpenGL符合性的状态。 Mesa 10符合OpenGL 3.3,适用于Intel,AMD / ATI和Nvidia GPU硬件。 Mesa 11被宣称某些驱动程序符合OpenGL 4.1。

Mesa 12包含OpenGL 4.2和4.3以及Intel Vulkan 1.0支持。

Mesa 13带来了Intel对OpenGL 4.4和4.5的支持(所有功能都支持Intel Gen 8 +,Radeon GCN,Nvidia(Fermi,Kepler),但没有针对4.5标签的Khronos-Test)和通过社区驱动程序RADV提供的实验性AMD Vulkan 1.0支持。 借助Intel Skylake(Gen9),可以实现OpenGL ES 3.2。

2017年的第一个稳定版本是17.0(新年计数)。 就绪功能已通过OpenGL 4.5认证,适用于Intel Haswell的OpenGL 4.5,适用于NVidia Maxwell和Pascal(GM107 +)的OpenGL 4.3。 使用Maxwell 1(GeForce GTX 750 Ti以及使用GM1xx进行的测量)可测量出巨大的性能提升。 Maxwell-2-Card(GeForce GTX 980以及带有GM2xx的显卡)在没有NVidia信息的情况下进行了超频。

适用于OpenGL 4.4、4.5和OpenGL ES 3.0+的Khronos CTS测试套件现已发布(2017-01-24)开放源代码,现在可以免费进行Mesa 13和17的所有测试。

2017年的第二个稳定版本17.1.0于2017年5月10日发布,进行了一些有趣的改进。 亮点2是用于Intel Ivy Bridge的OpenGL 4.2+和用于Intel Open SWR Rasterizer的OpenGL 3.3+。

请注意,由于OpenGL的模块化性质,Mesa实际上可以支持来自OpenGL较新版本的扩展,而无需声明完全支持此类版本。 例如,在2016年7月,Mesa支持OpenGL ES 3.1,但还支持除五个以外的所有OpenGL ES 3.2扩展,以及一些不属于任何OpenGL或OpenGL ES版本的扩展。

对于Mesa和Linux,一个悬而未决的问题是高动态范围(HDR)。 尚有许多问题和未解决的问题,需要进行干净而基本的实施。

第三版17.2自2017年9月起可用,具有一些新的OpenGL 4.6功能以及3D在Intel和AMD方面的速度改进。 在Nouveau for Kepler中,只有1.4%的测试针对OpenGL 4.5失败。

2018年的第一个版本是18.0,自2018年3月起,可以在2017年以相同的方案在2017年使用。尚未完全提供对OpenGL 4.6的支持,但是许多功能和改进功能已在RC3中成功进行了测试。 色彩中对Intel i965的10位支持也是一个亮点。 新功能是使用实际的Linux版本支持Intel Cannon Lake和AMD Vega。 AMD Evergreen芯片(RV800或R900)接近OpenGL 4.5支持。 旧的AMD R600或RV700芯片只能支持具有OpenGL 4.x某些功能的OpenGL 3.3。 Freedreno是Adreno硬件的驱动程序,接近OpenGL 3.3支持。

2018年的第二个版本是18.1,自5月开始可用。 目标是Intel ANV和AMD RADV驱动程序中的Vulkan 1.1.72。 带有spir-V的OpenGL 4.6也是主要目标。永久工作可能会完成旧硬件的功能和驱动程序优化,例如AMD R600 / Evergreen,Nvidia Tesla以及之前,Fermi,Kepler或Intel Sandybridge,Ivybridge,Haswell或Broadwell。 ARM体系结构在主要目标OpenGL ES的Adreno 3xx / 4xx / 5xx和用于Raspi的Broadwell VC4 / VC5中也进行了重大改进。

2018年的第三版为18.2,可在9月稳定的日历中使用。 WIP中带有spir-V的OpenGL 4.6和Vulkan 1.1.80。 虚拟机VIRGL的软驱动程序已准备好用于OpenGL 4.3和OpenGL ES 3.2。 RadeonSI也已准备好用于OpenGL ES 3.2。RadeonSI for AMD GCN卡的其他亮点还包括对OpenGL 4.4(在18.1中为3.1)的ASTC纹理压缩支持和兼容性模式支持。 新的Vulkan 1.1以及适用于Intel和AMD的更多功能可用。 可以通过Mesamatrix查看Vulkan的更多详细信息。

2018年的第四版为18.3,并于2018年12月作为稳定的版本18.3.1发行。详细信息的许多功能和对较新硬件的支持是主要部分。尚未完全支持OpenGL 4.6。

2019年的第一个版本是19.0,现已于3月发布。还没有完全支持OpenGL 4.6,但是所有驱动程序中都以这种方式进行了许多改进。

2019年的第二个版本是19.1。TGSI向NIR的过渡是通过Spir-V和更多OpenCL向OpenGL 4.6过渡的一项主要功能。RadeonSI在带有NIR的dev-Version中运行良好。

2019年的第三版是19.2。OpenGL 4.6已为Beta版准备好了新的Intel Iris驱动程序。

2019年的第四版是19.3。OpenGL 4.6已为Intel i965准备就绪,并为新的Iris驱动程序提供了可选功能。

2020年的第一个版本是20.0。Vulkan 1.2已准备好用于AMD RADV和Intel ANV。 英特尔Broadwell Gen 8+默认使用英特尔虹膜。 RadeonSI驱动程序默认切换为使用NIR,而不是TGSI。

2020年的第二版是20.1。许多驱动程序已准备好许多改进。 Zink是基于Vulkan的OpenGL的新虚拟驱动程序。

2020年的第三版是20.2。OpenGL 3.0 for Zink是一项新功能。 LLVMpipe将支持OpenGL 4.3+(在20.3中为4.5+)。 大多数模块都对ARM Panfrost进行了改进。 在Pascal及更高版本的Nouveau中,OpenCL可以共享虚拟内存。

2020年的第四版是20.3。v3d和v3dv是具有Broadcom硬件(如Raspberry Pi 4)的OpenGL和Vulkan 1.0的新驱动程序。三叶草模块完全支持OpenCL 1.2。 Zink支持OpenGL 3.3+。 LLVMpipe虚拟驱动程序现在支持OpenGL 4.5+(含4.6)。 作为LLVMpipe的Vulkan树的VALLIUM被合并。

在Mesa 21.0中,d3d12将与OpenGL 3.0合并为3.3。 Microsoft和Collabora在WSL2中使用Direct 3D 12向Windows 10开发了新的仿真d3d12。OpenCL 1.2也是d3d12中的目标。 带有改进的OpenGL代码的Benchmark SPECviewperf中,将因子2加速到5。 Mesa 21.0的许多功能可以提高性能。 新版本21.0.0自2021年3月11日起公开发布。

Mesa 21.1是2021年的第二个版本。OpenGL 4.6+可用于Zink。 AMD驱动程序600g可以更改为NIR,对于旧的Radeeon HD 5000和6000卡提供更多的可能性。

1.1 VulKan

Khronos集团于2015年3月正式宣布了Vulkan API,并于2016年2月16日正式发布了Vulkan1.0。Vulkan中断了与OpenGL的兼容性,并完全放弃了其单片状态机的概念。 Gallium3D的开发人员称Vulkan类似于Gallium3D 2.0 – Gallium3D将实现OpenGL状态机的代码和特定于硬件的代码分开。

当Gallium3D摄取TGSI时,Vulkan摄取SPIR-V(如“ Vulkan”中的标准便携式中间表示版本“ V”Standard Portable Intermediate Representation version "V" as in "Vulkan")。

英特尔在规范正式发布的当天就为其硬件发布了Vulkan驱动程序的实现,但该技术仅在4月上线,因此成为2016年7月发布的Mesa 12.0的一部分。尽管尚未按照Gallium3D规范编写i965驱动程序,但对于Vulkan驱动程序而言,将其固定在Gallium3D上的意义甚至更小。同样,没有技术原因可以将其与NIR结合使用,但是英特尔的员工却以这种方式实施了他们的Vulkan驱动程序。

可以预期的是,AMD自己专有的Vulkan驱动程序已于3月发布,并宣布将在未来以免费和开源软件的形式发布,并且将主要应用到Mesa,也将放弃Gallium3D。

RADV是AMD的免费项目,自版本13开始可用。符合Khronos-Test的版本为17.3。自Mesa 18.1起,实际是对Vulkan 1.0和1.1的完全支持。

英伟达在发布之日就发布了其专有的GeForce驱动程序,并获得了Vulkan的支持,Imagination Technologies(PowerVR),高通(Adreno)和ARM(Mali)所做的相同或至少宣布了适用于Android和其他操作系统的专有Vulkan驱动程序。 但是,何时以及是否还会出现针对这些GPU的其他免费和开源Vulkan实现,还有待观察。

Mesa软件驱动程序VIRGL于2018年通过GSOC项目启动Vulkan开发,以支持虚拟机。

1.2 Explicit fencing

一种将一个缓冲区与其余内存分开的内存屏障称为围栏(fance)。 围栏可以确保缓冲区在渲染和显示操作完成之前不会被覆盖。 隐式防护用于图形驱动程序和GPU硬件之间的同步。当一个组件不再使用缓冲区时,围栏会发出信号,以便可以在另一个组件上操作或重用它。 过去,Linux内核具有隐式的防护机制,其中将围栏直接附加到缓冲区(请参见GEM句柄和FD),但是用户空间对此并不了解。 显示围栏将围栏暴露给用户空间,其中用户空间从Direct Rendering Manager(DRM)子系统和GPU都获得围栏。Vulkan需要显式防护,并且在跟踪和调试方面具有优势。

Linux内核4.9在主线中添加了Android的同步框架。

1.3 Generic Buffer Management

Generic Buffer Management (GBM) 是一种API,它提供了一种机制,用于为绑定到Mesa的图形渲染分配缓冲区。 GBM旨在用作DRM或openwfd上EGL的本机平台。它创建的句柄可用于初始化EGL和创建渲染目标缓冲区。

Mesa GBM是图形驱动程序特定的缓冲区管理API(例如各种libdrm_*接口的库)的抽象,API通过调用Mesa GPU驱动程序在内部实现。

例如,Wayland合成器Weston(The Wayland compositor Weston)使用OpenGL ES 2进行渲染,并通过调用EGL对其进行初始化。由于Weston在“bare KMS Driver”上运行,因此它使用EGL DRM平台,因为它依赖于Mesa GBM接口,因此Weston可以真正称为GBM平台。

在XDC2014上,Nvidia员工Andy Ritger建议增强EGL以取代GBM。 社区对此没有积极的态度,Nvidia最终改变了主意,并采取了另一种方法。

1.4 Implementations of video acceleration APIs

这里有进行视频流的编码和解码所需计算的三种可能的方法:
Ø 使用视频压缩或解压缩算法的软件实现(通常称为CODEC)并在CPU上执行此软件;

Ø 使用视频压缩或解压缩算法的软件实现(通常称为CODEC),并在GPU(3D渲染引擎)上执行此软件;

Ø 使用视频压缩或解压缩算法的完整(或部分)硬件实现; 将此类ASIC集成到GPU / CPU / APU / SoC的芯片中已变得非常普遍,因此可以大量使用。 出于营销原因,公司已经为其ASIC建立了品牌,例如PureVideo(Nvidia),Unified Video Decoder(AMD),Video Coding Engine(AMD),Quick Sync Video(Intel),DaVinci(Texas Instruments),CedarX(Allwinner),Crystal HD(Broadcom);一些ASIC可作为半导体知识产权核心获得许可;通常,不同的版本会实现不同的视频压缩和(或者)视频解压缩算法; 对此类ASIC的支持通常属于内核驱动程序,以初始化硬件并做底层工作。 在用户空间中运行的Mesa包含几种用于软件的API的实现,例如 VLC媒体播放器,GStreamer,HandBrake等可以方便地访问此类ASIC:

l 视频加速API(VAAPI)–最常见的Linux API,由AMD和Intel使用;

l Unix视频解码和演示API(VDPAU)–Nvidia使用;

l DirectX视频加速(DXVA)–只有Microsoft Windows使用;

l OpenMAX IL –由Khronos Group设计用于视频压缩;

l 分布式编解码器引擎(DCE)–由德州仪器(TI)设计;

l X-Video比特流加速(XvBA)– Xv的扩展—由VAAPI完成;

l X-Video运动补偿(XvMC)– Xv的扩展--由VAAPI完成;

例如,作为Mesa的一部分开发的Nouveau(开源英伟达显卡驱动),还是被作为Linux内核的一部分来开发的Linux内核组件。Nouveau支持PureVideo品牌的ASIC,并提供通过VDPAU和部分通过XvMC对ASIC访问。

自由的radeon驱动程序通过VDPAU和OpenMAX支持统一视频解码器和视频编码引擎。

请注意,V4L2是内核到用户空间的接口,针对由网络摄像头或电视调谐器提供的视频比特流。

1.5 Device drivers

可用的自由和开源的图形芯片组设备驱动程序由Mesa“管理”(因为现有API的自由开源代码在Mesa内部实现的)。 当前有两种框架来编写图形驱动程序:“Mesa classic”和“Gallium 3D”。mesamatrix.net提供了有关Mesa中某些(但不是全部)驱动程序的概述。


图1-4 Linux AMD graphics stack-2

图1-4 图形设备驱动程序使用两个组件来实现:UMD(用户模式驱动程序)和KMD(内核模式驱动程序)。从linux内核4.2开始,AMD Catalyst和Mesa将共享相同的linux内核驱动程序:amdgpu。Amdgpu提供由DRM和KMS定义的接口。


Mesa classic


Gallium3D

这里有用于AMD / ATI R100至R800,Intel和Nvidia卡的设备的3D加速驱动程序。 以前,存在用于PlayStation 3的IBM / Toshiba / Sony Cell APU,S3 Virge&Savage芯片组,VIA芯片组,Matrox G200和G400等的驱动程序。

自由和开源驱动程序与专有的闭源驱动程序竞争。根据硬件文档和人力的可用性,自由和开源驱动程序在支持新硬件的3D加速方面会或多或少地落后。此外,3D渲染性能通常会明显降低,但有一些明显的例外。如今,对于大多数NVIDIA GPU的Nouveau而言,情况仍然如此,而在AMD Radeon GPU上,开源驱动程序现在几乎可以达到或超过专有驱动程序的性能。

通过适配DRI,Mesa库最终取代了具有各种后端组件的完整OpenGL框架的前端组件,这些后端组件可以提供不同程度的3D硬件支持,同时又不丧失完整的软件渲染功能。 整个系统使用了许多不同的软件组件。

虽然设计要求所有这些组件都仔细交互,但它们之间的接口是相对固定的。 尽管如此,由于与Mesa堆栈进行交互的大多数组件都是开源的,因此实验工作通常是通过同时更改多个组件以及它们之间的接口来完成的。如果此类实验证明成功,则可以将其合并到下一个主要或次要版本中。这适用于在2007-2008年期间开发的DRI规范的更新。 该实验的结果DRI2,在没有锁的情况下运行,并具有改进的后缓冲区支持。 为此,创建了Mesa的特殊git分支。

自2013年以来,DRI3受Intel驱动程序的支持,自2016年以来在某些Linux发行版中默认为DRI3,以支持Vulkan等。 自2016年末以来(X.Org Server 1.18.3和更高版本),它也是AMD硬件上的默认设置。

1.6 Direct Rendering Infrastructure(DRI)

当3D图形卡成为PC的主流时,一些公司的部分支持者开始致力于为Mesa添加对硬件加速3D渲染功能的更多支持。直接渲染基础架构(DRI)是将Mesa,OpenGL和其他3D渲染API库等软件与设备驱动程序以及硬件对接的一种方法。在达到基本的可用性水平后,DRI支持正式添加到了Mesa。这大大拓宽了使用Mesa库时可获得的硬件支持范围。

1.7 Software render

Mesa还包含称为swrast的软件渲染实现,当不存在图形硬件加速器时,该渲染器允许着色器在CPU上运行,作为后备。 Gallium软件光栅化器称为软件管道(softpipe),或者在构建时支持LLVM llvmpipe,后者在运行时生成CPU代码。 自Mesa 10.x起,Softpipe(10.3)和LLVMpipe(10.2)支持OpenGL 3.3+。 实际约有80%的OpenGL 4.x功能是在Mesa 17.3中实现的(请参阅Mesamatrix)。

在Mesa 12.0中,新的Intel Rasterizer OpenSWR在大型数据集的群集中具有很高的优势。 它比游戏或艺术图像更注重工程可视化,并且只能在x86处理器上工作。 另一方面,现在支持OpenGL 3.1+。在某些示例中,测量了与LLVMPIPE相关的从29到51的加速度值。 自Mesa 17.1开始,OpenSWR支持OpenGL 3.3+。

VirGL是自2015年以来在Mesa 11.1中实现的,具有OpenGL 3.3支持的虚拟机光栅化程序,并且自Mesa 18开始在Mesamatrix中显示。在实际的新Mesa 18.2中,它比OpenGL 4.3和OpenGL ES 3.2所支持的功能更多。大约80%的OpenGL 4.4和4.5功能现在也已准备就绪。Vulkan Development从GSOC 2018项目开始。

1.8 Mega drivers

埃里克·安霍尔特(Eric Anholt)提出了将多个驱动程序捆绑为一个“大型”驱动程序的想法。它允许在多个驱动程序之间使用共享Mesa代码的单个副本(而不是在每个驱动程序中单独存在),并且由于除去了内部库接口,因此比单独的共享库提供更好的性能。 VDPAU和XvMC的状态跟踪器已成为独立的库。

shader-db是从各种计算机游戏和基准中收集的大约20,000个着色器的集合,以及一些用于编译这些着色器和收集一些统计信息的脚本。Shader-db旨在帮助验证优化。

人们注意到,着色器的数量不是手写的,而是生成的。 这意味着这些着色器最初是用HLSL编写的,然后通过某些翻译器程序(例如, HLSL2GLSL。 问题在于,生成的代码通常远非最佳。 马特·特纳(Matt Turner)说,在翻译程序中修复此问题要比让Mesa的编译器承担处理此类过大的着色器的负担要容易得多。

shader-db不能被视为免费的开源软件。 要合法使用它,必须拥有着色器所属的所有计算机游戏的许可证。

二、Software architecture

图2-1 Division of labor cpu and gpu


图2-1 图形驱动程序由OpenGL状态机的实现和将着色器编译为GPU的机器语言的编译栈组成。此编译以及几乎所有其他编译都在CPU上执行,然后将已编译的着色器发送到GPU并由GPU执行。(SDL=Simple DirectMedia Layer)


图2-2 Mesa layers of crap 2014


图2-2 Mesa中的中间件(IRs):GLSL IR、Mesa IR、TGSI和LLVM IR。缺少HIR\LIR\NIR


图2-3 Mesa layers of crap 2016


图2-3 Mesa IR将被完全删除

Mesa中所谓的“用户模式图形设备驱动程序”(UM?D)与通常称为设备驱动程序的共同点很少。有几个区别:
Ø 它们旨在附加在存在的内核模式图形设备驱动程序之上工作,例如可作为源代码在/drivers/gpu/drm/下的Linux内核的一部分获得。每个UMD都在特定库libdrm_specific和一个通用库libdrm的帮助下与其对应的内核模式进行通信。本节应仅在libdrm上方的用户模式部分查看;

Ø 有限状态机的某些实现方式例如由 OpenGL; OpenGL状态机的这种实现可以在多个UMD之间共享,也可以不共享;

Ø 它们占了某种编译器的很大一部分,例如 GLSL,并最终输出机器代码。解析器可以在多个UMD之间共享,也可以是特定的;

2.1 Mesa's Intermediate Representations

Mesa的目标之一是优化要由相应GPU执行的代码。 一个是代码共享。代替记录执行该操作或执行该操作的软件片段,该Wikipedia文章应着眼于在编译和优化过程中使用的中间表示。 请参阅抽象语法树(AST)和静态单一分配形式(SSA形式)。

SPIR-V

SPIR-V是标准便携式中间表示的特定版本。 这个想法是,图形应用程序输出SPIR-V而不是GLSL。 与后者相反,SPIR-V是二进制的,以避免不同驱动程序实现的GLSL编译器前端之间的实现差异,因为这已成为应用程序不兼容性和错误的主要来源。 同样,SPIR-V二进制文件通常也经过一些常规优化。 同样,在某种程度上,SPIR-V的二进制表示形式提供了某种程度的混淆,这可能会作为一种知识产权保护形式而吸引某些软件供应商。 但是,SPIR-V包含大量的反射信息,并且存在将SPIR-V转换回高质量,人类可读的高级代码的工具。UMD仅需要应用特定于支持硬件的优化。

LLVM IR

UMD radeonsi和llvmpipe不输出机器代码,而是LLVM IR。从这里开始,LLVM进行优化并编译为机器代码。这确实意味着还必须安装LLVM的某个最低版本。

RADV ACO IR

RADV ACO使用自己的接近NIR的IR,以优化和生成Radeon GPU(GCN 1+,又名GFX6 +)GPU上的Vulkan SPIR-V着色器的最终二进制代码。 从20.1.0版开始,ACO仅在RADV(Vulkan驱动程序)中使用,尚未在RadeonSI中使用。

Mesa's GLSL compiler

Mesa的GLSL编译器生成自己的IR。由于每个驱动程序对LIR的要求都非常不同,因此需要区分HIR(高级别IR)和LIR(低级别IR)。

此外,最主要的Gallium 3D部分还未介绍,篇幅限制,后续单独整理。


本文转自互联网,原始出处已不可考,感谢原作者。