Metal框架详细解析(二十一) —— 基本课程之基本缓冲区(一)

版本记录

版本号 时间
V1.0 2018.10.08 星期一

前言

很多做视频和图像的,相信对这个框架都不是很陌生,它渲染高级3D图形,并使用GPU执行数据并行计算。接下来的几篇我们就详细的解析这个框架。感兴趣的看下面几篇文章。
1. Metal框架详细解析(一)—— 基本概览
2. Metal框架详细解析(二) —— 器件和命令(一)
3. Metal框架详细解析(三) —— 渲染简单的2D三角形(一)
4. Metal框架详细解析(四) —— 关于GPU Family 4(一)
5. Metal框架详细解析(五) —— 关于GPU Family 4之关于Imageblocks(二)
6. Metal框架详细解析(六) —— 关于GPU Family 4之关于Tile Shading(三)
7. Metal框架详细解析(七) —— 关于GPU Family 4之关于光栅顺序组(四)
8. Metal框架详细解析(八) —— 关于GPU Family 4之关于增强的MSAA和Imageblock采样覆盖控制(五)
9. Metal框架详细解析(九) —— 关于GPU Family 4之关于线程组共享(六)
10. Metal框架详细解析(十) —— 基本组件(一)
11. Metal框架详细解析(十一) —— 基本组件之器件选择 - 图形渲染的器件选择(二)
12. Metal框架详细解析(十二) —— 基本组件之器件选择 - 计算处理的设备选择(三)
13. Metal框架详细解析(十三) —— 计算处理(一)
14. Metal框架详细解析(十四) —— 计算处理之你好,计算(二)
15. Metal框架详细解析(十五) —— 计算处理之关于线程和线程组(三)
16. Metal框架详细解析(十六) —— 计算处理之计算线程组和网格大小(四)
17. Metal框架详细解析(十七) —— 工具、分析和调试(一)
18. Metal框架详细解析(十八) —— 工具、分析和调试之Metal GPU Capture(二)
19. Metal框架详细解析(十九) —— 工具、分析和调试之GPU活动监视器(三)
20. Metal框架详细解析(二十) —— 工具、分析和调试之关于Metal着色语言文件名扩展名、使用Metal的命令行工具构建库和标记Metal对象和命令(四)

Basic Buffers - 基本缓冲区

演示如何使用顶点缓冲区管理数百个顶点。

Hello Triangle示例中,您学习了如何在Metal中渲染基本几何体。

在此示例中,您将学习如何使用顶点缓冲区来提高渲染效率。 特别是,您将学习如何使用顶点缓冲区来存储和加载多个四边形的顶点数据。


Manage Large Amounts of Vertex Data - 管理大量的顶点数据

Hello Triangle示例中,示例呈现三个顶点,每个顶点32个字节,相当于96个字节的顶点数据。通过调用setVertexBytes:length:atIndex:方法将少量顶点数据发送到顶点函数。此方法分配了图形处理单元(GPU)可访问的少量内存,并且可以在每个帧中分配,而不会产生明显的性能成本。

Hello Triangle示例不同,此示例渲染了2,250个顶点,每个顶点32个字节,相当于72,000个字节的顶点数据。需要更有效地管理该顶点数据量。事实上,对于超过4千字节(4,096字节)的顶点数据,Metal不允许使用setVertexBytes:length:atIndex:方法。更重要的是,不应在每个帧中重新分配和复制顶点数据。

通常,Metal应用程序或游戏会绘制具有数千个顶点的模型,每个顶点都有多个顶点属性,这些顶点属性消耗几兆字节的内存。为了使这些应用程序或游戏能够很好地扩展并进行有效管理,Metal提供了由MTLBuffer对象表示的专用数据容器。这些缓冲区是GPU可访问的内存分配,用于存储多种自定义数据,尽管它们通常用于顶点数据。此示例分配大量顶点数据一次,将其复制到MTLBuffer对象中,然后在每个帧中重用顶点数据。


Allocate, Generate, and Copy Vertex Data - 分配,生成和复制顶点数据

在Objective-C中,字节缓冲区由NSDataNSMutableData对象包装,使用起来既安全又方便。 AAPLVertex数据类型用于样本中的每个顶点,每个四边形由6个这些顶点值组成(每个四边形有两个三角形)。 30 x 20网格的四边形共计3,600个顶点,占用115,200字节的内存,即为样本的顶点数据分配的数量。

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应用程序或游戏会加载模型文件中的顶点数据。 模型加载代码的复杂性因模型而异,但最终顶点数据也存储在传递给Metal代码的字节缓冲区中。 为避免引入模型加载代码,此示例使用generateVertexData方法模拟顶点数据切换,该方法在运行时生成简单的顶点数据。

NSDataMTLBuffer对象都存储自定义数据,这意味着您的应用程序负责在读取或写入操作期间正确定义和解释此数据。 在此示例中,顶点数据是只读的,其内存布局由AAPLVertex数据类型定义,这是vertexShader顶点函数所需的。

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

从根本上说,NSDataMTLBuffer对象都非常相似。 但是,MTLBuffer对象是GPU可访问的专用容器,使图形渲染管道能够从中读取顶点数据。

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:方法创建一个具有特定字节大小和某些访问选项的新MTLBuffer对象。 顶点数据占用115,200字节的内存(vertexData.length),由CPU写入并由GPU读取(MTLResourceStorageModeShared)

其次,memcpy()函数将顶点数据从源NSData对象复制到目标MTLBuffer对象。 _vertexBuffer.contents查询返回指向缓冲区内存的CPU可访问指针。 顶点数据通过指向源数据(vertexData.bytes)的指针和要复制的指定数据量(vertexData.length)复制到此目标。


Set and Draw Vertex Data - 设置和绘制顶点数据

由于样本的顶点数据现在存储在MTLBuffer对象中,因此无法再调用setVertexBytes:length:atIndex:方法;而调用setVertexBuffer:offset:atIndex:方法。 此方法将顶点缓冲区,与该缓冲区中的顶点数据的字节偏移量以及将缓冲区映射到顶点函数的索引作为参数。

注意:使用MTLBuffer作为顶点函数参数不会阻止应用或游戏使用setVertexBytes:length:atIndex:方法为另一个参数设置数据。 实际上,此示例仍使用Hello Triangle示例中引入的viewportSizePointer参数。

最后,通过发出一个从数组中的第一个顶点array (0)开始并最后一个(_numVertices)结束的绘制调用来绘制所有顶点。

[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];

在此示例中,您学习了如何使用顶点缓冲区来提高渲染效率。

后记

本篇主要讲述了基本缓冲区,感兴趣的给个赞或者关注~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,928评论 6 523
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,032评论 3 410
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 173,382评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,580评论 1 304
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,558评论 6 403
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,018评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,261评论 3 432
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,328评论 0 281
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,858评论 1 328
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,843评论 3 351
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,954评论 1 358
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,565评论 5 352
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,251评论 3 342
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,677评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,834评论 1 278
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,558评论 3 383
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,033评论 2 368

推荐阅读更多精彩内容