Metal框架詳細(xì)解析(二十一) —— 基本課程之基本緩沖區(qū)(一)

版本記錄

版本號 時間
V1.0 2018.10.08 星期一

前言

很多做視頻和圖像的,相信對這個框架都不是很陌生憋肖,它渲染高級3D圖形因痛,并使用GPU執(zhí)行數(shù)據(jù)并行計算。接下來的幾篇我們就詳細(xì)的解析這個框架岸更。感興趣的看下面幾篇文章鸵膏。
1. Metal框架詳細(xì)解析(一)—— 基本概覽
2. Metal框架詳細(xì)解析(二) —— 器件和命令(一)
3. Metal框架詳細(xì)解析(三) —— 渲染簡單的2D三角形(一)
4. Metal框架詳細(xì)解析(四) —— 關(guān)于GPU Family 4(一)
5. Metal框架詳細(xì)解析(五) —— 關(guān)于GPU Family 4之關(guān)于Imageblocks(二)
6. Metal框架詳細(xì)解析(六) —— 關(guān)于GPU Family 4之關(guān)于Tile Shading(三)
7. Metal框架詳細(xì)解析(七) —— 關(guān)于GPU Family 4之關(guān)于光柵順序組(四)
8. Metal框架詳細(xì)解析(八) —— 關(guān)于GPU Family 4之關(guān)于增強(qiáng)的MSAA和Imageblock采樣覆蓋控制(五)
9. Metal框架詳細(xì)解析(九) —— 關(guān)于GPU Family 4之關(guān)于線程組共享(六)
10. Metal框架詳細(xì)解析(十) —— 基本組件(一)
11. Metal框架詳細(xì)解析(十一) —— 基本組件之器件選擇 - 圖形渲染的器件選擇(二)
12. Metal框架詳細(xì)解析(十二) —— 基本組件之器件選擇 - 計算處理的設(shè)備選擇(三)
13. Metal框架詳細(xì)解析(十三) —— 計算處理(一)
14. Metal框架詳細(xì)解析(十四) —— 計算處理之你好,計算(二)
15. Metal框架詳細(xì)解析(十五) —— 計算處理之關(guān)于線程和線程組(三)
16. Metal框架詳細(xì)解析(十六) —— 計算處理之計算線程組和網(wǎng)格大性醮丁(四)
17. Metal框架詳細(xì)解析(十七) —— 工具谭企、分析和調(diào)試(一)
18. Metal框架詳細(xì)解析(十八) —— 工具廓译、分析和調(diào)試之Metal GPU Capture(二)
19. Metal框架詳細(xì)解析(十九) —— 工具、分析和調(diào)試之GPU活動監(jiān)視器(三)
20. Metal框架詳細(xì)解析(二十) —— 工具债查、分析和調(diào)試之關(guān)于Metal著色語言文件名擴(kuò)展名非区、使用Metal的命令行工具構(gòu)建庫和標(biāo)記Metal對象和命令(四)

Basic Buffers - 基本緩沖區(qū)

演示如何使用頂點緩沖區(qū)管理數(shù)百個頂點。

Hello Triangle示例中攀操,您學(xué)習(xí)了如何在Metal中渲染基本幾何體院仿。

在此示例中秸抚,您將學(xué)習(xí)如何使用頂點緩沖區(qū)來提高渲染效率速和。 特別是,您將學(xué)習(xí)如何使用頂點緩沖區(qū)來存儲和加載多個四邊形的頂點數(shù)據(jù)剥汤。


Manage Large Amounts of Vertex Data - 管理大量的頂點數(shù)據(jù)

Hello Triangle示例中颠放,示例呈現(xiàn)三個頂點,每個頂點32個字節(jié)吭敢,相當(dāng)于96個字節(jié)的頂點數(shù)據(jù)碰凶。通過調(diào)用setVertexBytes:length:atIndex:方法將少量頂點數(shù)據(jù)發(fā)送到頂點函數(shù)。此方法分配了圖形處理單元(GPU)可訪問的少量內(nèi)存鹿驼,并且可以在每個幀中分配欲低,而不會產(chǎn)生明顯的性能成本。

Hello Triangle示例不同畜晰,此示例渲染了2,250個頂點砾莱,每個頂點32個字節(jié),相當(dāng)于72,000個字節(jié)的頂點數(shù)據(jù)凄鼻。需要更有效地管理該頂點數(shù)據(jù)量腊瑟。事實上,對于超過4千字節(jié)(4,096字節(jié))的頂點數(shù)據(jù)块蚌,Metal不允許使用setVertexBytes:length:atIndex:方法闰非。更重要的是,不應(yīng)在每個幀中重新分配和復(fù)制頂點數(shù)據(jù)峭范。

通常财松,Metal應(yīng)用程序或游戲會繪制具有數(shù)千個頂點的模型,每個頂點都有多個頂點屬性纱控,這些頂點屬性消耗幾兆字節(jié)的內(nèi)存游岳。為了使這些應(yīng)用程序或游戲能夠很好地擴(kuò)展并進(jìn)行有效管理,Metal提供了由MTLBuffer對象表示的專用數(shù)據(jù)容器其徙。這些緩沖區(qū)是GPU可訪問的內(nèi)存分配胚迫,用于存儲多種自定義數(shù)據(jù),盡管它們通常用于頂點數(shù)據(jù)唾那。此示例分配大量頂點數(shù)據(jù)一次访锻,將其復(fù)制到MTLBuffer對象中褪尝,然后在每個幀中重用頂點數(shù)據(jù)。


Allocate, Generate, and Copy Vertex Data - 分配期犬,生成和復(fù)制頂點數(shù)據(jù)

在Objective-C中河哑,字節(jié)緩沖區(qū)由NSDataNSMutableData對象包裝,使用起來既安全又方便龟虎。 AAPLVertex數(shù)據(jù)類型用于樣本中的每個頂點璃谨,每個四邊形由6個這些頂點值組成(每個四邊形有兩個三角形)。 30 x 20網(wǎng)格的四邊形共計3,600個頂點鲤妥,占用115,200字節(jié)的內(nèi)存佳吞,即為樣本的頂點數(shù)據(jù)分配的數(shù)量。

const AAPLVertex quadVertices[] =
{
    // Pixel positions, RGBA colors
    { { -20,   20 },    { 1, 0, 0, 1 } },
    { {  20,   20 },    { 0, 0, 1, 1 } },
    { { -20,  -20 },    { 0, 1, 0, 1 } },

    { {  20,  -20 },    { 1, 0, 0, 1 } },
    { { -20,  -20 },    { 0, 1, 0, 1 } },
    { {  20,   20 },    { 0, 0, 1, 1 } },
};
const NSUInteger NUM_COLUMNS = 25;
const NSUInteger NUM_ROWS = 15;
const NSUInteger NUM_VERTICES_PER_QUAD = sizeof(quadVertices) / sizeof(AAPLVertex);
const float QUAD_SPACING = 50.0;

NSUInteger dataSize = sizeof(quadVertices) * NUM_COLUMNS * NUM_ROWS;
NSMutableData *vertexData = [[NSMutableData alloc] initWithLength:dataSize];

通常棉安,Metal應(yīng)用程序或游戲會加載模型文件中的頂點數(shù)據(jù)底扳。 模型加載代碼的復(fù)雜性因模型而異,但最終頂點數(shù)據(jù)也存儲在傳遞給Metal代碼的字節(jié)緩沖區(qū)中贡耽。 為避免引入模型加載代碼衷模,此示例使用generateVertexData方法模擬頂點數(shù)據(jù)切換,該方法在運(yùn)行時生成簡單的頂點數(shù)據(jù)蒲赂。

NSDataMTLBuffer對象都存儲自定義數(shù)據(jù)阱冶,這意味著您的應(yīng)用程序負(fù)責(zé)在讀取或?qū)懭氩僮髌陂g正確定義和解釋此數(shù)據(jù)。 在此示例中滥嘴,頂點數(shù)據(jù)是只讀的木蹬,其內(nèi)存布局由AAPLVertex數(shù)據(jù)類型定義,這是vertexShader頂點函數(shù)所需的氏涩。

vertex RasterizerData
vertexShader(uint vertexID [[ vertex_id ]],
             device AAPLVertex *vertices [[ buffer(AAPLVertexInputIndexVertices) ]],
             constant vector_uint2 *viewportSizePointer  [[ buffer(AAPLVertexInputIndexViewportSize) ]])

從根本上說届囚,NSDataMTLBuffer對象都非常相似。 但是是尖,MTLBuffer對象是GPU可訪問的專用容器意系,使圖形渲染管道能夠從中讀取頂點數(shù)據(jù)。

NSData *vertexData = [AAPLRenderer generateVertexData];

// Create a vertex buffer by allocating storage that can be read by the GPU
_vertexBuffer = [_device newBufferWithLength:vertexData.length
                                     options:MTLResourceStorageModeShared];

// Copy the vertex data into the vertex buffer by accessing a pointer via
// the buffer's `contents` property
memcpy(_vertexBuffer.contents, vertexData.bytes, vertexData.length);

首先饺汹,newBufferWithLength:options:方法創(chuàng)建一個具有特定字節(jié)大小和某些訪問選項的新MTLBuffer對象蛔添。 頂點數(shù)據(jù)占用115,200字節(jié)的內(nèi)存(vertexData.length),由CPU寫入并由GPU讀取(MTLResourceStorageModeShared)兜辞。

其次迎瞧,memcpy()函數(shù)將頂點數(shù)據(jù)從源NSData對象復(fù)制到目標(biāo)MTLBuffer對象。 _vertexBuffer.contents查詢返回指向緩沖區(qū)內(nèi)存的CPU可訪問指針逸吵。 頂點數(shù)據(jù)通過指向源數(shù)據(jù)(vertexData.bytes)的指針和要復(fù)制的指定數(shù)據(jù)量(vertexData.length)復(fù)制到此目標(biāo)凶硅。


Set and Draw Vertex Data - 設(shè)置和繪制頂點數(shù)據(jù)

由于樣本的頂點數(shù)據(jù)現(xiàn)在存儲在MTLBuffer對象中,因此無法再調(diào)用setVertexBytes:length:atIndex:方法扫皱;而調(diào)用setVertexBuffer:offset:atIndex:方法足绅。 此方法將頂點緩沖區(qū)捷绑,與該緩沖區(qū)中的頂點數(shù)據(jù)的字節(jié)偏移量以及將緩沖區(qū)映射到頂點函數(shù)的索引作為參數(shù)。

注意:使用MTLBuffer作為頂點函數(shù)參數(shù)不會阻止應(yīng)用或游戲使用setVertexBytes:length:atIndex:方法為另一個參數(shù)設(shè)置數(shù)據(jù)氢妈。 實際上粹污,此示例仍使用Hello Triangle示例中引入的viewportSizePointer參數(shù)。

最后首量,通過發(fā)出一個從數(shù)組中的第一個頂點array (0)開始并最后一個(_numVertices)結(jié)束的繪制調(diào)用來繪制所有頂點壮吩。

[renderEncoder setVertexBuffer:_vertexBuffer
                        offset:0
                       atIndex:AAPLVertexInputIndexVertices];

[renderEncoder setVertexBytes:&_viewportSize
                       length:sizeof(_viewportSize)
                      atIndex:AAPLVertexInputIndexViewportSize];

// Draw the vertices of the quads
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
                  vertexStart:0
                  vertexCount:_numVertices];

在此示例中,您學(xué)習(xí)了如何使用頂點緩沖區(qū)來提高渲染效率加缘。

后記

本篇主要講述了基本緩沖區(qū)鸭叙,感興趣的給個贊或者關(guān)注~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市生百,隨后出現(xiàn)的幾起案子递雀,更是在濱河造成了極大的恐慌柄延,老刑警劉巖蚀浆,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異搜吧,居然都是意外死亡市俊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門滤奈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摆昧,“玉大人,你說我怎么就攤上這事蜒程∩鹉悖” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵昭躺,是天一觀的道長忌锯。 經(jīng)常有香客問我,道長领炫,這世上最難降的妖魔是什么偶垮? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮帝洪,結(jié)果婚禮上似舵,老公的妹妹穿的比我還像新娘。我一直安慰自己葱峡,他們只是感情好砚哗,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著砰奕,像睡著了一般蛛芥。 火紅的嫁衣襯著肌膚如雪泌参。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天常空,我揣著相機(jī)與錄音沽一,去河邊找鬼。 笑死漓糙,一個胖子當(dāng)著我的面吹牛铣缠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昆禽,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蝗蛙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了醉鳖?” 一聲冷哼從身側(cè)響起捡硅,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盗棵,沒想到半個月后壮韭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡纹因,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年喷屋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞭恰。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡屯曹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惊畏,到底是詐尸還是另有隱情恶耽,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布颜启,位于F島的核電站偷俭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏农曲。R本人自食惡果不足惜社搅,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望乳规。 院中可真熱鬧形葬,春花似錦、人聲如沸暮的。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冻辩。三九已至猖腕,卻和暖如春拆祈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背倘感。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工放坏, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人老玛。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓淤年,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜡豹。 傳聞我的和親對象是個殘疾皇子麸粮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容