美文网首页
Metal(一)-简述 & 主要API

Metal(一)-简述 & 主要API

作者: Henry________ | 来源:发表于2020-08-23 22:29 被阅读0次

    Metal简述

    Metal是苹果公2014年推出的一套取代OpenGLES的渲染应用程序编程接口,支持到iOS8以上。Metal不单延续了OpenGLES中的渲染高级3D图形,还可以使用GPU高效完成数据并行计算。
    Core Image, SpriteKit, 和 SceneKit已经在使用了。

    Metal优化点

    1. 最大程度的降低了CPU的相关开销
    2. 最大程度的使用GPU的性能
    3. 最大限度的提高了CPU、GPU的并行能力
    4. 最大限度的进行系统资源的有效管理

    graphics pipeline(图形管道)

    • 和OpenGL中的图形管道相比相似度非常高;
    • 顶点处理:物体矩阵、世界矩阵、观察者矩阵(相当于MVP),裁剪
    • 图元装配方式:点、线、线环、三角形、三角形带
    • 片段处理:纹理、模板、透明度、混合

    Cpu:处理顶点数据->GPU: 顶点处理(顶点着色器)->图元装配(5种)->光栅化->片段处理(片元着色器)->帧缓存区

    OpenGl

    可以对照这幅图回忆一下自己的知识结构和OpenGLES中的知识点。

    在使用Metal前,Apple有一些建议

    • Separate Your Rendering Loop分开渲染循环:不希望将渲染的处理逻辑放到ViewController | View中。建议单独创建一个类来完成各种Metal的渲染绘制工作。
    • Respond to View Events响应代理<MTKViewDelegate>的事件
    • Metal Command Objects创建一个命令对象,即创建执行命令的GPU

    Metal中对象之间的关系

    图一
    图二
    两张图可以对比来看 838133-8b76a2d6479f743b.jpg
    1. 命令缓存区(command buffer) 是从命令队列列(command queue) 创建的
    2. 命令编码器器(command encoders) 将命令编码到命令缓存区中
    3. 提交命令缓存区并将其发送到GPU
    4. GPU执⾏行行命令并将结果呈现为可绘制

    Metal中常见Api

    MTKView

    MTKView理解上可以对标GLKView来理解。
    相同点: 提供用于绘制layer的专属视图。

    不同点:

    1. 没有MTKViewController。
    2. GLKView初始化时需要提供GLKContent,而MTKView需要确定MTLDevice

    MTLDevice

    Metal是直接操作GPU的,所以需要获取GPU的使用权限。在iOS中一般是通过默认的方式MTLCreateSystemDefaultDevice()获取GPU的使用权限。也可以使用MTLCopyAllDevices()来获取系统中所有Metal设备对象的引用数组。

    MTLDevice协议表示可以执行命令的GPU,提供了如下功能

    • 创建新的命令队列
    • 从内存分配缓冲区
    • 创建纹理
    • 查询设备功能

    MTLCommandQueue

    在获取了GPU后,还需要一个渲染队列,即命令队列Command Queue类型是MTLCommandQueue,该队列是与GPU交互的第一个对象,队列中存储的是将要渲染的命令MTLCommandBuffer。正好对应上方图。

    创建方式:

    _commandQueue = [_device newCommandQueue];
    
    • 该对象的创建需要消耗大量资源,加之这个命令队列生命周期很长,所以建议该对象作为全局,而不是反复创建和消耗。

    MTLCommandBuffer

    命令缓存区Command Buffer主要是用于存储编码的命令,其生命周期是指导缓存区被提交到GPU执行为止,单个的命令缓存区可以包含不同的编码命令,主要取决于用于构建它的编码器的类型和数量。

    创建方式:

    commandBuffer = [_commandQueue commandBuffer]
    
    • buffer的创建需要通过Command Queue来创建的
    • buffer中生成的CommandEncoder都需要通过当前buffer来进行提交、渲染、绘制.

    commandBuffer在未提交命令缓存区之前,是不会开始执行的。等待提交后命令缓存区将按其按照加入队的顺序进行执行。当然这是整个编码步骤中的最后一步。
    commandBuffer的执行顺序有以下两种:

    • enqueue:顺序执行,enqueue方法在命令队列中为命令缓存区保留一个位置,此时并未提交命令缓存区,当最终提交命令缓存区后,按照命令队列的顺序依次执行
    • commit:插队尽快执行,如果前面有commit还是需要排队等着

    MTLRenderCommandEncoder

    MTLRenderCommandEncoder表示单个渲染过程中相关联的渲染状态和渲染命令(可以对标OpenGL中的上下文状态机来理解),有以下功能:

    1. 指定图形资源,例如缓存区和纹理对象,其中包含顶点、片元、纹理图片数据
    2. 指定MTLRenderPipelineState对象,其中包含编译的渲染状态、顶点着色器、片段着色器
    3. 指定固定功能状态,包括视口,三角形填充模式,剪刀矩形,深度和模板测试以及其他值
    4. 绘制3D图元
    编码器执行流程
    1. 通过调用MTLCommandBuffer对象的makeRenderCommandEncoder(descriptor :)方法来创建MTLRenderCommandEncoder对象。
    2. 调用setRenderPipelineState(_ :)方法以指定MTLRenderPipelineState,该状态定义图形渲染管道的状态,包括顶点和片段函数。
    3. 指定用于顶点和片元函数输入和输出的资源,并在对应的参数中设置每个资源的位置(即索引),即将顶点数据等通过commandEncoder调用setVertexBytes:length:atIndex:函数传递到metal shader Language文件的顶点着色器和片元着色器函数
    4. 指定其他的固定功能状态,例如通过commandEncoder调用setViewport:函数设置视口大小等
    5. 绘制图形
    6. 调用endEncoding()方法以终止渲染命令编码器。

    MTLRenderPipelineDescriptor

    MTLRenderPipelineDescriptor管道状态描述符:在渲染过程中使用的渲染配置状态,包括光栅化(例如多重采样),可见性,混合,镶嵌和图形功能状态,主要是渲染管道描述符中指定顶点或片段函数。

    举例:

        MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
            //管道名称
        pipelineStateDescriptor.label = @"Simple Pipeline";
            //可编程函数,用于处理渲染过程中的各个顶点
        pipelineStateDescriptor.vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"];
            //可编程函数,用于处理渲染过程中各个片段/片元
        pipelineStateDescriptor.fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"];
            //一组存储颜色数据的组件
        pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat;
            //同步创建并返回渲染管线状态对象
        _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error];
    

    MTLRenderPassDescriptor

    官方文档定义为渲染命令编码器描述符:用于保存渲染过程中的一组结果
    下图中红圈位置代表MTLRenderPassDescriptor在Metal整个渲染流程中的位置,也可以对标OpenGLES中的frameBuffer来理解

    Metal渲染流程

    参考资料

    Metal
    MTKView
    Metal Best Practices Guide
    Metal Programming Guide
    apple官方demo

    参考文章

    相关文章

      网友评论

          本文标题:Metal(一)-简述 & 主要API

          本文链接:https://www.haomeiwen.com/subject/fznwjktx.html