劉世豪 杜慧敏 黃虎才 王 可 盧 通
(西安郵電大學 西安 710121)
隨著計算機圖形學技術的快速發(fā)展,用戶對動畫、游戲開發(fā)、虛擬現(xiàn)實等圖形場景的真實感[1~3]的要求越來越高。紋理映射是GPU(Graphics Processing Unit,圖形處理器)實現(xiàn)逼真效果的重要方法[4~5]。
紋理單元是GPU 中實現(xiàn)紋理映射的模塊,可分為紋理前處理和紋理后處理,前處理部分讀取紋理數(shù)據(jù),包含紋理地址計算和紋理cache模塊,后處理部分過濾紋理數(shù)據(jù)后將數(shù)據(jù)輸出,包含紋理過濾和紋理數(shù)據(jù)輸出模塊。紋理單元接收SP(SIMT Processor,單指令多線程處理器)發(fā)來的紋理數(shù)據(jù)采樣請求,地址計算模塊根據(jù)紋理坐標計算出紋理數(shù)據(jù)的地址,再由地址訪問紋理cache,讀出紋理數(shù)據(jù),最后根據(jù)紋理采樣方式對紋理數(shù)據(jù)濾波處理,將過濾后的紋理數(shù)據(jù)返回給SP,紋理單元流水線如圖1所示。
基 于tile 渲 染 模 式(Tile-based Rendering,TBR)將一幀圖像劃分為多個tile[6~7],為提升圖像的渲染速度,通常采用多核并行渲染不同tile。當渲染的場景中存在大量重復紋理圖片時,如教室內(nèi)的課桌、草地、鳥群或軍隊等,不同tile 可能用相同的紋理進行貼圖。如圖2 所示,圖中每個tile 對應的紋理圖像都是兔子。
圖1 紋理單元流水線
圖2 重復貼圖的兔子
在基于tile 的GPU 設計中,對于只有一個紋理單元的架構,多個SP 同時訪問紋理單元。本文提出了固定處理模式與預處理模式兩種方法實現(xiàn)SP對紋理單元的訪問。其中,預處理模式可實現(xiàn)多個SP 用相同的紋理數(shù)據(jù)采樣請求,紋理單元只執(zhí)行一次操作,減少了紋理單元的功耗,提升了紋理映射的速度。本文用System Verilog 語言在VCS 環(huán)境下驗證了兩種方法,測試了4 類數(shù)據(jù)集。測試結果表明當存在大量重復紋理貼圖的情況下,本文提出的預處理方法能夠較好提升紋理映射性能。
紋理映射作為提升圖像真實感的重要處理方式,國內(nèi)外進行了深入的研究。
在紋理映射綜述方面,張英杰[8]等較早地介紹了紋理映射技術的發(fā)展歷史和紋理映射中的圖形反混淆算法,盧張平[9]等對紋理映射的算法進行分類,從二維紋理映射和三維紋理映射兩個大類分別進行闡述。曾成強[10]系統(tǒng)地總結紋理映射技術的發(fā)展歷史和紋理映射的幾種經(jīng)典算法,并比較了其中幾種算法的優(yōu)劣。
在紋理映射算法方面,謝豐等人采用mipmap濾波對凹凸映射進行優(yōu)化[11],在保證紋理凹凸感的前提下,減少了凹凸映射的計算量。Wanghai Qing等針對紋理數(shù)據(jù)大傳輸粒度導致CPU 無法訪問內(nèi)存和空轉的情況,提出了一種數(shù)據(jù)預取的方法[12],有效提升了渲染速度。杜慧敏和徐啟超等提出了采用線性逼近的方法實現(xiàn)各向同性逼近各項異性濾波器[13],該算法易于硬件實現(xiàn),且誤差較小。
在紋理映射架構方面董梁等提出一種實用型流水線設計結構[14],分析紋理單元的功能,并提出了一種紋理映射的設計方法,通過軟件進行了功能驗證。趙國宇等提出了一種高效紋理單元的硬件架構[15],采用查找表和二次多項式逼近算法優(yōu)化浮點除法運算,并且動態(tài)配置紋理cache的映射方式,優(yōu)化了紋理單元運算和存儲帶寬的性能。沈春江完成了紋理單元各模塊的設計,紋理載入速率達到了每秒30 幀[16]。韓立敏等提出了一種多模式并行處理硬件專用紋理引擎[17],并行實施多模式的紋理操作,顯著提升了紋理貼圖的執(zhí)行效率。
高分辨率的圖片意味著更真實的效果,但是會增加存儲容量,研究人員以減少數(shù)據(jù)大小和帶寬,同時以最小化視覺影響為目的提出各種紋理壓縮方案[18~19]?,F(xiàn)在常用的紋理壓縮格式有S3 公司發(fā)布 的S3TC(S3 Texture Compression),Imagination Technologies 公 司 發(fā) 布 的 PVRTC/PVRTC2(PowerVR Texture Compression),Khronos Group 組織發(fā)布的ETC/ETC2,ARM 公司發(fā)布的ASTC(Adaptive Scalable Texture Compression)等。不同存儲格式對紋理映射性能也會產(chǎn)生影響,可利用紋理數(shù)據(jù)的局部性提升紋理數(shù)據(jù)訪問效率[20]。Baokang Wang 等提出一種Z 型布局的存儲格式[21],縮小了地址跨度,減少了cache沖突缺失,紋理數(shù)據(jù)可根據(jù)紋理像素坐標將Z 型區(qū)域內(nèi)的地址設置為連續(xù)地址。
紋理單元實現(xiàn)了紋理映射復雜算法,在多核并行訪問紋理單元的情況下,若存在一種檢測機制,將多核發(fā)送的相同紋理數(shù)據(jù)采樣請求合并為一個請求,可減少紋理單元的執(zhí)行次數(shù),降低紋理單元功耗,并提升紋理映射的速度。業(yè)界對于紋理單元并行訪問機制的處理方法并沒有詳細的公開資料,而多核并行訪問紋理單元的預處理方法對紋理映射性能有很大提升,因此該方向的研究具有重要意義。
多個處理器核對應同一紋理單元的固定處理模式結構如圖3所示。設定8個SP對應1個紋理單元,當多個SP 同時訪問紋理單元時,紋理單元首先對多個請求進行仲裁,采用自適應輪詢調(diào)度算法選出當前優(yōu)先級最高的SP 請求。輪詢調(diào)度算法[22]設定每個SP 的優(yōu)先級相同,防止固定優(yōu)先級導致的低優(yōu)先級餓死情況。
圖3 固定處理模式結構
GPU 在處理圖像時,所有的SP 不是每拍都會同時發(fā)出請求,針對此類情況采用自適應輪詢調(diào)度算法。當全部SP同時發(fā)出請求時,第一拍執(zhí)行SP0請求,第二拍執(zhí)行SP1 請求,依次輪詢。但是由于SP執(zhí)行的tile場景可能不同,因此不一定全部SP同時發(fā)起紋理請求,如果當前拍只有SP1、SP2 和SP6訪問紋理單元,那么當前的優(yōu)先級為SP1→SP2→SP6,如果下一拍的請求為SP1、SP2、SP4 和SP6,那么當前優(yōu)先級為SP2→SP4→SP6→SP1。優(yōu)先級按照0-7 的順序依次輪詢,剛被執(zhí)行的SP 在下一拍的優(yōu)先級最低,當前拍的優(yōu)先級排序只在有紋理請求的SP中進行。
紋理單元對仲裁出的請求進行處理,當多個SP 訪問相同紋理坐標的情況,該模式仍然對每一個訪問請求進行處理,在單幀重復貼圖基數(shù)大的模型場景中,紋理單元會存在大量的重復性操作,導致功耗大并且處理內(nèi)容冗余。
3.2.1 預處理方法的基本思想
根據(jù)自適應輪詢調(diào)度算法確定當前SP 訪問請求的優(yōu)先級,當出現(xiàn)多個SP 的紋理采樣點相同時,合并相同紋理采樣請求,使紋理單元只執(zhí)行一次紋理數(shù)據(jù)采樣操作。預處理結構圖如圖4所示。
預處理方法是在紋理單元的前處理部分(Tex_pre_process 模塊)增加外圍電路,包括Arbiter模塊、Req_buf 模塊和Data_buf 模塊。預處理方法通過兩次比較解決了同一時刻和某段時間內(nèi)出現(xiàn)相同紋理數(shù)據(jù)采樣請求的情況,減少了紋理單元重復冗余的操作。
圖4 預處理結構圖
3.2.2 各模塊功能及處理流程
1)發(fā)出采樣請求
圖中各個SP用于渲染不同tile內(nèi)場景,SP下發(fā)紋理映射請求給Arbiter模塊,請求數(shù)據(jù)包含紋理映射的狀態(tài)信息(如紋理坐標、SP 的ID、每個SP 的請求ID、紋理圖片大小、紋理數(shù)組使能和陰影貼圖使能等)。
2)仲裁并處理采樣請求
Arbiter 模塊接收各個SP 發(fā)來的紋理映射請求,根據(jù)自適應輪詢調(diào)度算法得到當前拍優(yōu)先級最高的SP請求,并送給Req_buf模塊。
Arbiter模塊將優(yōu)先級最高的SP請求與其他SP請求進行比較,如果紋理坐標相等,說明同一拍中不同SP 有相同的紋理數(shù)據(jù)采樣請求,這里規(guī)定其他的紋理數(shù)據(jù)采樣請求為副本請求。當前節(jié)拍仲裁出的紋理請求經(jīng)Req_buf送給Tex_pre_process模塊,然后通過Data_buf,再由Tex_post_process 模塊把采樣點處的紋理數(shù)據(jù)送給Arbiter 模塊。優(yōu)先級最高的紋理請求和所有副本請求對應的SP 都接收該次采樣的紋理數(shù)據(jù),上述處理過程如圖5所示。
圖5 合并相同SP請求示意圖
Arbiter 模塊解決了同一拍中多個SP 的紋理數(shù)據(jù)采樣請求相同的問題,并行地將紋理數(shù)據(jù)返回給所有發(fā)出相同紋理坐標請求的SP。
3)緩存不同紋理數(shù)據(jù)采樣請求
Req_buf 模塊接收Arbiter 模塊發(fā)送的紋理數(shù)據(jù)采樣請求,并緩存最近n 次無副本請求的紋理坐標。Req_buf深度為n,緩存的數(shù)據(jù)為紋理坐標。
Req_buf每接收到一個新請求都會與其內(nèi)部緩存的舊請求進行坐標比較,如果新請求的坐標和Req_buf 某行存儲的紋理坐標不相同,則緩存本次新請求,并且將新請求發(fā)送給Tex_pre_process模塊讀取紋理數(shù)據(jù)。如果新請求和Req_buf 某行存儲的紋理坐標相同,說明在n 次訪問內(nèi)已經(jīng)讀取了該紋理坐標對應的數(shù)據(jù),那么本次的請求無需發(fā)送給Tex_pre_process 模塊,將紋理坐標直接發(fā)送到Data_buf,讀取該坐標對應行的數(shù)據(jù),比較方式如圖6所示。
當buffer 內(nèi)數(shù)據(jù)存滿并且新的紋理請求與buffer 中任意一行不匹配,則采用先入先出的替換策略,替換n行中最先存入buffer的數(shù)據(jù),如圖7所示。
圖7 替換策略
4)讀取紋理數(shù)據(jù)
Tex_pre_process 模塊實現(xiàn)紋理數(shù)據(jù)讀取功能。該模塊接收紋理采樣請求,在經(jīng)過紋理地址計算和讀取紋理cache數(shù)據(jù)后得到對應坐標的紋理數(shù)據(jù),將紋理數(shù)據(jù)和紋理坐標送給Data_buf。
5)緩存紋理坐標與紋理數(shù)據(jù)
Data_buf 每一行存放的數(shù)據(jù)為紋理坐標和紋理數(shù)據(jù)。Data_buf深度為n,當buffer數(shù)據(jù)存滿時采用先入先出的替換策略。
Data_buf 將Tex_pre_process 模塊輸出的紋理坐標和數(shù)據(jù)緩存到buffer 內(nèi),然后將接收到的紋理數(shù)據(jù)送給Tex_post_process 模塊。并且Data_buf 會與Req_buf 發(fā)送的坐標進行匹配,為未經(jīng)過Tex_pre_process 模塊處理的請求讀取數(shù)據(jù),如果坐標命中,將相應buffer 行的數(shù)據(jù)送給Tex_post_process 模塊,如果坐標未命中,則將該坐標存入Data_buf中的失靶buffer中,Data_buf每接收一組紋理坐標與數(shù)據(jù)都會與失靶buffer 中的坐標進行匹配,直到讀出紋理數(shù)據(jù)。
6)紋理后處理
Tex_post_process 模塊根據(jù)紋理映射模式對紋理數(shù)據(jù)進行過濾和格式轉換等操作,由該模塊得到采樣點處紋理數(shù)據(jù),然后輸出給Arbiter模塊。
本文對紋理映射的兩種方法進行抽象,將方法一與方法二的性能進行比較。在存在大量重復紋理圖像的場景中,量化地統(tǒng)計方法二相較于方法一的性能提升比率。
采用System verilog 進行建模,在VCS 平臺仿真,時鐘頻率為100MHz,測試數(shù)據(jù)2048個,每個SP對應16*16的像素塊,處理256個數(shù)據(jù),不同測試集下預處理方法的速率提升結果如表1所示。
表1 預處理模式的性能提升比率
A 類測試集:16*16的像素塊內(nèi)貼4個8*8的紋理圖像,每個SP隨機發(fā)送紋理坐標。
B 類測試集:16*16 的像素塊內(nèi)貼16 個4*4 的紋理圖像,每個SP隨機發(fā)送紋理坐標。
C 類測試集:16*16 的像素塊內(nèi)貼64 個2*2 的紋理圖像,每個SP隨機發(fā)送紋理坐標。
D 類測試集:8 個SP 向Arbiter 模塊發(fā)送紋理請求,每個發(fā)送256個,每個SP發(fā)送的紋理坐標相同。
紋理映射是圖形渲染管線中極其重要的一部分,它是圖像真實性的有效保證,性能優(yōu)越的紋理單元不僅能夠保障圖像的真實性,也能提升紋理映射的處理速度。對于多核并行訪問紋理單元的架構,應該根據(jù)渲染圖像的特點,合并相同的紋理數(shù)據(jù)采樣請求,減少紋理單元的冗余操作,本文據(jù)此提出了一種多核并行訪問紋理單元的預處理方法,對預處理模式的各個模塊進行介紹,核心思路為采用兩次比較的方式減少了冗余操作,提升了紋理單元的性能。實驗結果表明,在存在大量重復紋理貼圖的情況下,能夠較好提升紋理映射性能。