版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.11.04 星期日 |
前言
很多做視頻和圖像的,相信對這個框架都不是很陌生,它渲染高級3D圖形,并使用GPU執行數據并行計算。接下來的幾篇我們就詳細的解析這個框架。感興趣的看下面幾篇文章。
1. Metal框架詳細解析(一)—— 基本概覽
2. Metal框架詳細解析(二) —— 器件和命令(一)
3. Metal框架詳細解析(三) —— 渲染簡單的2D三角形(一)
4. Metal框架詳細解析(四) —— 關于GPU Family 4(一)
5. Metal框架詳細解析(五) —— 關于GPU Family 4之關于Imageblocks(二)
6. Metal框架詳細解析(六) —— 關于GPU Family 4之關于Tile Shading(三)
7. Metal框架詳細解析(七) —— 關于GPU Family 4之關于光柵順序組(四)
8. Metal框架詳細解析(八) —— 關于GPU Family 4之關于增強的MSAA和Imageblock采樣覆蓋控制(五)
9. Metal框架詳細解析(九) —— 關于GPU Family 4之關于線程組共享(六)
10. Metal框架詳細解析(十) —— 基本組件(一)
11. Metal框架詳細解析(十一) —— 基本組件之器件選擇 - 圖形渲染的器件選擇(二)
12. Metal框架詳細解析(十二) —— 基本組件之器件選擇 - 計算處理的設備選擇(三)
13. Metal框架詳細解析(十三) —— 計算處理(一)
14. Metal框架詳細解析(十四) —— 計算處理之你好,計算(二)
15. Metal框架詳細解析(十五) —— 計算處理之關于線程和線程組(三)
16. Metal框架詳細解析(十六) —— 計算處理之計算線程組和網格大小(四)
17. Metal框架詳細解析(十七) —— 工具、分析和調試(一)
18. Metal框架詳細解析(十八) —— 工具、分析和調試之Metal GPU Capture(二)
19. Metal框架詳細解析(十九) —— 工具、分析和調試之GPU活動監視器(三)
20. Metal框架詳細解析(二十) —— 工具、分析和調試之關于Metal著色語言文件名擴展名、使用Metal的命令行工具構建庫和標記Metal對象和命令(四)
21. Metal框架詳細解析(二十一) —— 基本課程之基本緩沖區(一)
22. Metal框架詳細解析(二十二) —— 基本課程之基本紋理(二)
23. Metal框架詳細解析(二十三) —— 基本課程之CPU和GPU同步(三)
24. Metal框架詳細解析(二十四) —— 基本課程之參數緩沖 - 基本參數緩沖(四)
25. Metal框架詳細解析(二十五) —— 基本課程之參數緩沖 - 帶有數組和資源堆的參數緩沖區(五)
26. Metal框架詳細解析(二十六) —— 基本課程之參數緩沖 - 具有GPU編碼的參數緩沖區(六)
27. Metal框架詳細解析(二十七) —— 高級技術之圖層選擇的反射(一)
28. Metal框架詳細解析(二十八) —— 高級技術之使用專用函數的LOD(一)
29. Metal框架詳細解析(二十九) —— 高級技術之具有參數緩沖區的動態地形(一)
30. Metal框架詳細解析(三十) —— 延遲照明(一)
31. Metal框架詳細解析(三十一) —— 在視圖中混合Metal和OpenGL渲染(一)
32. Metal框架詳細解析(三十二) —— Metal渲染管道教程(一)
33. Metal框架詳細解析(三十三) —— Metal渲染管道教程(二)
34. Metal框架詳細解析(三十四) —— Hello Metal! 一個簡單的三角形的實現(一)
35. Metal框架詳細解析(三十五) —— Hello Metal! 一個簡單的三角形的實現(二)
36. Metal框架詳細解析(三十六) —— Metal編程指南之概覽(一)
37. Metal框架詳細解析(三十七) —— Metal編程指南之基本Metal概念(二)
Command Organization and Execution Model - 命令組織和執行模型
在Metal架構中,MTLDevice協議定義了代表單個GPU的接口。 MTLDevice
協議支持詢問設備屬性的方法,用于創建其他特定于設備的對象(如緩沖區和紋理),以及用于編碼和排隊渲染和計算命令以提交給GPU執行。
命令隊列由命令緩沖區隊列組成,命令隊列組織這些命令緩沖區的執行順序。命令緩沖區包含用于在特定設備上執行的編碼命令。命令編碼器將渲染,計算和blitting命令附加到命令緩沖區,并且最終提交那些命令緩沖區以在設備上執行。
MTLCommandQueue協議定義了命令隊列的接口,主要支持創建命令緩沖區對象的方法。 MTLCommandBuffer協議定義了命令緩沖區的接口,并提供了創建命令編碼器,排隊命令緩沖區以執行,檢查狀態和其他操作的方法。MTLCommandBuffer
協議支持以下命令編碼器類型,這些接口用于將不同類型的GPU工作負載編碼到命令緩沖區中:
- MTLRenderCommandEncoder協議對單個渲染過程的圖形(3D)渲染命令進行編碼。
- MTLComputeCommandEncoder協議對數據并行計算工作負載進行編碼。
-
MTLBlitCommandEncoder協議對緩沖區和紋理之間的簡單復制操作以及
mipmap
生成等實用程序操作進行編碼。
在任何時間點,只有一個命令編碼器可以處于活動狀態,并將命令附加到命令緩沖區中。必須先結束每個命令編碼器,然后才能創建另一個命令編碼器以與同一命令緩沖區一起使用。 “每個命令緩沖區的一個活動命令編碼器”規則的一個例外是MTLParallelRenderCommandEncoder協議,在 Encoding a Single Rendering Pass Using Multiple Threads中討論。
完成所有編碼后,您將提交MTLCommandBuffer
對象本身,該對象將命令緩沖區標記為可供GPU執行。相對于已在命令隊列中的其他MTLCommandBuffer
對象,MTLCommandQueue
協議控制何時執行提交的MTLCommandBuffer
對象中的命令。
圖2-1顯示了命令隊列,命令緩沖區和命令編碼器對象如何密切相關。圖頂部的每列組件(緩沖區,紋理,采樣器,深度和模板狀態,管道狀態)表示特定于命令編碼器的資源和狀態。
The Device Object Represents a GPU - 代表GPU的設備對象
MTLDevice對象表示可以執行命令的GPU。 MTLDevice
協議具有創建新命令隊列,從內存分配緩沖區,創建紋理以及查詢設備功能的方法。 要在系統上獲取首選系統設備,請調用MTLCreateSystemDefaultDevice函數。
Transient and Non-transient Objects in Metal - Metal中的瞬態和非瞬態對象
Metal中的一些對象設計為瞬態且極輕量級,而其他對象則更昂貴且可能持續很長時間,可能是應用程序的生命周期。
命令緩沖區和命令編碼器對象是瞬態的,僅供單次使用。 分配和釋放它們非常便宜,因此它們的創建方法返回自動釋放的對象。
以下對象不是瞬態的。 在性能敏感的代碼中重用這些對象,并避免重復創建它們。
Command queues
Data buffers
Textures
Sampler states
Libraries
Compute states
Render pipeline states
Depth/stencil states
Command Queue - 命令隊列
命令隊列接受GPU將執行的命令緩沖區的有序列表。 發送到單個隊列的所有命令緩沖區都保證按命令緩沖區入隊的順序執行。 通常,命令隊列是線程安全的,允許同時編碼多個活動命令緩沖區。
要創建命令隊列,請調用MTLDevice
對象的newCommandQueue方法或newCommandQueueWithMaxCommandBufferCount:方法。 通常,命令隊列應該是長壽命的,因此不應重復創建和銷毀它們。
Command Buffer - 命令緩沖區
命令緩沖區存儲編碼的命令,直到緩沖區被提交以供GPU執行。單個命令緩沖區可以包含許多不同類型的編碼命令,具體取決于用于構建它的編碼器的數量和類型。在典型的應用程序中,整個渲染幀被編碼到單個命令緩沖區中,即使渲染該幀涉及多個渲染過程,計算處理函數或blit
操作。
命令緩沖區是瞬態一次性對象,不支持重用。一旦命令緩沖區被提交執行,唯一有效的操作是等待命令緩沖區被調度或完成 - 通過在Registering Handler Blocks for Command Buffer Execution中討論的同步調用或處理程序塊 - 并檢查命令緩沖區執行狀態。
命令緩沖區也是應用程序唯一可獨立跟蹤的工作單元,它們定義了由Metal Memory
模型建立的一致性邊界,詳見Resource Objects: Buffers and Textures。
1. Creating a Command Buffer - 創建命令緩沖區
要創建MTLCommandBuffer對象,請調用MTLCommandQueue的commandBuffer
方法。 MTLCommandBuffer
對象只能提交到創建它的MTLCommandQueue
對象中。
commandBuffer
方法創建的命令緩沖區保留執行所需的數據。 對于某些情況,如果在執行MTLCommandBuffer
對象期間在其他位置保留這些對象,則可以通過調用MTLCommandQueue
的commandBufferWithUnretainedReferences
方法來創建命令緩沖區。 僅對極其性能關鍵的應用程序使用commandBufferWithUnretainedReferences
方法,這些應用程序可以保證關鍵對象在應用程序的其他位置具有引用,直到命令緩沖區執行完成。 否則,可能會過早釋放不再具有其他引用的對象,并且未定義命令緩沖區執行的結果。
2. Executing Commands - 執行命令
MTLCommandBuffer
協議使用以下方法在命令隊列中建立命令緩沖區的執行順序。 命令緩沖區在提交之前不會開始執行。 一旦提交,命令緩沖區按它們入隊的順序執行。
- enqueue方法為命令隊列上的命令緩沖區保留一個位置,但不提交命令緩沖區以供執行。 最終提交此命令緩沖區時,將在相關命令隊列中任何先前排隊的命令緩沖區之后執行該命令緩沖區。
-
commit方法使命令緩沖區盡快執行,但是在提交了同一命令隊列中的任何先前排隊的命令緩沖區之后。 如果先前沒有將命令緩沖區入隊,則
commit
會進行隱含的enqueue
調用。
有關使用多線程入隊的示例,請參閱Multiple Threads, Command Buffers, and Command Encoders。
3. Registering Handler Blocks for Command Buffer Execution - 為命令緩沖區執行注冊處理塊
下面列出的MTLCommandBuffer方法監視命令執行。計劃和完成的處理程序在未定義的線程上按執行順序調用。您在這些處理程序中執行的任何代碼都應該快速完成;如果需要進行昂貴或阻塞工作,請將該工作推遲到另一個線程。
- addScheduledHandler:方法注冊在調度命令緩沖區時要調用的代碼塊。當滿足其他MTLCommandBuffer對象或系統中的其他API提交的工作之間的任何依賴關系時,將考慮調度命令緩沖區。您可以為命令緩沖區注冊多個預定處理程序。
-
waitUntilScheduled方法在調度命令緩沖區之后同步等待并返回,并且
addScheduledHandler:
方法注冊的所有處理程序都已完成。 - addCompletedHandler:方法在設備完成命令緩沖區的執行后立即注冊要調用的代碼塊。您可以為命令緩沖區注冊多個已完成的處理程序。
- waitUntilCompleted方法在設備完成命令緩沖區的執行后同步等待并返回,并且addCompletedHandler:方法注冊的所有處理程序都已返回。
presentDrawable:方法是已完成處理程序的特例。這種便捷方法在調度命令緩沖區時呈現可顯示資源(CAMetalDrawable對象)的內容。有關presentDrawable:
方法的詳細信息,請參閱Integration with Core Animation: CAMetalLayer。
4. Monitoring Command Buffer Execution Status - 檢測命令緩沖區執行狀態
只讀status屬性包含Command Buffer Status Codes中列出的MTLCommandBufferStatus
枚舉值,該值反映了此命令緩沖區生命周期中的當前調度階段。
如果執行成功完成,則只讀error屬性的值為nil
。 如果執行失敗,則status
設置為MTLCommandBufferStatusError
,error
屬性可能包含Command Buffer Error Codes中列出的值,指示失敗的原因。
Command Encoder - 命令編碼器
命令編碼器是一個瞬態對象,您可以使用該對象以GPU可以執行的格式將命令和狀態寫入單個命令緩沖區。 許多命令編碼器對象方法將命令附加到命令緩沖區。 命令編碼器處于活動狀態時,它具有為其命令緩沖區附加命令的專有權。 完成編碼命令后,調用endEncoding方法。 要編寫更多命令,請創建一個新的命令編碼器。
1. Creating a Command Encoder Object - 創建命令編碼器對象
由于命令編碼器將命令附加到特定命令緩沖區,因此您可以通過從要使用它的MTLCommandBuffer對象中請求命令來創建命令編碼器。 使用以下MTLCommandBuffer
方法創建每種類型的命令編碼器:
- renderCommandEncoderWithDescriptor:方法創建一個MTLRenderCommandEncoder對象,用于圖形渲染到MTLRenderPassDescriptor中的附件。
- computeCommandEncoder方法為數據并行計算創建MTLComputeCommandEncoder對象。
- blitCommandEncoder方法為內存操作創建MTLBlitCommandEncoder對象。
-
parallelRenderCommandEncoderWithDescriptor:方法創建一個MTLParallelRenderCommandEncoder對象,該對象使多個
MTLRenderCommandEncoder
對象能夠在不同的線程上運行,同時仍然呈現給共享MTLRenderPassDescriptor中指定的附件。
2. Render Command Encoder - 渲染命令編碼器
可以根據rendering pass
來描述圖形渲染。 MTLRenderCommandEncoder對象表示與單個渲染過程關聯的渲染狀態和繪制命令。 MTLRenderCommandEncoder
需要關聯的MTLRenderPassDescriptor(在Creating a Render Pass Descriptor中描述),其包括用作渲染命令的目標的顏色,深度和模板附件。MTLRenderCommandEncoder
具有以下方法:
- 指定包含頂點,片段或紋理圖像數據的圖形資源,例如緩沖區和紋理對象
- 指定包含已編譯渲染狀態的MTLRenderPipelineState對象,包括頂點和片段著色器
- 指定固定功能狀態,包括視口,三角形填充模式,剪刀矩形,深度和模板測試以及其他值
- 繪制3D基元
有關MTLRenderCommandEncoder
協議的詳細信息,請參閱Graphics Rendering: Render Command Encoder。
3. Compute Command Encoder - 計算命令編碼器
對于數據并行計算,MTLComputeCommandEncoder協議提供了對命令緩沖區中的命令進行編碼的方法,該命令緩沖區可以指定計算函數及其參數(例如,紋理,緩沖區和采樣器狀態)并調度計算函數以供執行。 要創建計算命令編碼器對象,請使用MTLCommandBuffer的computeCommandEncoder方法。 有關MTLComputeCommandEncoder
方法和屬性的詳細信息,請參閱Data-Parallel Compute Processing: Compute Command Encoder。
4. Blit Command Encoder - Blit命令編碼器
MTLBlitCommandEncoder協議具有為緩沖區(MTLBuffer)和紋理(MTLTexture)之間的內存復制操作附加命令的方法。 MTLBlitCommandEncoder
協議還提供了使用純色填充紋理并生成mipmap
的方法。 要創建blit
命令編碼器對象,請使用MTLCommandBuffer
的blitCommandEncoder方法。 有關MTLBlitCommandEncoder
方法和屬性的詳細信息,請參閱Buffer and Texture Operations: Blit Command Encoder。
5. Multiple Threads, Command Buffers, and Command Encoders - 多線程,命令緩沖區和命令編碼器
大多數應用程序使用單個線程在單個命令緩沖區中為單個幀編碼渲染命令。在每個幀的末尾,您提交命令緩沖區,它既調度又開始執行命令。
如果要并行化命令緩沖區編碼,則可以同時創建多個命令緩沖區,并使用單獨的線程對每個命令緩沖區進行編碼。如果事先知道命令緩沖區應該以什么順序執行,那么MTLCommandBuffer的enqueue方法可以在命令隊列中聲明執行順序,而無需等待命令被編碼和提交。否則,當提交命令緩沖區時,它將在命令隊列中任何先前排隊的命令緩沖區之后分配一個位置。
只有一個CPU線程可以訪問命令緩沖區。多線程應用程序可以使用每個命令緩沖區一個線程來并行創建多個命令緩沖區。
圖2-2顯示了一個包含三個線程的示例。每個線程都有自己的命令緩沖區。對于每個線程,一次一個命令編碼器可以訪問其相關的命令緩沖區。圖2-2還顯示了每個命令緩沖區接收來自不同命令編碼器的命令。完成編碼后,調用命令編碼器的endEncoding方法,然后新的命令編碼器對象可以開始將命令編碼到命令緩沖區。
MTLParallelRenderCommandEncoder對象允許在多個命令編碼器之間分解單個渲染過程并將其分配給單獨的線程。 有關MTLParallelRenderCommandEncoder的更多信息,請參閱Encoding a Single Rendering Pass Using Multiple Threads。
后記
本篇主要講述了Metal編程指南之命令組織和執行模型,感興趣的給個贊或者關注~~~