在上一篇文章中,我談到了GPU架構(gòu)的工作原理。這是一個(gè)比較新穎的架構(gòu),與其他架構(gòu)的工作方式不太相同,我們稱(chēng)之為基于區(qū)塊貼圖的延遲渲染或TBDR。從概念而言,其基本前提非常簡(jiǎn)單。
首先,我們把屏幕分成小的區(qū)塊,使之操作簡(jiǎn)單且大小適于完全放在GPU上,大量減少訪(fǎng)問(wèn)內(nèi)存。這部分我先做闡釋?zhuān)皇煜ご瞬糠值恼?qǐng)先行了解。
第二部分需使用第一部分生成的信息——渲染貼圖的原語(yǔ)列表——盡可能多地延遲隨后生成的像素,所以渲染盡量不會(huì)放過(guò)每個(gè)細(xì)節(jié)之處。讓我們先來(lái)看看硬件的工作。
TBDR上的數(shù)據(jù)報(bào)告:PowerVR Rogue的延遲渲染
參數(shù)緩沖區(qū)
在我的上一篇文章中提到,硬件所需完成的最后一件事便是填滿(mǎn)參數(shù)緩沖區(qū)(PB)?;仡櫼幌拢琍B本質(zhì)上是一個(gè)打包的區(qū)塊貼圖列表,填充了形成貼圖的轉(zhuǎn)換幾何圖,硬件同樣可以對(duì)其進(jìn)行有效的計(jì)算。記住,我們不必使用簡(jiǎn)單且效率低下的方法來(lái)計(jì)算究竟是哪個(gè)幾何對(duì)象構(gòu)成了貼圖。實(shí)際上,我們可以準(zhǔn)確地計(jì)算貼圖,因而不必要浪費(fèi)時(shí)間處理那些最終不會(huì)對(duì)貼圖產(chǎn)生影響的原語(yǔ)。
因此,GPU建立了中間數(shù)據(jù)結(jié)構(gòu),并具有完整的三角形列表。接下來(lái)便是光柵化,,并把那些三角形變成像素,且在內(nèi)核中對(duì)像素進(jìn)行著色。對(duì)于我們的架構(gòu)而言,光柵化尤為復(fù)雜:驅(qū)動(dòng)GPU效率的關(guān)鍵事物投射在這部分管道中,接下來(lái)讓我們逐步了解相關(guān)過(guò)程。
另外,一些讀者可能會(huì)很驚訝地發(fā)現(xiàn),光柵化并不僅僅發(fā)生在一個(gè)簡(jiǎn)單的稱(chēng)之為光柵格的單片上。在所有GPU中,無(wú)論大小,都是由許多子塊組成的比較緊湊的面向數(shù)據(jù)流的管道在運(yùn)行。使之在不成為影響吞吐量的瓶頸下保持平衡則非常困難,且由于任務(wù)的性質(zhì),固定功能邏輯比可編程著色器內(nèi)核更加合適。
提取PB數(shù)據(jù)至內(nèi)核中
首先,我們需要從內(nèi)存中提取貼圖列表至內(nèi)核中,然后解析他們的狀態(tài)、位置數(shù)據(jù)和一些控制位,使GPU可以恰當(dāng)?shù)倪\(yùn)行幾何對(duì)象。數(shù)據(jù)可以被壓縮,所以區(qū)塊負(fù)責(zé)讀取數(shù)據(jù),即我們所說(shuō)的參數(shù)獲取,其也能解壓數(shù)據(jù)。由于區(qū)塊存在內(nèi)存訪(fǎng)問(wèn),一些獲取內(nèi)存延遲的情況必須容許,所以可以從內(nèi)存中預(yù)讀取及突發(fā)讀取數(shù)據(jù),使PB中的數(shù)據(jù)可以再次進(jìn)入內(nèi)核中。目前為止,一切很順利。
邊緣方程
既然我們已經(jīng)把三角形放置在內(nèi)核中,接下來(lái)便是將它們變成像素。注意,我們是在3D而非2D空間處理幾何對(duì)象,而您的屏幕是一個(gè)2D平面。所以我們需要采取某種方式,將渲染的3D計(jì)算視圖映射到2D屏幕上。
接受來(lái)自參數(shù)提取物的原語(yǔ)的硬件字節(jié),在柵格化像素的過(guò)程中負(fù)責(zé)設(shè)置定義三角形邊界的三角方程,因此我們?cè)谄聊簧峡吹降牟粌H僅是點(diǎn),還有三角形的呈現(xiàn)。由于涉及到一些計(jì)算,硬件字節(jié)在固定的設(shè)置下有其專(zhuān)用且實(shí)際上非常復(fù)雜的浮點(diǎn)單元。
接下來(lái)便是三角形的邊界計(jì)算方程。三角形共享準(zhǔn)確深度值時(shí),深度偏置可以起作用。這樣便不必糾結(jié)于哪個(gè)邊界應(yīng)該可視化,且一些角度的計(jì)算可以為進(jìn)一步形成的區(qū)塊提供有關(guān)幾何圖像構(gòu)成的信息。
平面方程
有了一組邊界方程,便可結(jié)合邊界方程定義三角幾何,猶如3D空間中的三棱鏡。在頭腦中想象圖像可能有違直覺(jué),因?yàn)槟鷱奈凑嬲催^(guò)其3D效果。您需要一些想象的線(xiàn)條來(lái)構(gòu)建可視化的圖像。
其次,需要一個(gè)穿過(guò)棱鏡的2D切片,這樣當(dāng)三角形的2D效果呈現(xiàn)在屏幕上時(shí),可以基本拉平圖像,并找出棱鏡的字節(jié)。這是一個(gè)重要的里程碑。要實(shí)現(xiàn)上述過(guò)程,便需要一個(gè)四階方程來(lái)定義通過(guò)棱鏡的平面片,而棱鏡則由邊界方程定義。
在硬件中評(píng)估四階方程,其給出的平面片可以映射到貼圖的像素中。接下來(lái)對(duì)屏幕貼圖做一些闡述以助于理解此部分內(nèi)容。
貼圖大小
任何貼圖架構(gòu)都要在貼圖大小和存儲(chǔ)空間之間進(jìn)行一些權(quán)衡。在我們的案例中,我們需要一些用于參數(shù)緩沖區(qū)的存儲(chǔ)空間來(lái)儲(chǔ)存貼圖的三角形列表。而這個(gè)存儲(chǔ)空間位于系統(tǒng)內(nèi)存中。其次,還需要GPU芯片內(nèi)的存儲(chǔ)空間,用于處理貼圖中的像素。
因此對(duì)于這兩個(gè)貼圖理論上的尺寸,一個(gè)貼圖是另一個(gè)的四倍 (兩倍X軸和兩倍Y軸),且渲染分辨率是1080 p。顯然,如果尺寸較小,則需要較多的貼圖,這意味著參數(shù)緩沖區(qū)中需要有更多的貼圖列表,但可與貼圖交叉的三角形則更少,因此所需GPU存儲(chǔ)也更小。反之亦然。我們只需較少的貼圖列表,因?yàn)橘N圖不可能足夠多,但每個(gè)貼圖的三角形平均數(shù)量則可能會(huì)增多,且由于每個(gè)貼圖是像素的4倍,因此需要4倍的GPU存儲(chǔ)空間。
所以,在我們的架構(gòu)中,貼圖的尺寸趨于偏小。John和他的團(tuán)隊(duì)在計(jì)算最優(yōu)尺寸時(shí)則考慮的更多,但尺寸等都是最大的考慮因素。目前,Rogue上用于一般渲染的像素是32×32,但其比起過(guò)去在SGX上的渲染像素要更小,且架構(gòu)也非方形矩陣。
多重采樣
在一般渲染時(shí),還需考慮一件事情:多重采樣。這里不對(duì)MSAA作全面介紹——以后發(fā)表的文章中將會(huì)詳述——但它卻可以提高圖像質(zhì)量,因?yàn)樗瘸R?guī)的渲染(通常為一個(gè)像素)所生成的像素樣品更多,且使用這些額外的數(shù)據(jù)可以在樣品中濾除圖像中的高頻信號(hào)。
因此如果為每個(gè)像素生成的數(shù)據(jù)更多,我們需要相應(yīng)的存儲(chǔ)空間。幾個(gè)方式可以嘗試。一個(gè)是在系統(tǒng)內(nèi)存中存儲(chǔ)額外的樣品;另一個(gè)是使用GPU存儲(chǔ),這樣在處理MSAA時(shí)便不需要消耗非GPU帶寬。
采用第二種方式時(shí),在GPU中為多重采樣數(shù)據(jù)分配一些存儲(chǔ),以提高效率及降低外部?jī)?nèi)存帶寬。存儲(chǔ)的形式不在本文討論范圍之內(nèi),但顯然這應(yīng)該著色器內(nèi)核的一部分,這樣USC便可以迅速對(duì)之訪(fǎng)問(wèn)。
實(shí)際柵格化
回到我們之前討論的柵格化。每個(gè)區(qū)塊貼圖中的三角形都會(huì)生成一個(gè)邊界方程,我們?cè)诤铣蓤D像處理器(ISP)中對(duì)這些邊界方程和平面方程進(jìn)行共同評(píng)估。ISP是GPU設(shè)計(jì)的核心,因?yàn)橛辛薎SP,延期渲染才得以進(jìn)行。
評(píng)估方程后,對(duì)貼圖中每個(gè)像素樣品位置的三角形顯示結(jié)果進(jìn)行測(cè)試(或如果是多重采樣,則對(duì)采樣位置進(jìn)行測(cè)試),看看哪些像素位于即將產(chǎn)生的三角形內(nèi)。這時(shí),我們才最終完成柵格化:通過(guò)評(píng)估邊界方程且對(duì)貼圖像素的結(jié)果進(jìn)行測(cè)試后,使三角形形成2D圖像,這樣便知道其覆蓋的屏幕區(qū)域。
消除隱藏面
消除隱藏面才意味著GPU開(kāi)始真正地節(jié)約效率。貼圖操作把屏幕分成很多適宜于GPU的小字節(jié),這樣,既可將數(shù)據(jù)儲(chǔ)存在GPU上,又可以在運(yùn)行數(shù)據(jù)時(shí)避免過(guò)多消耗且保證內(nèi)存訪(fǎng)問(wèn)時(shí)功率充足。但我們還可以做到更極致。
在進(jìn)行像素柵格化時(shí),對(duì)其在深度緩沖區(qū)中的深度(在圖表中用Z表示)進(jìn)行了測(cè)試。如果深度測(cè)試(通常是“是否比深度緩沖區(qū)像素位置最后的值更接近屏幕?”)通過(guò),則用最新的像素值更新深度緩沖區(qū),且將數(shù)據(jù)“此三角形中的此像素形成了貼圖”進(jìn)行存儲(chǔ)。
可以想象,這一處理的結(jié)果是一組貼圖數(shù)據(jù),且僅對(duì)通過(guò)了深度測(cè)試的可見(jiàn)像素進(jìn)行編碼。這里再重點(diǎn)強(qiáng)調(diào)一遍。處理的結(jié)果是一組貼圖數(shù)據(jù),且僅有通過(guò)深度測(cè)試的可見(jiàn)像素才進(jìn)行編碼。
處理過(guò)程中節(jié)約效率尤為重要。我們可以在GPU工作之前預(yù)先捕獲給定渲染的繪制調(diào)用。在其他GPU中,驅(qū)動(dòng)器將發(fā)送命令到GPU,使之盡快在應(yīng)用程序中完成繪制調(diào)用。它不會(huì)在乎前一個(gè)或接下來(lái)的繪制是什么。但在命令較多的時(shí)候,知曉前后繪制調(diào)用的內(nèi)容便可以大量節(jié)省功率。嘗試及避免在其他架構(gòu)上工作的傳統(tǒng)方式類(lèi)似于這種情況,即在像素渲染前便已完成深度測(cè)試。但是測(cè)試往往不如我們測(cè)試像素這般精準(zhǔn)。
在給GPU輸送命令之前,我們啟用所有影響給定緩沖區(qū)的繪制調(diào)用。這個(gè)過(guò)程可以讓我們獲取影響緩沖區(qū)渲染的所有幾何對(duì)象,使我們可以完成貼圖和HSR,盡可能避免多余的工作。
對(duì)于非透明的幾何對(duì)象,這種方式非常有效,文末將對(duì)此進(jìn)行簡(jiǎn)要介紹。
透明度
顯然,當(dāng)透明物體被擋后,ISP需要克服障礙。我們處理透明度的方法相當(dāng)簡(jiǎn)單,即節(jié)省效率。當(dāng)透明的物體從先前的區(qū)塊中進(jìn)入ISP時(shí),我們可以有效地停止操作,直接沖刷所有通過(guò)深度測(cè)試的像素進(jìn)入著色器內(nèi)核。為何?因?yàn)槲覀兛梢栽陧旤c(diǎn)對(duì)透明物進(jìn)行混合,我們所需了解的是混合值。
所以,我們清空ISP進(jìn)入U(xiǎn)SC(或SGX中的USSE),對(duì)所有阻擋物體的可見(jiàn)非透明阻擋物進(jìn)行渲染,并使用最終像素值更新緩沖區(qū),這樣我們便可以在頂點(diǎn)混合。到這一步先稍安勿躁,先看看接下來(lái)進(jìn)入ISP的對(duì)象是什么,因?yàn)槲覀冃枰S持API提交順序,以滿(mǎn)足所有當(dāng)前的API規(guī)范。
如果一個(gè)透明物進(jìn)入后,再次進(jìn)入另一個(gè)透明物,我們需再次沖刷以確保正確的渲染。不管非透明對(duì)象如何覆蓋所有透明對(duì)象,只要通過(guò)深度測(cè)試,便不影響繼續(xù)操作。
因此要確定沖刷對(duì)效率的損失有多少,取決于何種渲染物以何種順序完成渲染。立即模式渲染值得一提:它們從不在意渲染的類(lèi)型,并一直在消耗帶寬的情況下進(jìn)行混合。但我們的架構(gòu)旨在盡可能節(jié)省成本,我們要做的是一個(gè)權(quán)衡了原始性能的產(chǎn)品。
所以你還未曾見(jiàn)過(guò)我們的開(kāi)發(fā)人員推薦文件,但最后會(huì)要求開(kāi)發(fā)人員公開(kāi)相關(guān)文件。
并行性
這里我要講一點(diǎn)有關(guān)并行性的內(nèi)容。由于我們操作貼圖,而貼圖通常是獨(dú)立儲(chǔ)存,可以想象要在硬件層進(jìn)行并行處理理論上來(lái)說(shuō)是非?,嵥榈氖虑椤6鳵ogue配置了兩個(gè)前端。我們讓一個(gè)在列表中分配貼圖的前端控制器處于并行工作狀態(tài),然后再同時(shí)關(guān)閉,完成上述描述的整個(gè)流程。
節(jié)省了什么?
總結(jié)一句,HSR部分是我們?cè)诩軜?gòu)中節(jié)省效率最大的一部分。但保存至芯片且僅處理可見(jiàn)像素到底節(jié)省了什么?首先,所有的紋理和目標(biāo)在像素渲染過(guò)程中要渲染緩沖出入口帶寬,渲染這些像素時(shí)會(huì)引起消耗。像素渲染將紋理作為輸入,并需要在最后編寫(xiě)最終值。而對(duì)于延遲渲染,我們可以創(chuàng)建和使用芯片上的整個(gè)G-buffer區(qū) (如果它適合每個(gè)像素空間)且沒(méi)有外部?jī)?nèi)存訪(fǎng)問(wèn)。
我們還保留了所有在ISP中舍棄的像素的渲染運(yùn)算操作:現(xiàn)代著色器有數(shù)以百計(jì)的周期,USC是設(shè)計(jì)中消費(fèi)功率的最大部分。最重要的是,USC在運(yùn)行著色程序時(shí),還需要在最后一個(gè)值寫(xiě)入貼圖內(nèi)存之前讀寫(xiě)其內(nèi)部寄存器來(lái)存儲(chǔ)中間值。而注冊(cè)訪(fǎng)問(wèn)則消耗內(nèi)部寄存器文件的帶寬和大量的功率。
因此,潛在成百上千的ALU操作和寄存器讀寫(xiě),而這些本是不必要的。為像素點(diǎn)亮USC才形成最終看到的畫(huà)面。相比同類(lèi)產(chǎn)品,我們最大的優(yōu)勢(shì)很大程度上是由于這種由ISP驅(qū)動(dòng)的機(jī)制及運(yùn)用各層級(jí)管道來(lái)實(shí)現(xiàn)的。
在我們使用GPU的產(chǎn)品中,功率優(yōu)勢(shì)對(duì)于您使用手機(jī)、電腦或智能手表時(shí)的體驗(yàn)尤為重要。實(shí)際上,任何設(shè)備均需要強(qiáng)大有效且可以最佳利用電池的GPU。
評(píng)論