Metal 编程指南

Metal Programming Guide

Command organization and execution model (指令组织和执行模型)

  1. 在 Metal 框架中, MTLDevice 协议定义的接口描述了一个 GPU, 该协议提供了一系列方法可以查询设备属性, 创建设备相关对象(缓存和纹理)

  2. command queue 包含了一系列的 command buffers, command queue 用于管理其中的 command buffers 的执行顺序.

  3. command buffer 包含了多个被编码的指令, 这些指令在一个特定设备上运行.

  4. command encoder 可以将绘制, 计算, 位图传输指令放到一个 command buffer 中

  5. command buffers 最终被提交到设备中去执行.

  6. MTLCommandQueue 协议为 command queue 定义了接口, 主要是创建 command buffer 对象的方法.

  7. MTLCommandBuffer 协议 为 command queue 定义了接口, 提供了创建 command encoder, 入队列执行, 检测状态以及其他操作. 该协议定义了几种 command encoder 的类型, 他们可以被用于将不同的 GPU 任务编码到 command buffer 中执行.

    MTLRenderCommandEncoder 协议 - 将图形渲染指令编码为一次渲染过程.
    MTLComputeCommandEncoder 协议 - 编码并行计算任务
    MTLBlitCommandEncoder 协议 - 在缓存和纹理之间的拷贝以及 mipmap 的生成.

  8. 任一时刻, 只有一个 Encoder 是处于激活状态的, 他可以向一个 command buffer 提交 command. 对于同一个 command buffer 来说,必须是前一个 encoder 结束后, 新的 encoder 才可以被创建并且用于此 command buffer(MTLParallelRenderCommandEncoder 例外).

  9. 一点所有的指令编码结束, MTLCommandBuffer 对象自己就会提交,并且会被标记为准备执行状态. MTLCommandQueue 协议可以用来控制这些要被执行的 MTLCommandBuffer 对象.

  10. 一个 MTLDevice 对象代表了一个可以执行 command 的 GPU. MTLDevice 协议有创建新的 command queue , 从内存创建缓存, 创建纹理, 查询设备能力的方法. 使用 MTLCreateSystemDefaultDevice 来创建首选设备.

  11. 创建: command buffers 和 command encoder 基本不耗费什么系统资源.

  12. Command queue & buffer & texture & sample state libraries & compute state & render pipeline state & depth/stencil state, 这些对象系统鼓励重用.

Command Queue

  1. command queue 接受的是: 有序的 command buffer(将要在 GPU 中执行) 列表. 在 command queue 中的 command buffers 会被确保按顺序执行. command queue 是线程安全的.

  2. MTLDevice 中有两个方法可以创建 command queue

    newCommandQueue
    newCommandQueueWithMaxCommandBufferCount

  3. 不要没事销毁和创建 commandQueue, 记得复用.

Command buffer

  1. command buffer 在被 GPU 执行之前会包含多个被编码的 command,
  2. 不支持重用, 能做的就是提交执行后, 检查状态
  3. 他还是 app 中独立可以被追踪的任务单元.

创建 command buffer

  1. MTLCommandQueue 中定义了创建 commandBuffer 的方法. 一个 MTLCommandQueue 对象只能提交给创建他的 MTLCommandQueue.
  2. commandBuffers创建的 command buffer 对象持有他执行时需要的数据. 在特定场景下, 你需要的资源已经被持有了, 可以使用commandBufferWithUnretainedReferences方法.(该方法只有在极端需要性能 app 中, 并且能够保证在 command 执行完之前资源都保持存活的情况下才使用)

Executing Command

  1. MTLCommandBuffer 协议中有下列的方法可以设定在 command queue 中的执行顺序. 一个 command buffer 一定要先提交然后在执行.
  2. enqueue 方法可以为一个 command buffer 在 command queue 中预定一个位置.但是并没有把 command buffer 提交执行.当这个 command buffer 最终提交的时候, 他会在之前做 enqueue 操作的 command buffer 之后执行.
  3. commit 方法会使 command buffer 尽快的被执行.但必须是等到之前 enqueue 的 command buffer 执行后. commit 会隐式的调用 enqueue.

Registering Handler Blocks for Command Buffer Execution

  1. addScheduledHandler, 当 command buffer 被 schedule 的时候调用.
  2. waitUntilScheduled, 该方法同步的等待, 当 command buffer 被完全执行完或者其所有注册 addScheduledhandler 都结束的时候返回.
  3. addCompleteHandler, 当设备执行完 command buffer 的时候调用.
  4. waitUntilCompleted, 该方法同步的等待, 当设备执行完 command buffer并且所有注册 addCompleteHandler 都返回的时候.
  5. presentDrawable:, 便捷函数:在command buffer 被 schedule 的时候, 能够将可显示的资源(CAMetalDrawable 对象)展示出来
  6. status, read-only 属性. command buffer 是在生命周期的哪个阶段.
  7. error, 如果没有异常,为 nil. 如果有错误, 可以看看 command buffer error codes.

Command Encoder

1.Encoder 是一个一次性的 transient 的对象, 在激活状态的时候可以他就可以把一个 command 追加到 command buffer 中. 使用 endEncoding 来结束编码 command. 还想要编码 command, 只能在新建一个 encoder.

Creating a Command Encoding Object

  1. renderCommandEncoderWithDescriptor, 创建一个 MTLRenderCommandEncoder 类型的 encoder 用来在 TMLRenderPassDescriptor中做图形渲染.
  2. computeCommandEncoder, 创建一个 MTLComputeCommandEncoder 类型的 encoder 用来做并行计算.
  3. blitCommandEncoder, 创建了一个 MTLBlitCommandEncoder 类型的 encoder 用来做内存操作.
  4. parallelRenderCommandEncoderWithDescriptor, 创建了一个 MTLParallelRenderCommandEncoder 类型的 encoder, 用来让多个 MTLRenderCommandEncoder 对象在不同的线程工作,并且保证渲染到同一个 attachment(共享的MTLRenderPassDescriptor) 中.

Render Command Encoder

  1. 该 encoder 需要关联一个MTLRenderPassDescriptor对象,在这个descriptor对象中包含了颜色 、景深、模板attachment,这些attachment将被当做绘制命令的目标,

  2. 该 Encoder 有如下能力:

    指定图形资源, 如缓存和纹理对象。
    指定 MTLRenderPipelineState对象(包含 compiled rendering state 以及顶点和片段着色器)
    指定 fixed-function 状态, 包括 viewport,
    更多可以看 MTLRenderCommandEncoder 协议

Compute Command Encoder

参见 MTLComputeCommandEncoder 协议

Blit Command Encoder

MTLBlitCommandEncoder 协议可以追加一个 command 用来做 MTLBuffer 和 MTLTexture 之前的内存拷贝操作.
还可以用固定颜色填充纹理生成一个 mipmaps

Multiple Thread, Command Buffers, Command Encoder

  1. 大多数程序使用单一的线程来encoder 绘制指令到一个 command buffer 来绘制一帧画面.在每一帧结束的时候, 提交 command buffer, 这样就可以 shcedule 并且 开始 command 的执行.
  2. 如果需要并行的为 command buffer 编码, 这样就需要在同时创建多个command buffer, 在不同的线程 encoder 每一个 command buffer. 如果提前知道 command buffer 的执行顺序, 就可以按顺序 enqueue 每个 command buffer, 就不用等待执行编码和提交.

Resource Objects: Buffers and Textures

  1. MTLBuffer 表示一块非格式化的内存可以存放任何类型的数据.通常用来存放顶点, 着色器, 计算状态数据.
  2. MTLTexture 表示一块有格式的图像数据, 有特定的纹理类型 & 像素格式
  3. MTLSampleState 用于纹理对象的查找计算.

Buffers are Typeless Allocations of Memory

一个 MTLBuffer 表示了一段内存区域,他可以存放任何数据类型.

Creating a Buffer Object

  1. 下面的 MTLDevice 方法创建并返回一个 MTLBuffer 对象

newBufferWithLenth:Options: 分配内存创建一个 MTLBuffer 对象
newBufferWithBytes:length:options: 通过从已有的存储器中拷贝到新分配的内存中
newBufferWithBytesNoCopy:length:options:deallocator: 该方法创建一个 MTLBuffer 对象,但不会为这个对象新分配内存,而是使用已经存在的内存。

作者

shouyi.www

发布于

2019-12-04

更新于

2025-01-30

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×