李 亮,黨利軍,石歌頌,王 江,李鎖在
(1.中電(海南)聯(lián)合創(chuàng)新研究院,海南 澄邁 571924;2.中軟信息系統(tǒng)工程有限公司,北京 102209)
視覺是人眼感知外界三維環(huán)境空間信息的重要手段,隨著計(jì)算機(jī)圖形學(xué)的發(fā)展,3D 圖形圖像顯示技術(shù)被廣泛應(yīng)用于生產(chǎn)生活的多個領(lǐng)域,高性能高效率的 3D渲染計(jì)算研究對未來 PKS 體系搶占該領(lǐng)域市場高地、拓寬現(xiàn)有生態(tài)、保障國內(nèi)安全生產(chǎn)有重大意義。本文通過在 PKS 體系上深入研究多種 3D 圖形圖像顯示技術(shù)路線,比較 OpenGL 和Vulkan 兩種 3D 圖形應(yīng)用程序編程接口(Application Programming Interfaces,API)的性能差異,為將來該技術(shù)在 PKS 的發(fā)展提供參考。
3D 圖形圖像顯示技術(shù)路線指的是顯卡和圖形 API的組合,現(xiàn)如今,高性能顯卡主要來自AMD 和 Nvidia這兩個廠商。圖形 API 又稱圖形庫,其主要作用是通過調(diào)用顯卡對圖形進(jìn)行計(jì)算,主流的圖形庫有三種,分別為:DirectX、OpenGL[1]和Vulkan[2],其中 DirectX 由微軟公司創(chuàng)建,跨平臺能力差,這三種圖形庫的細(xì)節(jié)如表 1所示。本文主要研究 OpenGL 和 Vulkan 這兩種圖形庫。
OpenGL 是 1990 年代開發(fā)的首批圖形框架之一,被認(rèn)為是行業(yè)標(biāo)準(zhǔn),同時在很長一段時間內(nèi),AMD 顯卡加OpenGL 是PKS 體系唯一的 3D 圖形圖像顯示技術(shù)路線。然而,隨著晶體管尺寸的減小,中央處理器(CPU)開始面臨丹納德縮放等問題,CPU 的開發(fā)趨勢偏向于并行和多核[3]。伴隨著芯片設(shè)計(jì)廠商設(shè)計(jì)理念的轉(zhuǎn)變,當(dāng)時的 OpenGL 正在阻礙顯卡性能的發(fā)揮,即使 OpenGL努力跟上潮流,但當(dāng)時的 OpenGL 無法有效地使用多線程來渲染,意味著渲染密集型程序受到 CPU 單核性能的限制,未能發(fā)揮多個CPU 核心的計(jì)算優(yōu)勢。
表1 三種主流圖形庫細(xì)節(jié)一覽表
為了解決 OpenGL 的不足,開放標(biāo)準(zhǔn)組織Khronos Group 于2015 年推出了一款新的圖形框架 Vulkan 接口,這款接口相比 OpenGL 更為輕量化,且更貼近底層[4],可以更加充分利用多核 CPU 的核心計(jì)算優(yōu)勢,這與 PKS 體系芯片多 CPU 核心的發(fā)展方向非常契合。
本文主要探索與研究基于 PKS 體系的 3D 圖形圖像顯示技術(shù),主要工作包含以下幾個方面:
(1)深入研究 PKS 體系上 OpenGL 和 Vulkan 的圖形渲染流程和機(jī)制;
(2)在 PKS 體系上增加 Vulkan 圖形庫對 AMD 和Nvidia 的適配,拓寬 PKS 體系上 3D 圖形圖像顯示的技術(shù)路線;
(3) 在 PKS 終端上通過三種開源基準(zhǔn)工具對OpenGL 和 Vulkan 進(jìn)行實(shí)驗(yàn),實(shí)驗(yàn)結(jié)果為 PKS 未來在3D 顯示技術(shù)的發(fā)展提供有意義的參考。
本節(jié)對 Linux 圖形棧和圖形底層 API,即 OpenGL和 Vulkan 進(jìn)行介紹。
Linux 圖形顯示的基本流程如圖1 所示,應(yīng)用程序根據(jù)用戶需求,將一系列渲染指令通過 OpenGL 或 Vulkan 等接口提交給 GPU 硬件。OpenGL 和 Vulkan 等圖形庫在 Linux 的實(shí)現(xiàn)可以有很多形式,這里以圖形庫的開源實(shí)現(xiàn) Mesa 3D 為例,其實(shí)現(xiàn)包含軟件實(shí)現(xiàn)和硬件加速。所有的 3D 渲染請求都會經(jīng)過 Mesa 3D,它根據(jù)實(shí)際情況,選擇通過軟件或者硬件的方式響應(yīng)應(yīng)用程序的渲染請求。當(dāng)系統(tǒng)存在基于直接渲染基礎(chǔ)架構(gòu)(Direct Render Infrastructure,DRI)的硬件渲染機(jī)制時,Mesa 3D 會通過 OpenGL 的接口實(shí)現(xiàn) libGL-meas-DRI 調(diào)用DRI 提供的渲染功能。libGL-meas-DRI 會調(diào)用 libdrm,libdrm 會通過 ioctl 函數(shù)調(diào)用內(nèi)核態(tài)的 DRI 驅(qū)動,這里稱作直接渲染模塊(Direct Rendering Module,DRM),內(nèi)核中的 DRM 最終通過 GPU 完成渲染操作。
圖1 Linux 圖形顯示的基本流程
當(dāng) GPU 繪制完成后,結(jié)果以圖形緩存的形式返回給應(yīng)用程序,應(yīng)用程序?qū)⒔Y(jié)果提交給 Wayland compositor,Wayland compositor 提供顯示服務(wù),通過內(nèi)核模式設(shè)置(Kernel Mode Setting,KMS)確定顯示的分辨率及深度,最終將結(jié)果顯示在屏幕上。
具體到底層圖形接口本身,OpenGL 和 Vulkan 之間的特性又有差異。在使用 OpenGL 時,只需關(guān)心應(yīng)用層,因?yàn)?OpenGL 的驅(qū)動層設(shè)計(jì)十分臃腫復(fù)雜,對顯卡廠商來說渲染效果是未知的,同時 OpenGL 的錯誤管理機(jī)制一直處于激活狀態(tài),造成能耗的增加。Vulkan 對驅(qū)動層的設(shè)計(jì)更為精簡,將顯卡內(nèi)存的分配、釋放和內(nèi)存管理等操作交給應(yīng)用層,把更多的控制權(quán)限交給應(yīng)用層,雖然這種設(shè)計(jì)理念增加了在程序設(shè)計(jì)的復(fù)雜性,但卻降低了驅(qū)動層的負(fù)載,從而實(shí)現(xiàn)更高性能和更平衡的CPU 計(jì)算和 GPU 渲染的使用。OpenGL 和 Vulkan 工作方式如圖2 所示。
圖2 OpenGL 和 Vulkan 工作方式對比
OpenGL 與 Vulkan 在設(shè)計(jì)理念上的另一差別是對并行運(yùn)算的友好程度。早期的 OpenGL 不允許從一個以上的線程進(jìn)行渲染調(diào)用[5],不能良好地發(fā)揮多個 CPU核心執(zhí)行渲染指令的優(yōu)勢。在 OpenGL 誕生之初不是問題,因?yàn)楫?dāng)時的 CPU 都為單線程居多。現(xiàn)如今已是多核處理器的時代,如果應(yīng)用程序受 CPU 限制,這樣的設(shè)計(jì)會嚴(yán)重限制性能[6]。
3D 渲染指令包括綁定頂點(diǎn)緩沖區(qū)、綁定索引緩沖區(qū)、綁定著色器資源和發(fā)布基本體渲染的 API 函數(shù)。生成渲染指令是一項(xiàng) CPU 密集型任務(wù),應(yīng)該盡可能高效率地完成。在 OpenGL 中,渲染指令是同時生成和執(zhí)行的,不可能將它們分開。OpenGL 做法是使用 gl-DraweElements() 函數(shù)將渲染指令送到 GPU,然后立即執(zhí)行。由于開發(fā)工程師經(jīng)常希望控制渲染對象的順序,因此只能使用一個線程。而在 Vulkan 中,生成渲染指令和執(zhí)行它們之間有著明顯的區(qū)別。指令在指令緩沖區(qū)(Command Buffer)中生成,然后將這些指令緩沖區(qū)提交到指令隊(duì)列(Command Queen),僅在此時執(zhí)行,Vulkan 的多線程工作模式如圖3 所示。指令緩沖區(qū)可以由多個線程并行生成,這對于 Vulkan 提高多線程性能的能力很重要。
圖3 Vulkan 多線程工作模式
指令緩沖區(qū)在不同的線程中生成,然后提交到主線程中的指令隊(duì)列。主線程是實(shí)際執(zhí)行渲染指令的線程。執(zhí)行渲染指令是一種相對簡單的 CPU 操作,因此它可以從單個線程中完成而不會損失過多的性能,這與生成真正占用 CPU 的渲染指令不同。
為了進(jìn)一步探索 PKS 體系上的3D 圖形圖像顯示技術(shù),本節(jié)在 AMD 和 Nvidia 平臺上對 OpenGL 和 Vulkan 進(jìn)行基準(zhǔn)性能測試。
絕大多數(shù)比較 OpenGL 和 Vulkan 性能的基準(zhǔn)數(shù)據(jù)工具都是為 Android 和 Windows 平臺設(shè)計(jì),且沒有開源代碼,少數(shù)能在 ARM 加 Linux 平臺上運(yùn)行的游戲也不能同時支持 OpenGL 與 Vulkan,盡管如此,本項(xiàng)工作還是找到了 3 個開源跨平臺的基準(zhǔn)測工具。
3.1.1 OpenGL vs Vulkan
第一個基準(zhǔn)測試工具被稱為GL_vs_VK[7],通過繪制多個移動三角形、使用區(qū)域四叉樹細(xì)節(jié)層次 (Level of Detail,LOD) 技術(shù)渲染地形圖以及渲染陰影映射三個場景來執(zhí)行測試。該工具源代碼可以在文獻(xiàn)[7]中找到。
(1)測試1:移動三角形。如圖4 (a) 所示,該測試在屏幕上顯示了許多具有隨機(jī)顏色和速度的移動三角形,每個三角形都使用頂點(diǎn)緩沖區(qū)。測試1 為 OpenGL 和Vulkan 提供了單線程和多線程版本。可以控制在這個場景上繪制的三角形數(shù)量來改變 CPU 和 GPU 之間的工作量。本次測試執(zhí)行了二十萬個三角形的場景。
圖4 測試 1 至測試 4 的場景
(2)測試2:細(xì)節(jié)層次。一個 1 024×1 024 的高度圖地形被渲染為一個線框,如圖4 (b) 所示。這個實(shí)現(xiàn)包括每個頂點(diǎn)的頂點(diǎn)緩沖區(qū)。為了盡量模擬真實(shí)游戲場景,靠近玩家的區(qū)域在游戲中具有更多定義的細(xì)節(jié),而最遠(yuǎn)的對象則減少了定義。因此,靠近玩家的區(qū)域?qū)⒕哂懈叩姆直媛示W(wǎng)格,而最遠(yuǎn)的區(qū)域?qū)⒕哂休^低的分辨率。相機(jī)位于地圖角落上方的固定位置。同時,模擬玩家圍繞地圖中心繞圈移動,顯示網(wǎng)格變化。此外,地形以未填充三角形網(wǎng)格的形式繪制。
(3)測試3:陰影映射。這個測試陰影映射技術(shù)。該場景由一個棋盤地板組成,上面有深灰色和淺灰色的正方形,在地板上方繪制的立方體,以及一個位于棋盤中心的大球體,漂浮在圖4 (c) 所示的立方體上方。該場景具有固定光源,而攝像機(jī)的位置圍繞棋盤中心旋轉(zhuǎn),并且攝像機(jī)始終注視棋盤中心。該場景使用深度緩沖區(qū)的簡單動態(tài)陰影映射技術(shù)從相機(jī)的角度渲染陰影。
3.1.2 Vkmark 和 Glmark2
其他兩個基準(zhǔn)測試工具分別為測試 OpenGL 和Vulkan 的Glmark2[8]和 Vkmark[9]。Glmark2 包含著不同著色技術(shù)、折射、紋理等場景的測試。Vkmark 和 Glmark2 出自同一位工程師,有部分測試場景相同,因此實(shí)驗(yàn)僅對比相同的場景。下面對兩個測試工具相同的場景進(jìn)行描述。
(1)測試4:紋理。在該場景中繪制一個旋轉(zhuǎn)的立方體,并將紋理圖像應(yīng)用于對象的所有面,如圖4 (d) 所示。該測試將 2D 圖像應(yīng)用于立方體的每個面,并且使用線性過濾方法。
(2)測試5 至測試8:Gouraud、Phong、Blinn-Phong和 Cel 四種著色場景。這四個測試場景將不同光照模型應(yīng)用于 3D 圖像。Gouraud 著色涉及計(jì)算 3D 模型上每個頂點(diǎn)的法線向量,然后,跨多個多邊形計(jì)算表面插值以估計(jì)照明強(qiáng)度。在這個場景中,模型只應(yīng)用了漫反射照明。Phong 著色改進(jìn)了 Gouraud 著色模型,提供了更好的表面著色近似。這是通過在模型表面上為每個像素插入法線向量來完成,而不是在每個頂點(diǎn)之間插入顏色的 Gouraud 著色。此外,該模型還包含鏡面光照,因此這種方法的計(jì)算成本更高。Blinn-Phong 著色方法通過修改鏡面光照改進(jìn)了 Phong 著色模型。在 Phong照明模型上,計(jì)算相機(jī)與光源反射之間的角度并將其投影到模型上。Cel 著色是一種屬于非真實(shí)感渲染類的方法。本次測試場景呈現(xiàn)四種不同的綠色陰影。測試 5至測試8 的場景分別如圖5 (a)~圖5 (d) 所示。
圖5 測試5 至測試8 四種著色模型場景
本次實(shí)驗(yàn)在兩臺 PKS 終端機(jī)上進(jìn)行,單機(jī)共4 個CPU 核心,運(yùn)行內(nèi)存 32 GB,兩臺終端機(jī)分別搭載型號為 AMD Radeon 580 2048sp 和 Nvidia RTX 2080 Super兩塊圖形顯卡。實(shí)驗(yàn)環(huán)境軟硬件平臺的具體信息可參考表2。
表2 實(shí)驗(yàn)軟硬件平臺總結(jié)
實(shí)驗(yàn)首先使用 GL_vs_VK 工具在搭載 Nvidia RTX 2080 Super 和 AMD RX 580 2048sp 的 PKS 終端機(jī)上測試 OpenGL 和 Vulkan 的性能,共獲得兩組實(shí)驗(yàn)數(shù)據(jù),性能評價指標(biāo)是顯示幀率(Frames Per Second,F(xiàn)PS)。實(shí)現(xiàn)選擇 benchmark 模式,該模式先后運(yùn)行三個測試場景,每個場景持續(xù)測試15 s,實(shí)驗(yàn)結(jié)果輸出每個場景平均幀率。
圖6 和圖7 分別展示了 GL_vs_VK 工具在 Nvidia和 AMD 顯卡上的實(shí)驗(yàn)結(jié)果,由于不同場景的實(shí)驗(yàn)結(jié)果相差過大,縱坐標(biāo)采用指數(shù)形式展示。在單線程測試中的三個測試場景,Vulkan 顯示性能均優(yōu)于 OpenGL,Vulkan 的幀率是 OpenGL 的1.9 至2.4 倍。
圖6 GL_vs_VK 工具在 Nvidia 顯卡上對比實(shí)驗(yàn)結(jié)果
圖7 GL_vs_VK 工具在 AMD 顯卡上對比實(shí)驗(yàn)結(jié)果
在多線程測試中,OpenGL 和 Vulkan 均使用4 個線程進(jìn)行渲染,OpenGL 多線程版本只在移動三角形場景提供,相比單線程,多線程有著1.2 倍左右的提升,于此同時 Vulkan 提升效果更為明顯,性能提升范圍在1.5 至2.6 倍。圖8 為在4 線程模式下Vulkan 和 OpenGL 的使用率,可以看到,Vulkan 四個核心的使用率均在90% 左右,而 OpenGL 壓力都在 CPU 3 上,其他核心只大約占用了 20%。這個現(xiàn)象說明了多線程 Vulkan 相比于單線程更能調(diào)動處理器的性能從而提高渲染效率,而多線程OpenGL 提升性能并不明顯。
圖8 多線程模式下 Vulkan 和 OpenGL 的 CPU 使用率差異
圖9 展示了Glmark2 和Vkmark 基準(zhǔn)測試工具在AMD 平臺的的實(shí)驗(yàn)結(jié)果。實(shí)驗(yàn)結(jié)果包括五個場景,主要是測試紋理和著色的渲染能力??偟膩砜?,Vulkan 在本次實(shí)驗(yàn)結(jié)果均高于 OpenGL,Vulkan 的幀率是OpenGL 的1.8 至1.9 倍。
圖9 Glmark2 和 Vkmark 工具在 AMD 顯卡上對比實(shí)驗(yàn)結(jié)果
本文在 PKS 體系上開展了 3D 圖形圖像顯示的研究,深入研究了 OpenGL 和 Vulkan 兩種圖形庫的結(jié)構(gòu)、工作原理以及兩者的差異。采用了三種基準(zhǔn)測試工具和兩種品牌的顯卡在 PKS 終端機(jī)上對 OpenGL 和 Vulkan 進(jìn)行性能比較,為 PKS 體系未來的 3D 圖形圖像顯示技術(shù)發(fā)展提供重要參考。實(shí)驗(yàn)結(jié)果表明,在單線程模式下,Vulkan 的性能均優(yōu)于 OpenGL,在多線程模式下,Vulkan 的性能提高更加顯著,這是因?yàn)?OpenGL 將所有渲染操作集中于一個線程,而Vulkan 引入了 Command Buffer,每個線程可以向其提交渲染指令,充分發(fā)揮了多核處理器的優(yōu)勢,Vulkan 的特性更適合 PKS 體系未來3D 圖形圖像顯示技術(shù)的發(fā)展方向。