對 iOS 中 GPU 編程的高度優化的框架 Metal

序言

前段時間在研究SceneKit,感受到iOS 系統有不少有趣又好玩的東西,我我的是比較喜歡折騰這些技術的,在研究SceneKit 的時候,發現它有兩套渲染機制,OpenGL 和 Matal ,OpenGL 還算比較熟悉,可是Metal部分就不太清除,因而決定好好研究,一下這磨人的小妖精。編程

初步瞭解

1.什麼是Matal?api

Metal 是一個和 OpenGL ES 相似的面向底層的圖形編程接口,經過使用相關的 api 能夠直接操做 GPU ,最先在 2014 年的 WWDC 的時候發佈,並於今年發佈了 Metal 2。 Metal框架支持GPU硬件加速、高級3D圖形渲染以及大數據並行運算。且提供了先進而精簡的API來確保框架的細粒度(fine-grain),而且在組織架構、程序處理、圖形呈現、運算指令以及指令相關數據資源的管理上都支持底層控制。其核心目的是儘量的減小CPU開銷,而將運行時產生的大部分負載交由GPU承擔安全

2.主要的技能bash

1.3D圖形渲染 2.並行運算網絡

Metal 具備特色數據結構

  • Metal 是 iOS 平臺獨有的
  • 消除「隱藏」的性能瓶頸,如隱式狀態驗證。你能夠在多線程異步控制GPU,有效用於平行建立和提交命令緩衝區
  • 描述了緩衝和紋理對象表明了GPU的內存分配。紋理對象有特定的像素格式,並可用於紋理圖像或附件對象
  • 使用相同的數據結構和資源(如緩衝區、紋理和命令隊列),用於圖形和計算操做。此外,金屬着色語言支持圖形和計算功能。Metal使得資源可以和runtime接口、圖形着色器、並計算函數之間共享
  • Metal 着色器能夠和你的app代碼同樣在運行時加載,編譯,這樣的好處時可以更好的生成代碼,以及編譯調試
  • Metal 不能再後臺執行命令代碼,不然系統崩潰

有步驟講解視頻以及資料.由於簡書文章沒有地方放.你們能夠加一下個人羣獲取一下。在羣裏討論一下Metal這一塊。iOS技術交流羣:923910776.多線程

基礎流程

使用Metal和Objective-C來建立一個有基本脈絡的應用:畫一個簡單的三角形。架構

注意:Metal應用不能跑在iOS模擬器上,它們須要一個設備,設備上裝載着蘋果A7芯片或者更新的芯片。因此須要一臺這樣的設備(iPhone 5S,iPad Air,iPad mini2)來完成代碼的測試。app

流程框架

1.配置 Device 和 Queue 2.獲取 CommandBuffer 3.配置 CommandBufferEncoder 4.配置 PipelineState 5.建立資源 6.Encoder Buffer 【若有須要的話能夠用 Threadgroups 來分組 Encoder 數據】 7.提交到 Queue 中

  • 若是有技術和我討論或者想拿源碼和思惟導圖資料的, 請聯繫我時,備註一下Matal
  • 加我技術交流QQ羣:923910776

初始化

新建一個普通的工程 Single View Application,在 VC 中導入 Metal Framework。

MTLDevice

都說是操做 GPU 了,固然咱們要拿到 GPU 對象,Metal 中提供了 MTLDevice 的接口,表明了 GPU。

//獲取設備
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
if (device == nil) {
    NSLog(@"don't support metal !");
    return;
}
複製代碼

當設備不支持 Metal 的時候會返回空。

MTLCommandQueue

有了 GPU 以後,咱們須要一個渲染隊列 MTLCommandQueue,隊列是單一隊列,確保了指令可以按順序執行,裏面的是將要渲染的指令 MTLCommandBuffer,這是個線程安全的隊列,能夠支持多個 CommandBuffer 同時編碼。 經過 MTLDevice 能夠獲取隊列

id<MTLCommandQueue> queue = self.device.newCommandQueue;
複製代碼

MTKView

要用 Metal 來直接繪製的話,須要用特殊的界面 MTKView,同時給它設置對應的 device 爲咱們上面獲取到 MTLDevice,並把它添加到當前的界面中。

_mtkView = [[MTKView alloc] initWithFrame:self.view.frame device:_device];
[self.view addSubview:_mtkView];
複製代碼

渲染

咱們配置好 MTLDevice,MTLCommandQueue 和 MTKView 以後,咱們開始準備須要渲染到界面上的內容了,就是要塞進隊列中的緩衝數據 MTLCommandBuffer 。 簡單的流程就是先構造 MTLCommandBuffer ,再配置 CommandEncoder ,包括配置資源文件,渲染管線等,再經過 CommandEncoder 進行編碼,最後才能提交到隊列中去。

MTLCommandBuffer

有了隊列以後,咱們開始構建隊列中的 MTLCommandBuffer,一開始獲取的 Buffer 是空的,要經過 MTLCommandEncoder 編碼器來 Encode ,一個 Buffer 能夠被多個 Encoder 進行編碼。

MTLCommandBuffer 是包含了多種類型的命令編碼 - 根據不一樣的 編碼器 決定 包含了哪些數據。 一般狀況下,app 的一幀就是渲染爲一個單獨的 Command Buffer。MTLCommandBuffer 是不支持重用的輕量級的對象,每次須要的時候都是獲取一個新的 Buffer。

Buffer 有方法能夠 Label ,用來增長標籤,方便調試時使用。

建立

  • MTLCommandQueue - commandBuffer 方法 ,只能加到建立它的隊列中。
  • 獲取 retain 的對象 commandBufferWithUnretainedReferences 可以重用 通常不推薦

這裏咱們經過以下方法建立

//command buffer
    id<MTLCommandBuffer> commandBuffer = [_queue commandBuffer];
複製代碼

執行

  • enqueue 順序執行
  • commit 插隊儘快執行 (若是前面有 commit 就仍是排隊等着)

監聽結果

commandBuffer.addCompletedHandler { (buffer) in
}
commandBuffer.waitUntilCompleted()

commandBuffer.addScheduledHandler { (buffer) in
}
commandBuffer.waitUntilScheduled()
複製代碼

建立 Metal 資源

接下來我須要把咱們須要繪製的內容 encode 到咱們上面生成 MTLCommandBuffer 中。我 們這裏是要畫一個三角形,因此要有三個頂點,而後須要繪製三角形的圖片。分別用 MTLBuffer 來讀入三個頂點。

在 Metal 中是歸一化的座標系,以屏幕中心爲原點(0, 0, 0),且是始終不變的。面對屏幕,你的右邊是x正軸,上面是y正軸,屏幕指向你的爲z正軸。長度單位這樣來定:窗口範圍按此單位剛好是(-1,-1)到(1,1),即屏幕左下角座標爲(-1,-1),右上角座標爲(1,1)。

因此咱們要畫在中間一個正三角形的話,三個頂點分別爲

(0.577, -0.25, 0.0, 1.0) (-0.577, -0.25, 0.0, 1.0) (0.0, 0.5, 0.0, 1.0)

Shader (着色器) 和 Pipeline (渲染管線)

能夠添加多個 Metal 文件,最後都會編譯到二進制文件default.metallib 中。 經過 Xcode 的 File - New - File 菜單,新建一個 Metal 文件。

渲染管線

着色器這邊的工做已經完成,下面咱們須要把它和咱們的 CommandBuffer 關聯起來,就須要咱們的 PipelineState 渲染管線了。

MTLCommandEncoder 編碼器

有了資源文件,渲染管線以後,咱們能夠開始作最後的步驟了,構造 MTLCommandEncoder 編碼器。 指令編碼器包括 渲染 計算 位圖複製三種編碼器。

  • MTLRenderCommandEncoder 渲染 3D 編碼器
  • MTLComputeCommandEncoder 計算編碼器
  • MTLBlitCommandEncoder 位圖複製編碼器 拷貝 buffer texture 同時也能生成 mipmap

這裏咱們是爲了渲染一個三角形,因此這裏用的是 MTLRenderCommandEncoder 。

繪製

編碼結束以後,就能夠開始準備提交到 GPU 了。 配置須要繪製的 Layer,獲取 MTKView 的 Layer 就能夠。

如今全部的工做就都完成了,運行項目就能夠看到三角形了

調試

如何進行調試和評估性能呢? 這裏 iOS 提供了兩個工具

  • Xcode 中的 Capute GPU Frame
  • Instruments 中的 Metal System Trace

總結

在 WWDC 2015,蘋果發佈了 Metal Performance Shaders (MPS) 框架,iOS 9 上的一組高性能的圖像濾鏡,其實就是邊寫好的 Shaders,提供了優秀的圖像處理能力。同時還提供了高性能的矩陣運算的 Shaders ,能用來作機器學習的運算,在 GPU 上運行卷積神經網絡。

提醒廣大網友

Metal 是一門特別深的技術,可能須要你花費你半年左右的時間去學習它,但願有鍥而不捨的情深。

相關文章
相關標籤/搜索