版本記錄
版本號 | 時間 |
---|---|
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概念(二)
38. Metal框架詳細解析(三十八) —— Metal編程指南之命令組織和執行模型(三)
39. Metal框架詳細解析(三十九) —— Metal編程指南之資源對象:緩沖區和紋理(四)
Functions and Libraries - 函數和庫
本章介紹如何創建MTLFunction對象作為Metal
著色器或計算函數的引用,以及如何使用MTLLibrary對象組織和訪問函數。
MTLFunction Represents a Shader or Compute Function - MTLFunction表示著色器或計算函數
MTLFunction對象表示以Metal著色語言編寫并在GPU上作為圖形或計算管道的一部分執行的單個函數。有關Metal shading language
的詳細信息,請參閱Metal Shading Language Guide
。
要在Metal運行時和使用Metal著色語言編寫的圖形或計算函數之間傳遞數據或狀態,可以為紋理,緩沖區和采樣器分配參數索引。參數索引標識Metal運行時和Metal著色代碼正在引用哪個紋理,緩沖區或采樣器。
對于渲染過程,您可以指定MTLFunction
對象以用作MTLRenderPipelineDescriptor對象中的頂點或片段著色器,如 Creating a Render Pipeline State中所述。對于計算傳遞,在為目標設備創建MTLComputePipelineState對象時指定MTLFunction
對象,如Specify a Compute State and Resources for a Compute Command Encoder中所述。
A Library Is a Repository of Functions - 庫是函數的倉庫
MTLLibrary對象表示一個或多個MTLFunction對象的存儲庫。 單個MTLFunction
對象表示使用著色語言編寫的一個Metal
函數。 在Metal著色語言源代碼中,任何使用Metal函數限定符(vertex, fragment, or kernel)
的函數都可以由庫中的MTLFunction
對象表示。 沒有這些函數限定符之一的Metal函數不能由MTLFunction
對象直接表示,盡管它可以由著色器中的另一個函數調用。
可以從以下任一來源創建庫中的MTLFunction
對象:
- 在應用程序構建過程中編譯為二進制庫格式的Metal著色語言代碼。
- 包含Metal著色語言源代碼的文本字符串,由應用程序在運行時編譯。
1. Creating a Library from Compiled Code - 從編譯代碼創建庫
為了獲得最佳性能,請在Xcode的應用程序構建過程中將Metal著色語言源代碼編譯到庫文件中,這樣可以避免在應用程序運行時編譯函數源的成本。 要從庫二進制文件創建MTLLibrary對象,請調用以下MTLDevice方法之一:
- newDefaultLibrary檢索為主包構建的庫,該庫包含應用程序Xcode項目中的所有著色器和計算函數。
-
newLibraryWithFile:error:獲取庫文件的路徑并返回包含存儲在該庫文件中的所有函數的
MTLLibrary
對象。 -
newLibraryWithData:error:獲取包含庫中函數代碼的二進制
blob
,并返回MTLLibrary
對象。
有關在構建過程中編譯Metal著色語言源代碼的更多信息,請參閱Creating Libraries During the App Build Process。
2. Creating a Library from Source Code - 從源代碼創建庫
要從可能包含多個函數的Metal著色語言源代碼字符串創建MTLLibrary,請調用以下MTLDevice方法之一。 這些方法在創建庫時編譯源代碼。 要指定要使用的編譯器選項,請在MTLCompileOptions對象中設置屬性。
-
newLibraryWithSource:options:error:從輸入字符串同步編譯源代碼以創建
MTLFunction
對象,然后返回包含它們的MTLLibrary
對象。 -
newLibraryWithSource:options:completionHandler:異步編譯輸入字符串中的源代碼以創建
MTLFunction
對象,然后返回包含它們的MTLLibrary
對象。completionHandler
是在完成對象創建時調用的代碼塊。
3. Getting a Function from a Library - 從庫中獲取函數
MTLLibrary
的newFunctionWithName:方法返回具有所請求名稱的MTLFunction
對象。 如果在庫中找不到使用Metal著色語言函數限定符的函數的名稱,則newFunctionWithName:
返回nil
。
Listing 4-1
使用MTLDevice
的newLibraryWithFile:error:
方法通過其完整路徑名定位庫文件,并使用其內容創建具有一個或多個MTLFunction
對象的MTLLibrary
對象。 加載文件時的任何錯誤都會返回error
。 然后MTLLibrary
的newFunctionWithName:
方法創建一個MTLFunction
對象,該對象表示源代碼中名為my_func
的函數。 返回的函數對象myFunc
現在可以在應用程序中使用
Listing 4-1 Accessing a Function from a Library
NSError *errors;
id <MTLLibrary> library = [device newLibraryWithFile:@"myarchive.metallib"
error:&errors];
id <MTLFunction> myFunc = [library newFunctionWithName:@"my_func"];
Determining Function Details at Runtime - 在運行時確定函數詳細信息
由于MTLFunction對象的實際內容是由可能在創建MTLFunction
對象之前編譯的圖形著色器或計算函數定義的,因此其源代碼可能無法直接用于應用程序。您可以在運行時查詢以下MTLFunction
屬性:
- name,包含函數名稱的字符串。
- functionType,指示函數是聲明為頂點,片段還是計算函數。
- vertexAttributes,一個MTLVertexAttribute對象數組,描述頂點屬性數據在內存中的組織方式以及如何將其映射到頂點函數參數。有關更多詳細信息,請參閱Vertex Descriptor for Data Organization。
MTLFunction
不提供對函數參數的訪問。可以在創建管道狀態期間獲得顯示著色器或計算函數參數的細節的反射對象(MTLRenderPipelineReflection或MTLComputePipelineReflection,具體取決于命令編碼器的類型)。有關創建管道狀態和反射對象的詳細信息,請參閱Creating a Render Pipeline State或Creating a Compute Pipeline State。如果不使用反射數據,請避免獲取反射數據。
反射對象包含命令編碼器支持的每種函數類型的MTLArgument對象數組。對于MTLComputeCommandEncoder,MTLComputePipelineReflection在arguments屬性中有一個MTLArgument對象數組,對應于其計算函數的參數。對于MTLRenderCommandEncoder,MTLRenderPipelineReflection有兩個屬性,vertexArguments和fragmentArguments,它們分別對應于頂點函數參數和片段函數參數。
并非函數的所有參數都存在于反射對象中。反射對象僅包含具有關聯資源的參數,但不包含使用[[stage_in]]
限定符或內置[[vertex_id]]
或[[attribute_id]]
限定符聲明的參數。
Listing 4-2
顯示了如何獲取反射對象(在此示例中為MTLComputePipelineReflection),然后在其arguments屬性中迭代MTLArgument對象。
Listing 4-2 Iteration Through Function Arguments
MTLComputePipelineReflection* reflection;
id <MTLComputePipelineState> computePS = [device
newComputePipelineStateWithFunction:func
options:MTLPipelineOptionArgumentInfo
reflection:&reflection error:&error];
for (MTLArgument *arg in reflection.arguments) {
// process each MTLArgument
}
MTLArgument屬性顯示著色語言函數的參數的詳細信息。
- name屬性只是參數的名稱。
- active是一個布爾值,指示是否可以忽略該參數。
-
index是其對應參數表中從零開始的位置。例如,對于
[[buffer(2)]]
,index
為2
。 - access描述任何訪問限制,例如,讀取或寫入訪問限定符。
-
type由著色語言限定符指示,例如
[[buffer(n)]]
,[[texture(n)]]
,[[sampler(n)]]
或[[threadgroup(n)]]
。
type確定哪些其他MTLArgument屬性是相關的。
- 如果
type
是MTLArgumentTypeTexture,則textureType屬性指示整體紋理類型(例如著色語言中的texture1d_array
,texture2d_ms
和texturecube
類型),textureDataType屬性指示組件數據類型(例如half
,float
,int
或uint
) )。 - 如果
type
是MTLArgumentTypeThreadgroupMemory,則threadgroupMemoryAlignment和threadgroupMemoryDataSize屬性是相關的。 - 如果
type
是MTLArgumentTypeBuffer,則bufferAlignment, bufferDataSize, bufferDataType和bufferStructType屬性是相關的。
如果buffer參數是結構體(即bufferDataType
是MTLDataTypeStruct),則bufferStructType
屬性包含表示結構的MTLStructType,而bufferDataSize
包含結構的大小(以字節為單位)。如果buffer
參數是一個數組(或指向數組的指針),則bufferDataType
指示元素的數據類型,bufferDataSize
包含一個數組元素的大小(以字節為單位)。
Listing 4-3
深入研究MTLStructType對象,以檢查struct成員的詳細信息,每個結構成員由MTLStructMember對象表示。結構成員可以是簡單類型,數組或嵌套結構。如果成員是嵌套結構,則調用MTLStructMember
的structType方法以獲取表示結構的MTLStructType
對象,然后遞歸深入分析以進行分析。如果該成員是數組,請使用MTLStructMember
的arrayType方法獲取表示它的MTLArrayType。然后檢查它的MTLArrayType
的elementType屬性。如果elementType
是MTLDataTypeStruct,則調用elementStructType方法以獲取結構并繼續深入查看其成員。如果elementType
是MTLDataTypeArray,則調用elementArrayType方法以獲取子數組并進一步分析它。
Listing 4-3 Processing a Struct Argument
MTLStructType *structObj = [arg.bufferStructType];
for (MTLStructMember *member in structObj.members) {
// process each MTLStructMember
if (member.dataType == MTLDataTypeStruct) {
MTLStructType *nestedStruct = member.structType;
// recursively drill down into the nested struct
}
else if (member.dataType == MTLDataTypeArray) {
MTLStructType *memberArray = member.arrayType;
// examine the elementType and drill down, if necessary
}
else {
// member is neither struct nor array
// analyze it; no need to drill down further
}
}
后記
本篇主要講述了Metal編程指南之函數和庫,感興趣的給個贊或者關注~~~