博客> Metal Framework基础使用教程——渲染流水线的基本执行模型
Metal Framework基础使用教程——渲染流水线的基本执行模型
2017-11-22 18:24 评论:0 阅读:401 ccsupport

版主zenny_chen授权转载

我们在使用Metal时,通常会先对一些资源做初始化设置,同时,这些资源将在整个执行过程中一直被保留,有些甚至不会被修改。然后,是做渲染过程。渲染过程可以通过定时器或其它刷新方式不断地执行。里面所含有的资源是瞬时的,即仅仅在一个渲染过程内有效。一次渲染过程又可以称为一个渲染遍(render pass)。

在Metal整个执行过程中,以下资源是要被长久保留的,即它们的生命周期与你的Metal layer一样长:

命令队列(Command Queue)、缓存(Buffer)、纹理(Texture)、采样器状态(Sampler State)、库(Library)、计算状态(Compute State)、渲染流水线状态(Render Pipeline State)、深度/模板状态(Depth/Stencil State)。

而这些资源是瞬时的:命令缓存(Command Buffer)、命令编码器(Command Encoder)。

下图描述了一个图形渲染流水线的基本执行流程:  Enter your image description here:

上图中,矩形框表示创建的对象为持久保留的,圆边矩形框表示创建或获得的资源是瞬时的,即在当前过程完成之后就被释放。实线箭头表示流水过程,虚线箭头A ---> B表示对象A对对象B有所引用。 平行四边形框表示动作行为。

下面对上图中所列出来的各个组件进行介绍:

1、MTLDevice:这个协议对象标识了当前的Metal设备。也就是说,我们用的是哪款图形处理器。当然,目前iOS就一块GPU,所以我们可以通过MTLCreateSystemDefaultDevice()函数来获得默认的Metal设备。之前说过,当前Metal设备仅支持Apple A7处理器的GPU或更新处理器中的GPU。不过,我们仍然可以对Metal设备进行查询其功能特征,通过调用MTLDevice协议的supportsFeatureSet:方法。

当前有两个特征集:MTLFeatureSet_iOS_GPUFamily1_v1与MTLFeatureSet_iOS_GPUFamily2_v1。iOS_GPUFamilyN表示大版本号,后面的vM表示小版本号。Family1与Family2是两个不同的家族,因此它们相互之间并非超级、子集的关系。

Family1_v1具有如下特征:

(1)一个MTLRenderPassDescriptor除了一个深度attachment与模板attachment之外,可以具有最多4个颜色attachment。 (2)每个渲染遍可以存储每个样本最大16个字节的颜色数据。 (3)ASTC(高级视频系统协会)像素格式(即YUV等视频格式)不被支持。 (4)在一个attachment中所有像素格式消耗每个样本最小4个字节,即便存储器中的每个像素少于4字节。 (5)一个attachment在宽度或高度上都不应该小于32个像素。 (6)每个线程组存储器分配会被舍入到16字节,即至少分配16字节,分配的字节数是16的倍数。比如,如果在分配了24字节,那么会被填充扩展到32字节。 (7)所有线程组存储器分配的总和不能超过16KB。也就是local memory的大小。 (8)对于一个MTLTextureDescriptor,高度和宽度属性不能超过4096,深度不能超过2048。 (9)对于参数表,最多31个缓存,31个纹理,16个采样器状态。

Family2_v1具有如下特征:

(1)一个MTLRenderPassDescriptor除了一个深度attachment与模板attachment之外,可以具有最多8个颜色attachment。 (2)每个渲染遍可以存储每个样本最大32个字节的颜色数据。 (3)ASTC(高级视频系统协会)像素格式(即YUV等视频格式)被支持。 (4)在一个attachment中所有像素格式消耗每个样本最小4个字节,即便存储器中的每个像素少于4字节。 (5)一个attachment在宽度或高度上都不应该小于32个像素。 (6)每个线程组存储器分配会被舍入到16字节,即至少分配16字节,分配的字节数是16的倍数。比如,如果在分配了24字节,那么会被填充扩展到32字节。 (7)所有线程组存储器分配的总和不能超过16KB。也就是local memory的大小。 (8)对于一个MTLTextureDescriptor,高度和宽度属性不能超过4096,深度不能超过2048。 (9)对于参数表,最多31个缓存,31个纹理,16个采样器状态。

2、MTLCommandQueue:命令队列由MTLDevice对象分配得到。命令队列接受一组有序的命令缓存,这些命令缓存会被GPU执行。所有发送到命令队列的命令缓存会确保按照命令缓存之前的排队顺序依次执行。

3、MTLLibrary:一个Metal库也是通过Metal设备创建。Metal库是Metal函数的仓库。与OpenGL不同,一个Metal文件里可以同时包含多个执行程序,甚至多个顶点函数、片段函数和计算函数。当然,你也可以写多个Metal文件。然后用Xcode工具编译,就能自动生成本地的默认Metal库。用MTLDevice的newDefaultLibrary方法就能创建使用本地编译好的Metal库的对象。当然,Metal Framework也提供了使用本地Metal源文件、选择bundle里的Metal库文件或是直接指定Metal源代码的方式来创建MTLLibrary对象。

MTLLibrary对象创建完之后就可以创建MTLFunction对象。把你要执行的主函数名传给MTLLibrary的newFunctionWithName:方法即可创建相应的MTLFunction对象。

4、MTLRenderPipelineState:渲染流水线状态通过Metal设备创建,用于设置顶点函数、片段函数或计算函数,以及样本个数、颜色像素格式、深度、模板等属性。它包含了在整个绘制过程中的主要渲染流水线状态,并且这些状态属性一般不太会去修改。

5、MTLBuffer:缓存通过Metal设备创建,一般用于存放顶点坐标、颜色数据,以及旋转角度等数据。这里面,有些数据在所有渲染遍中都不会改变,比如顶点坐标;有些则可能会每一个渲染遍都会更新,比如旋转角度属性。如果要对一个缓存的值进行修改,可以通过访问MTLBuffer的contents属性,获得其元数据的首地址,然后直接对其内容进行修改即可。比如:

// 设置时
float degree = 0.0f;
mRotateBuffer = [device newBufferWithBytes:&degree length:sizeof(degree) options:0];

// 渲染时
float *gpuRotateBuffer = [mRotateBuffer contents];
*gpuRotateBuffer = mCurrentDegree;

以上就是整个设置步骤。

收藏
1
sina weixin mail 回到顶部