引言

2D/3D加速一直是一個很大的topic,看了好幾次,也抄了很多筆記,還是很難有一條清楚的路。但即使如此,還是要寫點東西,個人理解難免過時或是有錯,儘供參考,歡迎指正。

 

開頭

要從哪開始記錄著實讓我困擾了一點時間,就先從OpenGL開始好了,以後有機會再來refine。

OpenGL,也就是GL,一種工業的graphic標準,是跨平台,跨語言的spec。用於生成2D/3D的圖像,包含約350個API。在windows上獨有的DirectX是類似的東西。OpenGL是設計成用來輸出,意即並沒有windows system, keyboard,mouse等輸入設備的概念,這樣的好處是與系統獨立,因此可以跨平台。但仍然可跟X windows整合,此時就需要更多的API,因此在X windows中,就有了GLX: OpenGL在X的API實作。GLX提供了X和OpenGL的binding, 使得一般的X應用程式也可以使用OpenGL的function (透過GLX)。GLX也提供了X protocol的extension,因此應用程式也可送3D的rendering command給X。

mesa是open source的OpenGL實作,是一種軟體的3D加速 (sw raster),在沒有hw的3D加速下,由CPU完成計算 (Note: 目前也有若干hw acceleration的實作)。因此,在3D indirect rendering的path是由應用程式呼叫GLX,再透過mesa所實作的OpenGL,最後由DDX driver呼叫graphic hw。這樣的path是透過sw處理3D的data。那direct rendering又是怎麼一回事呢?從path來看,是應用程式將3D data直接送到grapic hw (2D data還是走傳統路徑EXA)。名詞上是所謂的DRI (Direct Rendering Infrastructure),就是讓3D應用程式直接direct rendering,其目的主要是將X和hw串起來,並將從mesa或是OpenGL的函數呼叫轉為硬體的指令,直接存取硬體。這些工作就是由DRI driver來完成,DRI driver長像為xxx_dri.so,如i810_dri.so,radeon_dri.so,可在/usr/lib/dri找到這些。大部分的DRI driver都是基於mesa,由其套件名稱可看出,如i810_dri.so屬於libgl1-mesa-dri。

再來是libGL.so。libGL屬於libgl1-mesa-dev,提供GLX和DRI兩種方式,因此支援direct/indirect rendering,並提供 (實作) GLX API interface,OpenGL API的入口點 (the glue between OpenGL and X)。基本上libGL是一個loader,載入適當的driver。若是DRI,則透過libgl1-mesa-dri裡的DRI driver做direct rendering,如i965_dri.so。因此3D driver是實做OpenGL API的實作。若是GLX則載入libglx.so。綜上所述,libGL其實是在做dispatch的工作: 將OpenGL API call傳給3D driver,如果沒有3D driver,只好讓Xserver用sw硬幹 (fallback to)。libglx.so屬於xserver-xorg-core。(note:nvidia的實作不一樣,有自己的libglx,屬於nvidia-glx,其driver是直接對hw做存取)。

DRI之下,就是DRM了,這是kernel的部分,負責管理對硬體的存取。DRM主管graphics hw,就是resource的管理。resource包括DMA,memory management,locking,security等。之所以需要管理是因為要同時存取graphics hw的人很多,包括X serer,render clients,kernel等。kernel 2.6.28後更導入了intel 主導的GEM memory manager,用來管理graphics hw的memory。DRM提供DRI的支援為:

1. synchronized access: 這是lock的部分。比如說X server要做2D rendering,direct rendering client要存取framebuffer,或是kernel在做DMA。

2. security policy: X server以root執行,可存取framebuffer及MMIO (/dev/mem)。但一般direct rendering client是user,因此DRM提管mapping的管道,但有些限制,如用xauth透過與X的connection。

3. DMA engine:

再來看圖示:

從app層來的request,若是屬於direct rendering,則直接送給graphics hw。indirect rendering則為GLX packets (由libGL產生),透過GLX protocol送至GLX decode。X packets為conventional的X protocol。

下圖為2D/3D data的路徑。最快的當然是最左邊的direct rendering。3D indirect rendering App的3D data仍可透過GLX傳給Mesa,做sw raster,即軟體加速。2D的data都一樣,都是透過XAA/EXA做加速,最後由DDX driver (xxx_drv.so)送至kernel,DDX主要是處理像Render和Xvideo(xv)。

 

再來是最複雜的,很難解釋這張圖,但搭配著前面所解釋的,應該還可以看懂個五成左右。

1. xclient透過xlib將request傳給Xserver ,再由protocol decoder決定走哪條路。

2. 中間的x11程式就是傳統的xserver/xclient/xprotocol,其路徑為DIX->XAA->DDX。

3. 右邊的3D indirect rendering呼應第一張GLX archtecture,走的是GLX,然後由protocol decoder傳至GLX module,最後由Mesa做sw raster。

4.  左邊的direct rendering,不曉得為什麼還會有xlib->protocol這條路,似乎不make sense。而OpenGL Library->GLX library->DRI library這條看起來是AIGLX,雖然是indirect,但仍然使用了xxx_dri.so的3D加速,這跟以往的sw raster有很大的差別,雖然仍有一些X的overhead,但仍然被認為是快速的。而OpenGL lib->OpenGL Renderer應該才是真正的direct rendering吧! 在使用3D driver時,也有可能遇到graphics hw沒有support的function,因此還是有可能fallback to X。

5. kernel的DRM driver處理resource相關控制,如前述。

如果以上都通了,下面這張圖也就不難理解了。

 

 

 

Reference

Jserv (jserv的文章族繁不及備載,反正大家都知道這號人物!)

Wiki

DRM

DRI架構

文章標籤
全站熱搜
創作者介紹
創作者 kezeodsnx 的頭像
kezeodsnx

心的距離

kezeodsnx 發表在 痞客邦 留言(2) 人氣(8,150)