版本記錄
版本號 | 時間 |
---|---|
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ū)由NSData
或NSMutableData
對象包裝,使用起來既安全又方便龟虎。 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ù)蒲赂。
NSData
和MTLBuffer
對象都存儲自定義數(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) ]])
從根本上說届囚,NSData
和MTLBuffer
對象都非常相似。 但是是尖,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)注~~~