Xorg 嶄新的硬體加速與效能提昇機制
http://www.linuxgraphics.cn/xwindow/xorg_hardware_accelerate.html
作者: Jim Huang (黃敬群 / "jserv")
日期: 2009-06-26
本文是根据 jserv 于 2006 年 7 月 5 日在 ircconf.debian.org.tw 上的讲座整理而来的,该文详细讲解了 X window 崭新的硬件加速与性能提升机制。
|
简介本次 Debian@Taiwan IRC Conference 大綱如下:
演讲者:Jim Huang (黃敬群 / "jserv")。 演讲时间:2006-07-05 X Window System 的 Transport 效能與改善議題咱們先來複習過去提到 X Window System 種種變革的基礎。在許多層面,現在 的 Xorg (X Window System Reference Implementation) 已經跳脫傳統 Client-Server 的架構了。Client / Server 架構下使用相當緩慢的 transport 機制,從 Client 端將 rendering 指令,送到 Server 端,這在普通的應用來 說,已經足夠了,但是對於 2D / 3D Graphics 顯然是很大的效能瓶頸 — 耗費 太多時間在 round-trip (繪圖指令的往返) 通信上,回頭看看過去的示意圖: X Window System 的設計不像傳統的 GUI system,反而跟關聯性資料庫的架構 神似,因為考慮到網路的通透性 (network transparency),將 primitive graphical operations 包裝成一個又一個的指令,其中的 transport engine 則需要額外的 decode 動作,然而,在圖形應用日趨複雜的今日,開發者展開了 新的思索:能否提供更為直覺、簡單的設計,讓 X client 可以直接與圖形硬體 裝置對話、進而充分發揮硬體加速的能力 (2D / 3D 基本操作、OpenGL、 MPEG-2/4 Acceleration) 呢? 直接與硬體溝通的 Graphics Toolkits / Window System 相繼被提出,也有不錯的效能表現,比方說 DirectFB2 與 KGI3,但是在 X Window System 的設計原則,是希望透過層層的架構,讓硬體能夠抽象化,是否意味著我們將無法以更好的效能處理 2D /3D Graphics 呢?這是個相當大的挑戰,一方面要能處理硬體,另一方面要保留既有 X Window System 的相容設計原則,也就是 1987 年 X 第 11 版 (X11) 這個重要里程碑的 Protocol / API 相容性,於是 XFree86 Developer 提出 DRI (Direct Rendering Infrastructure) 的機制。
以 Linux kernel 來說,make menuconfig 中 Device Drivers-> Character devices-> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) 此 DRM (Direct Rendering Manager) 即運作於 kernel-level 的 driver,隨 後在 X server 層面實做 DRI 並適當驅動 (/etc/X11/xorg.conf 中 Option "RenderAccel") 後,即可展現 DRI 的威力,至於詳情,在「FreeDesktop.org 與 X.org 嶄新發展概況」一文中已經提過。 簡單來說,X Window System 的 Transport 效能改善因素是廣泛的,為了徹底 解決既有的問題必須考慮以下議題:
至於 EXA、XGL、EGL,以及 indirect rendering 等新名詞,稍後會提及,接下來我們要探討 2D Rendering 的突破。 2D Rendering 的突破2003 年,X.org 的領導人物 James Gettys 與 Keith Packard 共同撰寫了 "The (Re)Architecture of the X Window System"4,自始展開了這幾年 X Winow System 與 FreeDesktop 重大的突破,有幾個重點:
在這幾年的光影都有了頗大建樹,這些突破中,首要要克服的問題,都始於 X11 2D bit-blit 為基礎的 text 與 graphics system 設計。所謂的 bit-blit 也 稱 BitBLT 或 Bit Block Transfer,示意圖可參考:
原文的解釋為 "Copy image data (eg. copying a surface on another), applying image combination operations.",對於基本的繪圖操作雖游刃有餘, 然而,圖形處理是人類視覺永無止盡的妥協與突破,光是 text 的部份,一旦需 要作 antialiasing 或 vector graphics,或者 gradient 一類的操作,不僅功 能有所不足,原本處理的效能更是低落,不得不引入新機制以克服這些問題。 4. http://keithp.com/~keithp/talks/xarch_ols2004/xarch-ols2004-html/ 隨著 GPU (Graphics Processing Unit) 的突飛猛進,ATI 與 nVIDIA 的繪圖顯 示卡早已突破百萬個電晶體的數量,之所以有如此複雜的硬體支援,超過九成是 針對 3D /OpenGL 的需求,以下是 SGI (Silicon Graphics, Inc.) 規範於 OpenGL graphics system 的圖例:
較為先進的硬體,甚至是手持裝置的繪圖晶片,都在硬體層面實現了這一系列的 基本操作,包含 Vertices、Primitives,以及 Fragments 的支援,姑且不探究 細節,這些都是所謂的 3D pipeline,然而,沒有在架構上作突破的 X Window System 是完全無法使用到這些機制,換言之,過去頂多只使用不到一成的硬體 設計。 說到這邊,有個迷思需要澄清:既然常見的桌面系統,如 KDE、GNOME、XFCE, 或其他輕量級的軟體組合,都還僅限於 2D 操作,那麼探討 3D 與硬體加速的議 題,是否有意義呢? 事實上,2D 的螢幕,本身就是一個 surface,而 "surface" 這詞在圖學中就是表示允許繪圖操作的單元,就現在輸出裝置與投影的系統來說,3D / OpenGL 硬體最終的描繪就是普通的 2D 平面,而在前述的 3D pipeline 與 Kery operations 中,其實涵蓋了硬體層面的支援項目。 這裡介绍下 gradient。 http://blog.linux.org.tw/~jserv/archives/001444.html 簡單來說,gradient 是文字或圖樣中,顏色平順的變化。 具體來說,XFree86 4.x 的 Render extension 是 2D Rendering 突破的第一步。 2000 年時,當時是 XFree86 core team member 的 Keith Packard 在既有 XFree86 的 codebase 為基礎,加入 X Render extension,最早要克服的議題 就是 antialiased text,運作中的 anti-aliasing text 可參考以下展示: 為了滿足進階繪圖的需求,實做於 X server-side 的 X Render 增加了 Porter-Duff operation,也就是在 1984 年 Thomas Porter 與 Tom Duff 合著 的 "Compositing Digital Images"5 中描述 12 則基本規則的集合,簡單來 說,這些基本的 Alpha 合成規則,將源色與目標色組合,在圖形和像素中,實 現了混合與透明的效果,示意圖如下: 5. SIGGRAPH 84, 253-259 這些操作允許 surface 以許多不同的途徑或規則作結合,類似 OpenGL 的規範,這也使得除了 anti-aliasing text 外,X Render 逐漸用於進階的繪圖應用中。 附帶一提,FreeDesktop 有個計畫 glitz6 可視為 OpenGL 硬體加速版本的 X Render 實做,除了 X Render extension 規範的 component alpha 與 image transformations 外,glitz 還添增了 convolution filters 與 color gradients 支援,因為這些重要的特徵,Cairo Graphics7 與 Xgl 都大量使 用 glitz。
重點回顧:X Render extension 的特徵:
glitz 需要 OpenGL / DRI 的驅動,在一般的 distribution 為求穩定性可能會 直接 turn off。 這裡將 glitz 也歸類於 X Render 中,glitz 的主要開發者 David Raveman 撰 寫一篇重要的論文 "Glitz: Hardware Accelerated Image Compositing using OpenGL"8
在探討細節之前,先看看 Cairo、Glitz,以及 OpenGL 這三者的關係圖: Cairo (舊稱:Xr 或 Xr/Xc) 是個 vector graphics library,除了向量繪圖操 作外,Cairo 的設計允許多種設備的交叉輸出,就目前的實做 (cairo-1.2) 來 說,支援 Xlib、in-memory image buffer、Glitz/OpenGL、PNG、PostScript、 PDF、GDI (Win32)、Quartz (Mac OS X)、SVG,以及 XCB (X C Binding) 等。 Cairo 的目標就是在多樣化的輸出裝置提供一致的輸出結果,並支持硬體加速的 機制,舉例來說,在 X Window System 上會透過 X Render extension 或 Glitz,而允許的操作有描線、貝氏曲線、平面轉換、圖像透明度合成、 anti-aliasing、... 等。 除了 Gtk+ 2.8 採用 Cairo 作為底層 GDK Graphics 的基礎外,Mozilla/Firefox 在 Version 2.0 中,也採用 Cairo 作為跨平台的 vector graphics engine,即著眼於前述的特徵。對了,Cairo 開發團隊中有位大陸的 committer,做了很多 text 方面的改良,日前也實做了中文直排的基本支援。 這裡用簡單的例子展示 Cairo 的 programming model,作為向量繪圖的說明。 原本 Xlib 中的 int XDrawLine(Display *display, Drawable d, GC gc, int x1, int y1, int x2, int y2); 以 Cairo 繪圖的思維則是: cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); cairo_stroke (cr); Cairo 被賦予的使命是如此重大,Glitz/OpenGL 也被視為 FreeDesktop 效能的 指標之一,前面提過 OpenGL graphics system,這裡再詳細看看 OpenGL Rendering pipeline:
David Raveman 的論文詳細探討了 Glitz 的實做模式,而這裡簡述 Glitz 利用 OpenGL rendering 達到圖形加速的方式:
透過 OpenGL 的 pixel buffer (pbuffer) 處理 offscreen drawing。 需要注意的是,理想情況下,pbuffer 的操作完全是儲存於 video memory
提供直接存取圖形硬體的 API / Data 操作
將 surface 視為 texture,再以 OpenGL 的 fragment programs 來實做混合多個 textures 的操作 [按] 原文 - Fragment programs allow for fragment level programmability in OpenGL, and in combination with multi-texturing, Glitz can perform composite operations with a mask surface very efciently.
OpenGL 的強項,Glitz 完全採用 OpenGL 來實現 [Performance] 的部份探討了 Glitz 相較於 Enlightenment imlib2 與 X Render extension,結果 Glitz 在許多操作都有優越的表現,而透過 nVIDIA binary driver 來驅動 X Render extension 並與 Glitz 比較,後者仍略勝一籌。 再補充一下,X Render 一開始雖然設計為解決 X 上實現 anti-aliasing text 的問題,後來廣泛應用在許多 graphics operations。 就現在的桌面應用來說, 可以說繪圖動作大都耗費在 Render extension 中glitz 不僅引入 OpenGL 的思 維,還試圖以 OpenGL 來改進 X Render。 X Render 通常比较慢,没有加速。 請記住一點,現代的繪圖硬體對 3D 有很強大的支援, 90% 的電晶體都在實做這些, X Render 很多動作都是軟體實現。要提出一個機制讓不必要的 CPU bound 移轉到 GPU。過去的設計是沒有機會。 另一篇值得參考的文獻是 Keith Packard 的論文 "Getting X Off The Hardware"9,主要是探討將硬體相關的函式庫抽離出 X server 的可能性,並 舉 KDrive 的開發過程中,Eric Anholt 利用既有 ATI Radeon DRI driver 來 加速 2D 繪圖操作的實驗,給定兩個圖形硬體支援可能的方向:
而 Glitz 也在 [Graphics Acceleration] 中被提及,作為 OpenGL 加速 2D 顯 示的效能與可行性。 9. http://keithp.com/~keithp/talks/xserver_ols2004/xserver-ols2004-html/ Eric Anholt 是 X.org 中 ATI driver 的維護人、FreeBSD committer。 之前的文章 「FreeDesktop.org 與 X.org 嶄新發展介紹」提過 "X-on-GL" (or X-over-GL) 的概念,而 X Developer Conference10 2006 中, NVIDIA Corporation 的代表 Andy Ritger 在議程中,歸納 "The X-on-OpenGL Model" 有以下考量:
10. http://wiki.x.org/wiki/XDevConf 在 X-on-GL 中,DDX (Device-Dependent X) 被大量替換成 OpenGL 與其 driver 的實做,對硬體來說,整個 X server 就是一個 OpenGL context 的 owner,系統架構如下圖: 就目前的實做來說,Novell 主導的 Xgl (實際上採用 Xglx) 是朝這個方向開發, 而 nVIDIA 也在 DDX 與 hardware-specific OpenGL driver 的部份,提供 native Linux 的支援。 在 Novell Xgl 搭配 compiz (以 OpenGL 實做的 Window Manager 的 Composite Manager) 運作的情況,其架構圖可簡化為如下:
具體運作的內容,稍後會作介紹。但是我們也可從架構看到一個重點:以往的 X11 Application (X client) 執行任何 primitive graphics operations 時, 都需要透過 DIX 作 protocol engine 的 decoding,接下來這些解譯過的 command 才依據內容需求,透過 DDX 與 X Device Driver 來對硬體要求作繪圖 操作,然而,compiz 雖然本質上是個 X client,但我們可從架構圖看出, compiz 為了圖形處理的加速,可以透過 GLX 更快的路徑,直接操作硬體,如圖 中的 FBO (FrameBuffer Object) 與 pBuffer。 XAA 與 EXAXAAXAA (X Acceleration Architecture) 是 XFree86 4.0 新引入的機制,XAA 的 設計是 "User Space Drivers",可滿足多數的 2D video 需求,然而並不見得 適合現代桌面系統的應用。 依據 XAA 的設計,雖然是涵蓋多數 2D video / graphics 的操作,但是其中涵 蓋鮮少使用的操作,例如 Bresenham lines,反而對 X Render extension 並無 直接的支援,這對強調 client-side rendering 的桌面應用來說,顯得很沒有 效益。更重要的是,當 X Render extension 與 Composite extension (詳情 見之前的演講「綜觀 X Window System 新發展」,並非本次議程的重點) 被廣 泛使用時,XAA 的複雜 memory manager 會讓系統效能受限,並嚴重受限 於系 統資源的分配。必須說,事實上整個 XAA 的設計非常複雜,若用三言兩語帶過 實在很不負責,不過這與 Xorg 近來的發展方向相背,所以這裡直接探討新的 Acceleration Driver Model - EXA。EXA (EXcellent Architecture 或 Ex-kaa aXeleration Architecture) 由 KDE Hacker、Trolltech 員工 - Zack Rusin - 所提出,其著眼點就是針對 client-side rendering 所需的 X Render extension 與 Composite extension, 提出與 transform operations 都有一定程度的硬體支援,EXA driver 會以更 好的方式去直接驅動 (相反地,XAA 要處理這些運算,必須透過迂迴的方式,最 重要的是,無法發揮硬體的優勢)。 在 Xorg 的 GIT 分散式版本控制系統 (今年已經從 CVS repository 移轉) 中, 許多 X device driver 都開始支援 EXA driver model,例如 Intel i810、 ATI Radeon,以及 SiS i128 等等,EXA 已經在 Xorg X11R7 中納入,在 X11R7.1 之後則有更大的效能突破,至於 EXA 的實做與支援狀態,可參考: http://xorg.freedesktop.org/wiki/ExaStatus [按] Keith Packard 與 Eric Anholt 目前都服務於 Intel 驅動 EXA 的方式可 修改 /etc/X11/xorg.conf 的設定,以小弟的環境來說,像是: (ATI Radeon IGP 340) Section "Device" Identifier "Generic Video Card" Driver "radeon" BusID "PCI:1:5:0" Option "UseFBDev" "true" Option "AccelMethod" "EXA" Option "AccelDFS" Option "FBTexPercent" "0" Option "AGPMode" "4" Option "DPMS" Option "AGPFastWrite" "true" Option "EnablePageFlip" "true" # CRT: Analog; TMDS: Desktop Flat Panel; LVDS: Laptop Flat Panel Option "MonitorLayout" "LVDS" EndSection 注意到 Option "AccelMethod" 由預設的 XAA 改為 EXA,"AccelDFS" 則是 EXA driver model 的新特徵,意思是儘可能使用加速的 EXA DownloadFromScreen book,例如 Direct Rendering 的情況下,這是考量到 GPU 到 Host 傳輸的過 程中,AGP bridge 的議題,對 VRAM 能做出更好的掌握。 簡單來說,為什麼要有 EXA 呢?因為 XAA 過去的思維是 device-oriented 的,而 EXA 是真正從桌面應用 (client side rendering) 去思考 Driver Model 該做什麼改進。 另外一個問題就是如何有效管理 VRAM (Video RAM) 與 AGP,這是現在的桌面應 用中,相當重要的議題。XAA 因為是 device-oriented,所以設計相當被動基本 上只理會有無 request for 特定的繪圖操作,而 EXA 考量到 X Render extension 與 X Composite extension 在 X server 那端就已經預先考慮到 memory allocation & resource managment , 然後才透過 X Device Driver 的 EXA 支援來作掉,換言之,較為主動。VRAM 與 AGP 可說是決定硬體驅動與 效能表現的關鍵。 除了 EXA 的 driver memory 議題,DRI memory management 也是另一個複雜的 考量。基本上,DRI 的設計中,都是建立於「合作」的假設,倘若一個 DRI client 需要更多的 memory,DRI 會拒絕其他 OpenGL context,並且不保留 content,雖然這樣的架構設計較直觀,而且行之有年,系統示意圖如下: 但這也引來以下的問題:
所以,明確來說,若要進一步提昇整體的效能與彈性,並且避免之前設計中,對 硬體記憶體不精確的管理機制,DRI 與 Driver Model 還需要有以下設計:
專注於 open source X Window System / Driver 開發的 Tungsten Graphics11 為此提出新的設計,示意圖如下: 其中 TTM 就是 Translation To Maps,在 user-space,在這個設計下,memory page 被使用會自動配置,使用者可要求任何範圍的 page,系統會作另一層轉換 動作。之所以架構變得如此複雜,主要的想法就是讓 DRM (DRI Management kernel module) 管理所有 page 的 mapping 動作,包含 user/virtual、 kernel,以及 AGP 等,由於 DRM 介入,更動 binding / unbinding 時的 caching policy,使其由 TTM 進行處理。 11. http://www.tungstengraphics.com/ See Alsohttp://ircconf.debian.org.tw/log/2006-07-05.log |