引言

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。

glx-arch

下圖為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)。

2d-3d-data-path

 

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

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相關控制,如前述。

dri-control-flow

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

dri-arch

 

 

 

Reference

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

Wiki

DRM

DRI架構

arrow
arrow
    全站熱搜

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