Metal Programming Guide
读苹果文档时的笔记,给自己看。
primary goal of Metal is to minimize the CPU overhead incurred by executing GPU workloads.
用在两个方面:
- graphics
- data-parallel computation
Metal App 不能在后台运行,否则会被终止。
Command Organization and Execution Model

- MTLDevice 是对 GPU 的建模。
- command queue,由若干 command buffer 组成的队列,并负责这些 command buffer 的执行顺序。
- command buffer,包含 encoded commands (要在设备上执行的指令)。
- command encoder,把命令加到 command buffer 中。
Transient and Non-transient Objects in Metal
Command buffer 和 command encoder 是轻量级的,设计为单次使用。
下面这些的创建是比较消耗资源的,应该复用。
- Command queues
- Data buffers
- Textures
- Sampler states
- Libraries
- Compute states
- Render pipeline states
- Depth/stencil states
Registering Handler Blocks for Command Buffer Execution
block 中的方法可能在任意线程调用,并且不应该是耗时的。
- addScheduledHandler:
- waitUntilScheduled:
- addCompletedHandler:
- waitUntilCompleted
Resource Objects: Buffers and Textures
MTLBuffer
有两个类型。
MTLBuffer
: 无格式 (unformatted) 的内存,可以表示任意类型数据。MTLTexture
: 有格式 (formatted) 的图像数据。
Buffers Are Typeless Allocations of Memory
contents
方法返回 buffer 的 CPU 内存地址。newTextureWithDescriptor:offset:bytesPerRow:
方法创建 texture 对象,指向 buffer 的数据。
Textures Are Formatted Image Data
可以有下面的结构
- A 1D, 2D, or 3D image
- An array of 1D or 2D images
- A cube of six 2D images
Creating a Texture Object
- newTextureWithDescriptor:
对MTLDevice
调用,创建MTLTexture
对象,分配了存储空间。使用MTLTextureDescriptor
来描述纹理的性质。 - newTextureViewWithPixelFormat:
对MTLTexture
调用,返回MTLTexture
对象,和原来的纹理共享内存地址。新的纹理用新的像素格式来解释原有的纹理数据。 - newTextureWithDescriptor:offset:bytesPerRow:
对MTLBuffer
调用,返回MTLTexture
对象,和原来的 buffer 共享内存地址。
使用 Texture Descriptor 来创建纹理对象
MTLTextureDescriptor
定义了纹理的性质,只是用来创建纹理对象。在创建好纹理对象之后,对它的修改不会有任何影响。
MTLTextureDescriptor* txDesc = [[MTLTextureDescriptor alloc] init];
txDesc.textureType = MTLTextureType3D;
txDesc.height = 64;
txDesc.width = 64;
txDesc.depth = 64;
txDesc.pixelFormat = MTLPixelFormatBGRA8Unorm;
txDesc.arrayLength = 1;
txDesc.mipmapLevelCount = 1;
id <MTLTexture> aTexture = [device newTextureWithDescriptor:txDesc];
Copying Image Data to and from a Texture
- 把数据写入纹理
- replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:
- replaceRegion:mipmapLevel:withBytes:bytesPerRow:
- 把数据从纹理读出来
- getBytes:bytesPerRow:bytesPerImage:fromRegion:mipmapLevel:slice:
- getBytes:bytesPerRow:fromRegion:mipmapLevel:
例子如下:
// pixelSize is the size of one pixel, in bytes
// width, height - number of pixels in each dimension
NSUInteger myRowBytes = width * pixelSize;
NSUInteger myImageBytes = rowBytes * height;
[tex replaceRegion:MTLRegionMake2D(0,0,width,height)
mipmapLevel:0 slice:0 withBytes:textureData
bytesPerRow:myRowBytes bytesPerImage:myImageBytes];
Pixel Formats for Textures
有三种像素类型:
- Ordinary formats
- Packed formats
- Compressed formats
Creating a Sampler States Object for Texture Lookup
- 创建
MTLSamplerDescriptor
对象 - 设置对象的性质
- 创建
MTLSamplerState
对象。
MTLSamplerState
对象只是用来创建 MTLSamplerState
对象。创建完之后,对它的修改不会影响已经创建好的 MTLSamplerState
对象。
// create MTLSamplerDescriptor
MTLSamplerDescriptor *desc = [[MTLSamplerDescriptor alloc] init];
desc.minFilter = MTLSamplerMinMagFilterLinear;
desc.magFilter = MTLSamplerMinMagFilterLinear;
desc.sAddressMode = MTLSamplerAddressModeRepeat;
desc.tAddressMode = MTLSamplerAddressModeRepeat;
// all properties below have default values
desc.mipFilter = MTLSamplerMipFilterNotMipmapped;
desc.maxAnisotropy = 1U;
desc.normalizedCoords = YES;
desc.lodMinClamp = 0.0f;
desc.lodMaxClamp = FLT_MAX;
// create MTLSamplerState
id <MTLSamplerState> sampler = [device newSamplerStateWithDescriptor:desc];
Maintaining Coherency Between CPU and GPU Memory
CPU 和 GPU 都可以访问 MTLResource
对象。
GPU 只能记录在 MTLCommandBuffer
的 commit
方法调用之前,CPU 对 MTLResource
的改动。
CPU 只有在 GPU 完成 MTLCommandBuffer
中的指令之后,才可以看到 GPU 对 MTLResource
的改动。
Functions and Libraries
MTLFunction Represents a Shader or Compute Function
只有被 vertex
、fragment
或 kernel
修饰的函数才可以表示为 MTLFunction
。
A Library Is a Repository of Functions
Library 中的 MTLFunction
可以有两个来源:
- 在 build 阶段被编译好的二进制 Metal shading language code
- 包含 Metal shading language 源代码的字符串,在运行时被编译
Creating a Library from Compiled Code
可以提高效率,不必在运行时编译源代码。
可以通过以下方法来获取 MTLLibrary
。
- newDefaultLibrary
- newLibraryWithFile:error:
- newLibraryWithData:error:
Creating a Library from Source Code
- newLibraryWithSource:options:error: 同步方法
- newLibraryWithSource:options:completionHandler: 异步方法
Graphics Rendering: Render Command Encoder

Creating a Render Pass Descriptor
MTLRenderPassDescriptor
表示 encoded rendering commands 的目的地 (destination)。MTLRenderPassDescriptor
的属性可以包括至多 4 个颜色的 attachments,一个像素深度数据的 attachment,一个像素 stencil 数据的 attachment。
Load and Store Actions
指定了在 rendering pass 的起始和结束时的动作。
loadAction
包括:
- MTLLoadActionClear 为每一个像素写入指定的值。
- MTLLoadActionLoad 保存已有的值
- MTLLoadActionDontCare 在起始阶段可以有任意值,性能最高。
storeAction 包括
- MTLStoreActionStore 保存最后的像素值,color attachments 的默认值
- MTLStoreActionMultisampleResolve
- MTLStoreActionDontCare 会提高性能。depth and stencil attachments 的默认值。
一个例子如下:
MTLTextureDescriptor *colorTexDesc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
width:IMAGE_WIDTH height:IMAGE_HEIGHT mipmapped:NO];
id <MTLTexture> colorTex = [device newTextureWithDescriptor:colorTexDesc];
MTLTextureDescriptor *depthTexDesc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat:MTLPixelFormatDepth32Float
width:IMAGE_WIDTH height:IMAGE_HEIGHT mipmapped:NO];
id <MTLTexture> depthTex = [device newTextureWithDescriptor:depthTexDesc];
MTLRenderPassDescriptor *renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor];
renderPassDesc.colorAttachments[0].texture = colorTex;
renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(0.0,1.0,0.0,1.0);
renderPassDesc.depthAttachment.texture = depthTex;
renderPassDesc.depthAttachment.loadAction = MTLLoadActionClear;
renderPassDesc.depthAttachment.storeAction = MTLStoreActionStore;
renderPassDesc.depthAttachment.clearDepth = 1.0;
Using the Render Pass Descriptor to Create a Render Command Encoder
id <MTLRenderCommandEncoder> renderCE = [commandBuffer
renderCommandEncoderWithDescriptor:renderPassDesc];
Displaying Rendered Content with Core Animation
利用 CAMetalLayer
。
Creating a Render Pipeline State
MTLRenderPipelineState
对象生命周期很长,应该缓存起来复用。
MTLRenderPipelineState
对象是不可变的。先创建一个 MTLRenderPipelineDescriptor
,设置好性质,然后再创建 MTLRenderPipelineState
。

例子如下:
MTLRenderPipelineDescriptor *renderPipelineDesc =
[[MTLRenderPipelineDescriptor alloc] init];
renderPipelineDesc.vertexFunction = vertFunc;
renderPipelineDesc.fragmentFunction = fragFunc;
renderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;
// Create MTLRenderPipelineState from MTLRenderPipelineDescriptor
NSError *errors = nil;
id <MTLRenderPipelineState> pipeline = [device
newRenderPipelineStateWithDescriptor:renderPipelineDesc error:&errors];
assert(pipeline && !errors);
// Set the pipeline state for MTLRenderCommandEncoder
[renderCE setRenderPipelineState:pipeline];
Specifying Resources for a Render Command Encoder

调用 setVertex*
以及 setVertex*
方法。
Drawing Geometric Primitives
调用 draw*
方法。
Ending a Rendering Pass
调用 endEncoding
方法
Metal Programming Guide的更多相关文章
- 【IOS笔记】View Programming Guide for iOS -1
原文:View Programming Guide for iOS View and Window Architecture Views and windows present your applic ...
- Quartz 2D Programming Guide
Quartz 2D Programming Guide 官方文档: Quartz 2D Programming Guide 译文: Quartz 2D编程指南(1) - 概览 Quartz 2D编程 ...
- [IoLanguage]Io Programming Guide[转]
Io Programming Guide Introduction Perspective Getting Started Downloading Installing Binaries Ru ...
- Structured Streaming Programming Guide结构化流编程指南
目录 Overview Quick Example Programming Model Basic Concepts Handling Event-time and Late Data Fault T ...
- GraphX学习笔记——Programming Guide
学习的资料是官网的Programming Guide https://spark.apache.org/docs/latest/graphx-programming-guide.html 首先是Gra ...
- View Programming Guide for iOS_读书笔记[正在更新……]
原文:View Programming Guide for iOS 1 Introduction 先熟悉一下基本概念. Window Windows do not have any visible c ...
- OpenGL® ES 3.0 Programming Guide - Book Website
OpenGL® ES 3.0 Programming Guide - Book Website http://opengles-book.com sample codes in GitHub: htt ...
- 对Spark2.2.0文档的学习3-Spark Programming Guide
Spark Programming Guide Link:http://spark.apache.org/docs/2.2.0/rdd-programming-guide.html 每个Spark A ...
- Spark Streaming Programming Guide
参考,http://spark.incubator.apache.org/docs/latest/streaming-programming-guide.html Overview SparkStre ...
随机推荐
- jquery中的trigger()和preventDefault()方法
trigger()方法用户模拟用户操作,比较常见的一种情况就是输入框自动获得焦点: <!doctype html> <html> <head> <meta c ...
- 在Linux下删除文件及文件夹(rm)
删除目录.文件 rm(remove) 功能说明:删除文件或目录.语 法:rm [-dfirv][--help][--version][文件或目录...]补充说明:执行rm指令可删除文件或目录,如欲删除 ...
- Python 使用Pandas读取Excel的学习笔记
这里介绍Python中使用Pandas读取Excel的方法 一.软件环境: OS:Win7 64位 Python 3.7 二.文件准备 1.项目结构: 2.在当前实验文件夹下建立一个Source文件夹 ...
- 对于一个web工程,如果我们复制一个已有的工程粘贴到同一个workspace下,我们除了需要更改工程的名字还需要更改这个新工程的content root,否则会报错。
对于一个web工程,如果我们复制一个已有的工程粘贴到同一个workspace下,我们除了需要更改工程的名字还需要更改这个新工程的content root,否则会报错.步骤如下: 右键新的工程---&g ...
- 数据结构notes
1. 一份很好的数据结构教程,图文并茂,简明扼要,列出每种结构的定义和优缺点,非常适合初学者 via @ranyif https://www.interviewcake.com/data-struct ...
- WSTMart商城系统数据字典
欢迎来到WSTMart官网 开源多用户商城 QQ交流群: 返回首页|返回首页| 开发手册 | 数据库字典 | 授权查询 | 授权用户登录 | 官方微信扫一扫 x QQ客服 服务热线 020-852 ...
- PHP 中 Traits 的简单使用
PHP 5.4中的traits,是新引入的特性,中文还真不知道如何准确翻译好.其实际的目的,是为了有的场合想用多继承,但PHP又没多继承,于是就发明了这样的一个东西. Traits可以理解 ...
- 不要怂,就是GAN (生成式对抗网络) (五):无约束条件的 GAN 代码与网络的 Graph
GAN 这个领域发展太快,日新月异,各种 GAN 层出不穷,前几天看到一篇关于 Wasserstein GAN 的文章,讲的很好,在此把它分享出来一起学习:https://zhuanlan.zhihu ...
- join sql图
SELECT * FROM TableA INNER JOIN TableB ON TableA.name = TableB.name id name id name -- - ...
- (最短路 SPFA)Currency Exchange -- poj -- 1860
链接: http://poj.org/problem?id=1860 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 2326 ...