简介
本次 Debian@Taiwan IRC Conference 大綱如下:
- X Window System 的 Transport 效能與改善議題
- 2D Rendering 的突破
- XFree86 4.x 的 Render extension
- XAA 與其限制
- 嶄新的 EXA 與設計概念
- 3D Rendering 與 DRI
- 探索 3D Rendering 模型
- 既有硬體加速機制
- 迎向未來:Xgl 與 AIGLX
- 實做層面的效能提昇
演讲者: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 相繼被提出,也有不錯的效能表現,比方說 DirectFB 與 KGI,但是在 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 效能改善因素是廣泛的,為了徹底
解決既有的問題必須考慮以下議題:
- 硬體的驅動程式
- 支援 Xorg 種種變革的新 Driver Framework,如 EXA 與 XGL
- DRI/Mesa 對 Indirect rendering 與 EGL 的支援
至於 EXA、XGL、EGL,以及 indirect rendering 等新名詞,稍後會提及,接下來我們要探討 2D Rendering 的突破。
2D Rendering 的突破
2003 年,X.org 的領導人物 James Gettys 與 Keith Packard 共同撰寫了
"The (Re)Architecture of the X Window System",自始展開了這幾年 X
Winow System 與 FreeDesktop 重大的突破,有幾個重點:
- Text and Graphics
- Cairo
- Accessibility and Eye-Candy
- OpenGL based X
- Kernel support for graphics cards
- Housecleaning and Latency Elimination and Latency Hiding
在這幾年的光影都有了頗大建樹,這些突破中,首要要克服的問題,都始於 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 一類的操作,不僅功
能有所不足,原本處理的效能更是低落,不得不引入新機制以克服這些問題。
隨著 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" 中描述 12 則基本規則的集合,簡單來
說,這些基本的 Alpha 合成規則,將源色與目標色組合,在圖形和像素中,實
現了混合與透明的效果,示意圖如下:

這些操作允許 surface 以許多不同的途徑或規則作結合,類似 OpenGL 的規範,這也使得除了 anti-aliasing text 外,X Render 逐漸用於進階的繪圖應用中。
附帶一提,FreeDesktop 有個計畫 glitz 可視為 OpenGL 硬體加速版本的 X
Render 實做,除了 X Render extension 規範的 component alpha 與 image
transformations 外,glitz 還添增了 convolution filters 與 color
gradients 支援,因為這些重要的特徵,Cairo Graphics 與 Xgl 都大量使
用 glitz。
重點回顧:X Render extension 的特徵:
- 延伸 X Drawable 型態並擴展為 Picture 型態
- 增加 Alpha channel
- 增加 (選擇性) 座標轉換
- Server 端的 Rendering
- 提供新的途徑以做出原始 Picture 與 mask'ed Picture 間的合成處理
- 矩形區域
- 三角區域
- 不規則區域
- "Component alpha" 概念
glitz 需要 OpenGL / DRI 的驅動,在一般的 distribution 為求穩定性可能會
直接 turn off。
這裡將 glitz 也歸類於 X Render 中,glitz 的主要開發者 David Raveman 撰
寫一篇重要的論文 "Glitz: Hardware Accelerated Image Compositing using
OpenGL"
在探討細節之前,先看看 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

- User-Provided Immediate Data
提供直接存取圖形硬體的 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",主要是探討將硬體相關的函式庫抽離出 X server 的可能性,並
舉 KDrive 的開發過程中,Eric Anholt 利用既有 ATI Radeon DRI driver 來
加速 2D 繪圖操作的實驗,給定兩個圖形硬體支援可能的方向:
- With an OpenGL-based X server
- With a 2D-only X server based on a simple loadable driver API.
而 Glitz 也在 [Graphics Acceleration] 中被提及,作為 OpenGL 加速 2D 顯
示的效能與可行性。
Eric Anholt 是 X.org 中 ATI driver 的維護人、FreeBSD committer。
之前的文章 「FreeDesktop.org 與 X.org 嶄新發展介紹」提過 "X-on-GL" (or
X-over-GL) 的概念,而 X Developer Conference 2006 中, NVIDIA
Corporation 的代表 Andy Ritger 在議程中,歸納 "The X-on-OpenGL Model"
有以下考量:
- Motivated partly by lack of hardware-acceleration of the Render extension
- A successful implementation of X-on-OpenGL, Xgl, is in progress
- Replace XFree86/X.Org DDX with DDX that renders using OpenGL
- No hardware-specific X driver
- Instead use hardware-specific OpenGL driver
- Traditional X driver tasks (rendering, modesetting) handled by X-on-OpenGL DDX
- X-on-OpenGL DDX calls stand-alone OpenGL driver to perform low-level rendering and modesetting
在 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 與 EXA
XAA
XAA (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,雖然這樣的架構設計較直觀,而且行之有年,系統示意圖如下:

但這也引來以下的問題:
- 限制保留於 texture memory 的資料
- 為了避免破壞資料一致性,需要保留兩份 texture 的副本: 一者於主記憶體,另一者存於硬體的記憶體 ==> 導致 texture upload 效能低落
- 缺乏高速的 VBO (Vertex Buffer Object) 與 PBO (Pixel Buffer Object)
- 無法強制要求硬體配置記憶體 ==> Xgl/Compiz 的作法是透過 MESA hack
所以,明確來說,若要進一步提昇整體的效能與彈性,並且避免之前設計中,對
硬體記憶體不精確的管理機制,DRI 與 Driver Model 還需要有以下設計:
- 讓 OpenGL texture 到 buffer 的動作更一般化
- 確保 buffer content 可被保留
- 直接處理 buffer 到 AGP/VRAM 的機制
- 直接查詢 buffer offset 的機制 (透過 DMA 指令)
- map / unmap buffer 到 client memory 的機制
專注於 open source X Window System / Driver 開發的 Tungsten
Graphics 為此提出新的設計,示意圖如下:

其中 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 進行處理。
See Also
http://ircconf.debian.org.tw/log/2006-07-05.log
|