Mesa,也稱為Mesa3D和Mesa 3D圖形庫,是OpenGL,Vulkan和其他圖形API規范的開源軟件實現。Mesa根據規范轉換特定供應商的圖形硬件驅動程序。
它最重要的用戶是兩個圖形驅動程序,這些圖形驅動程序主要由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月發起。 Mesa隨后被廣泛采用,現在包含來自世界各地的各個個人和公司的眾多貢獻,包括管理OpenGL規范的Khronos Group的圖形硬件制造商的貢獻。對於Linux,開發工作也部分由眾籌推動。
一、 Overview
圖1.1 3D計算機游戲通過OpenGL將渲染計算任務實時派發給GPU。着色器使用OpenGL着色語言或者SPIR-V編寫,並在CPU上進行編譯。編譯后的程序在GPU上執行。
圖1-2 Linux圖形棧圖示:DRM和libDRM,Mesa 3D。Display server屬於窗口系統,不是必需的,例如對於游戲。
圖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 圖形設備驅動程序使用兩個組件來實現: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 圖形驅動程序由OpenGL狀態機的實現和將着色器編譯為GPU的機器語言的編譯棧組成。此編譯以及幾乎所有其他編譯都在CPU上執行,然后將已編譯的着色器發送到GPU並由GPU執行。(SDL=Simple DirectMedia Layer)
圖2-2 Mesa中的中間件(IRs):GLSL IR、Mesa IR、TGSI和LLVM IR。缺少HIR\LIR\NIR
圖2-3 Mesa IR將被完全刪除
Mesa中所謂的“用戶模式圖形設備驅動程序”(UMD)與通常稱為設備驅動程序的共同點很少。有幾個區別:
Ø 它們旨在附加在存在的內核模式圖形設備驅動程序之上工作,例如可作為源代碼在/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部分還為介紹,篇幅限制,后續單獨整理。