1.Metal 是一個(gè)和 OpenGL ES 類似的面向底層的圖形編程接口榛了,可以直接操作GPU;支持iOS和OS X悦荒,提供圖形渲染和通用計(jì)算能力待秃。(不支持模擬器)-
Metal框架支持GPU硬件加速、高級(jí)3D圖形渲染以及大數(shù)據(jù)并行運(yùn)算。且提供了先進(jìn)而精簡的API來確崩铣啵框架的細(xì)粒度(fine-grain)轮洋,并且在組織架構(gòu)、程序處理抬旺、圖形呈現(xiàn)弊予、運(yùn)算指令以及指令相關(guān)數(shù)據(jù)資源的管理上都支持底層控制。其核心目的是盡可能的減少CPU開銷开财,而將運(yùn)行時(shí)產(chǎn)生的大部分負(fù)載交由GPU承擔(dān)
MTLDevice :對(duì)象代表GPU汉柒,通常使用MTLCreateSystemDefaultDevice獲取默認(rèn)的GPU;
MTLCommandQueue:由device創(chuàng)建责鳍,用于創(chuàng)建和組織MTLCommandBuffer碾褂,保證指令(MTLCommandBuffer)有序地發(fā)送到GPU;MTLCommandBuffer會(huì)提供一些encoder薇搁,包括編碼繪制指令的MTLRenderCommandEncoder斋扰、編碼計(jì)算指令的MTLComputeCommandEncoder渡八、編碼緩存紋理拷貝指令的MTLBlitCommandEncoder啃洋。對(duì)于一個(gè)commandBuffer,只有調(diào)用encoder的結(jié)束操作屎鳍,才能進(jìn)行下一個(gè)encoder的創(chuàng)建宏娄,同時(shí)可以設(shè)置執(zhí)行完指令的回調(diào)。
MTLRenderCommandEncoder逮壁,MTLComputeCommandEncoder孵坚,MTLBlitCommandEncoder:分別代表渲染,計(jì)算窥淆,拷貝指令
PipelineState:也是由device創(chuàng)建其包含了頂點(diǎn)著色器和片元著色器以及并行運(yùn)算卖宠,動(dòng)態(tài)的供CommandEncoder使用,一個(gè)state代表一組著色器
Texture和Buffer:由device創(chuàng)建忧饭,動(dòng)態(tài)的供CommandEncoder使用
Threadgroups:結(jié)構(gòu)體扛伍,是并行計(jì)算著?器的線程組數(shù)量,動(dòng)態(tài)的供MTLComputeCommandEncoder使用
GPUs的類型很多词裤,每一種都有各自的接收和執(zhí)行指令方式刺洒,在MTLCommandEncoder把指令進(jìn)行封裝后,MTLCommandBuffer再做聚合到一次提交里吼砂。
暫態(tài)和?非暫態(tài)對(duì)象:
暫態(tài)對(duì)象:
在Metal中有些對(duì)象被設(shè)計(jì)成暫態(tài)逆航,使?用它們?非常輕量,下?面這些對(duì)象是暫態(tài)的渔肩,被設(shè)計(jì)來?一次性使?用因俐,它們的創(chuàng)建和銷毀的成本都?非常廉價(jià),它們的創(chuàng)建?方法都返回autoreleased對(duì)象。
Command Buffers?
Command Encoders
非暫態(tài)對(duì)象:
下?面這些對(duì)象是?非暫態(tài)的女揭,在性能相關(guān)的代碼?里應(yīng)該盡量重?用之蚤假,避免反復(fù)創(chuàng)建
Command Queues?
Buffers
Textures
Sampler States Libraries?
Compute States
Render Pipeline States?
Depth/Stencil States
并行計(jì)算
通用圖形計(jì)算是general-purpose GPU,簡稱GPGPU吧兔。
GPU可以用于加密磷仰、機(jī)器學(xué)習(xí)、金融等境蔼,圖形繪制和圖形計(jì)算并不是互斥的灶平,Metal可以同時(shí)使用計(jì)算管道進(jìn)行圖形計(jì)算,并且用渲染管道進(jìn)行渲染箍土。
計(jì)算管道只有一個(gè)步驟逢享,就是kernel function(內(nèi)核函數(shù)),內(nèi)核函數(shù)直接讀取并寫入資源吴藻,不像渲染管道需要經(jīng)過多個(gè)步驟瞒爬;
MTLComputePipelineState 代表一個(gè)計(jì)算處理管道,只需要一個(gè)內(nèi)核函數(shù)就可以創(chuàng)建沟堡,相比之下侧但,渲染管道需要頂點(diǎn)和片元兩個(gè)處理函數(shù);
每次內(nèi)核函數(shù)執(zhí)行航罗,都會(huì)有一個(gè)唯一的gid值禀横;
內(nèi)核函數(shù)的執(zhí)行次數(shù)需要事先指定,這個(gè)次數(shù)由格子大小決定粥血。
threadgroup 指的是設(shè)定的處理單元柏锄,這個(gè)值要根據(jù)具體的設(shè)備進(jìn)行區(qū)別,但必須是足夠小的复亏,能讓GPU執(zhí)行趾娃;
threadgroupCount 是需要處理的次數(shù),一般來說threadgroupCount*threadgroup=需要處理的大小缔御。
上圖左邊是一幅1024*768個(gè)像素大小的圖片抬闷,那么共需要1024*768個(gè)線程;我們將這些線程分為32*48個(gè)線程組刹淌,每個(gè)線程組有32*16個(gè)線程(上右圖)
Metal Language
1. Metal 與 C++ 11.0
Metal 這門語言是基于C++ 11.0標(biāo)準(zhǔn)設(shè)計(jì)的.它在C++基礎(chǔ)是行多了一些拓展和限制.下面我們可以簡單介紹介紹Metal著色語言與C++11.0 相比之下的修改和限制:
1.1 Metal 語言支持重載,如果C++11.0,包括方法重載規(guī)則,可以包括參數(shù)的地址空間描述符.Metal著色語言中的標(biāo)識(shí)為圖形渲染入口函數(shù)或是并行計(jì)算入口函數(shù)的不可以被重載
1.2?Templates 模塊
Metal 著色語言支持的模板如圖C++11.0 一樣.
1.3 Preprocessing Directives 預(yù)編譯指令
Metal 和 C++11.0 一樣支持預(yù)編譯指令
1.4? Restrictions 限制
如下的C++11.0特性在Metal 著色語言中是不支持的;
Lambda表達(dá)式
遞歸函數(shù)調(diào)用
動(dòng)態(tài)轉(zhuǎn)換操作符
類型識(shí)別
對(duì)象創(chuàng)建(new)和釋放(delloc)操作符
操作符noexcept
goto跳轉(zhuǎn)
變量存儲(chǔ)修飾符register和thread_local
虛函數(shù)修飾符
派生類
異常處理
1.5 Metal著色語言是有對(duì)于指針的使用限制
1.6Metal圖形和并行計(jì)算函數(shù)用到的入?yún)⑷绻侵羔槺仨毷褂玫刂房臻g修飾符(device,threadgroup,constant)
1.7 不支持函數(shù)指針
1.8 Metal函數(shù)名不能命名為main函數(shù)
基本數(shù)據(jù)類型:
Metal的數(shù)據(jù)類型包含表示向量和矩陣的類型,原子數(shù)據(jù)類型,緩存,紋理,采樣器,數(shù)組,自定義結(jié)構(gòu)體,還會(huì)描述類型對(duì)齊和類型轉(zhuǎn)換.
1. 標(biāo)量數(shù)據(jù)類型:
Metal 支持如下表格的類型,但是它不支持double,long,unsigned long?,long long,unsigned long long,long double
Metal 數(shù)據(jù)類型
注意
f或者F,表示單精度浮點(diǎn)類型字面量,(例如,0.5f 或 0.5F);
h或者H,表示半單精度浮點(diǎn)類型字面量,(例如,0.5h 或 0.5H);
u或者U,表示無符號(hào)整形字面量.
2.向量和矩陣數(shù)據(jù)類型
Metal著色語言通過系統(tǒng)向量數(shù)學(xué)庫支持一系列的向量和矩陣數(shù)據(jù)類型.
向量支持如下類型
booln
charn
shortn
intn
ucharn
ushortn
uintn
halfn
floatn
向量中的n,指的是維度.假設(shè)2,表示二維
矩陣支持如下類型
halfnxm
floatnxm
nxm分別指的是矩陣的行數(shù)和列數(shù).
3. 訪問向量的分量
//基本數(shù)據(jù)類型
bool a = true;
char b = 5;
int? d = 15;
size_t c = 1;
ptrdiff_t f = 2;
//向量
bool2 A= [1,2];
float4 pos = float4(1.0,2.0,3.0,4.0);
float x = pos[0];
float y = pos[1];
float4 VB;
for(int i = 0; i < 4 ; i++)
? ? VB[i] = pos[i] * 2.0f;
Metal 支持(,)作為選擇向量分量進(jìn)行訪問操作符.可以使用坐標(biāo)分量或者是顏色分量的字母來存取向量.向量名.xyzw,或是向量名.rgba;
//通過向量字母來獲取元素
int4 test = int4(1,2,3,4);
int a = test.x;
int b = test.y;
int c = test.z;
int d = test.w;
int e = test.r;
int f = test.g;
int g = test.b;
int h = test.a;
????????????緩存:
函數(shù)修飾符:
變量和參數(shù)修飾符:
注意:device是可變的饶氏,constant是不可變的
用于緩存、紋理有勾、采樣器的尋址修飾符:
index表示了一個(gè)緩存疹启、紋理、采樣器的位置蔼卡,它是一個(gè)索引喊崖;
[[position]] 表示頂點(diǎn)坐標(biāo)挣磨,為什么必須要指定postion不指定textureCoordinate等?因?yàn)轫旤c(diǎn)著色器要使用postion而其它是要傳遞給片元著色器的荤懂,?[[ vertex_id ]]表示頂點(diǎn)數(shù)組中某一個(gè)頂點(diǎn)坐標(biāo)
頂點(diǎn)著色器除了用?[[ vertex_id ]]和?[[ buffer(index)?]]來定位單個(gè)頂點(diǎn)茁裙,還可以使用[[?stage_in?]]和[?attribute(index) ]、?[[ vertex_id ]]來定位單個(gè)頂點(diǎn)