《Metal》官方文檔005 --資源對象:緩沖區(qū)和紋理

資源對象:緩沖區(qū)和紋理

本章介紹MTLResource用于存儲未格式化存儲器和格式化圖像數(shù)據(jù)的
Metal資源對象(MTLResource)。有兩種類型的MTLResource對象:

  • MTLBuffer表示可以包含任何類型數(shù)據(jù)的未格式化內(nèi)存的分配泽台。
    緩沖區(qū)通常用于頂點喂江,著色器和計算狀態(tài)數(shù)據(jù)隐锭。

  • MTLTexture表示具有指定紋理類型和像素格式的格式化圖像數(shù)據(jù)的分配晒杈。紋理對象用作頂點,片段或計算函數(shù)的源紋理方椎,以及存儲圖形渲染輸出(即附件)聂抢。

MTLSamplerState本章還討論了對象。雖然采樣器本身不是資源棠众,但是在使用紋理對象執(zhí)行查找計算時會使用它們涛浙。

緩沖區(qū)是無類型的內(nèi)存分配

一個MTLBuffer對象表示的存儲器的分配,它可以包含任何類型的數(shù)據(jù)。

創(chuàng)建緩沖區(qū)對象

以下MTLDevice方法創(chuàng)建并返回一個MTLBuffer對象:

所有緩沖區(qū)創(chuàng)建方法都有輸入值length來指示存儲分配的大邪粗洹(以字節(jié)為單位)。所有的方法也接受一個MTLResourceOptions對象options但骨,可以修改創(chuàng)建的緩沖區(qū)的行為励七。如果值為options0,則默認值用于資源選項奔缠。

緩沖方法

MTLBuffer協(xié)議具有以下的方法:

紋理是格式化的圖像數(shù)據(jù)

一個MTLTexture對象表示可被用作用于頂點著色器資源两波,片段著色器,或計算功能格式化的圖像數(shù)據(jù)的分配闷哆,或者作為附件被用作渲染目的地腰奋。一個MTLTexture對象可以有一個以下結構:

  • 1D,2D或3D圖像

  • 一維或二維圖像陣列

  • 一個立方體六個2D圖像

MTLPixelFormat指定MTLTexture對象中各個像素的組織抱怔。像素格式在“ 像素格式”進一步討論劣坊。

創(chuàng)建一個紋理對象

以下方法創(chuàng)建并返回一個MTLTexture對象:

  • 用紋理圖像數(shù)據(jù)創(chuàng)建一個新的存儲分配對象的newTextureWithDescriptor:方法,使用對象來描述紋理的屬性屈留。MTLDevice MTLTextureMTLTextureDescriptor

  • 所述newTextureViewWithPixelFormat:的方法MTLTexture創(chuàng)建一個
    MTLTexture共享相同的存儲分配作為調(diào)用對象MTLTexture的對象局冰。由于它們共享相同的存儲,所以對新的紋理對象的像素的任何改變都會反映在調(diào)用紋理對象中灌危,反之亦然锐想。對于新創(chuàng)建的紋理,該newTextureViewWithPixelFormat:方法重新解釋調(diào)用MTLTexture
    對象的存儲分配的現(xiàn)有紋理圖像數(shù)據(jù)乍狐,就像數(shù)據(jù)以指定的像素格式存儲一樣赠摇。在MTLPixelFormat新的紋理對象必須是兼容與MTLPixelFormat原始紋理的對象。(有關普通浅蚪,打包和壓縮像素格式的詳細信息藕帜,請參閱紋理的像素格式。)

  • 所述newTextureWithDescriptor:offset:bytesPerRow:的方法MTLBuffer創(chuàng)建一個MTLTexture共享主叫的存儲分配對象MTLBuffer對象作為其紋理圖像數(shù)據(jù)惜傲。當它們共享相同的存儲時洽故,對新的紋理對象的像素的任何改變都反映在調(diào)用紋理對象中,反之亦然盗誊。在紋理和緩沖區(qū)之間共享存儲可以阻止使用某些紋理優(yōu)化时甚,例如像素閃爍或平鋪隘弊。

使用紋理描述符創(chuàng)建紋理對象

MTLTextureDescriptor定義用于創(chuàng)建MTLTexture對象的屬性,包括其圖像大谢氖省(寬度梨熙,高度和深度),像素格式刀诬,排列(陣列或多維數(shù)據(jù)集類型)和mipmap的數(shù)量咽扇。的MTLTextureDescriptor屬性創(chuàng)建一個的過程中僅使用MTLTexture對象。創(chuàng)建MTLTexture對象后陕壹,其MTLTextureDescriptor對象中的屬性更改對該紋理不再有任何影響质欲。

從描述符創(chuàng)建一個或多個紋理:
1 :創(chuàng)建MTLTextureDescriptor包含描述紋理數(shù)據(jù)的紋理屬性的自定義對象:

2:MTLTextureDescriptor通過調(diào)用對象的newTextureWithDescriptor:方法從對象創(chuàng)建一個紋理MTLDevice愤炸。在紋理創(chuàng)建之后期揪,調(diào)用replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:方法來加載紋理圖像數(shù)據(jù),如將紋理圖像數(shù)據(jù)復制到紋理中所詳述的规个。

3:要創(chuàng)建更多的MTLTexture對象凤薛,可以重用同一個MTLTextureDescriptor對象,根據(jù)需要修改描述符的屬性值诞仓。

清單3-1顯示了用于創(chuàng)建紋理描述符txDesc并為3D缤苫,64x64x64紋理設置其屬性的代碼。

清單3-1 使用自定義紋理描述符創(chuàng)建紋理對象

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];
使用紋理片

一個slice是單個一維墅拭,二維或三維紋理圖像和其所有相關的mipmap活玲。對于每個切片:

  • 由指定的基級的mipmap的大小widthheightdepth所述的屬性MTLTextureDescriptor的對象谍婉。

  • mipmap級別i的縮放大小由max(1舒憾,floor(width/ 2 i))x max(1,floor(height/ 2 i))x max(1穗熬,floor(depth/ 2 i))指定镀迂。最大mipmap級別是第一個實現(xiàn)大小為1 x 1 x 1的mipmap級別。

  • 在一個切片的mipmap級的數(shù)目可以按樓層來確定(日志2(MAX( 唤蔗,width探遵,height)))+depth 1窟赏。

所有紋理對象至少有一個切片; 立方體和數(shù)組紋理類型可能有幾個切片。在寫入和讀取紋理圖像數(shù)據(jù)的方法中箱季,將紋理圖像數(shù)據(jù)復制到紋理和從紋理復制圖像數(shù)據(jù)涯穷,slice是一個基于零的輸入值。對于1D规哪,2D或3D紋理求豫,只有一個切片,因此值slice必須為0.立方體紋理具有六個總的2D切片诉稍,從0到5尋址蝠嘉。對于1DArray和2DArray紋理類型,每個數(shù)組元素代表一片杯巨。例如蚤告,對于具有arrayLength= 10 的2DArray紋理類型,有10個總片服爷,從0到9尋址杜恰。要從整體紋理結構中選擇單個1D,2D或3D圖像仍源,首先選擇一個片段心褐,然后選擇該片段中的mipmap級別。

用方便的方法創(chuàng)建紋理描述符

對于常見的2D和多維數(shù)據(jù)集紋理笼踩,請使用以下便利方法創(chuàng)建一個MTLTextureDescriptor對象逗爹,其中的幾個屬性值自動設置:

  • texture2DDescriptorWithPixelFormat:width:height:mipmapped:
    方法MTLTextureDescriptor為2D紋理創(chuàng)建一個對象。的width和height值定義了2D紋理的尺寸嚎于。該type屬性被自動設置為MTLTextureType2D掘而,并且depth和arrayLength被設置為1。

  • textureCubeDescriptorWithPixelFormat:size:mipmapped:方法創(chuàng)建一個MTLTextureDescriptor用于立方織構于购,其中所述對象type屬性設置為MTLTextureTypeCube袍睡,width和height被設置為大小,depth并且arrayLength被設置為1肋僧。

兩種MTLTextureDescriptor方便的方法都接受一個輸入值斑胜,pixelFormat它定義了紋理的像素格式。兩種方法也接受輸入值mipmapped嫌吠,該值決定紋理圖像是否被映射止潘。(如果mipmapped是YES,紋理是mipmap居兆。)

清單3-2使用該texture2DDescriptorWithPixelFormat:width:height:mipmapped:方法64x64為未映射的2D紋理創(chuàng)建描述符對象覆山。

清單3-2 使用方便的紋理描述符創(chuàng)建紋理對象

MTLTextureDescriptor * texDesc = [MTLTextureDescriptor

texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm

width:64 height:64 mipmapped:NO];

id <MTLTexture> myTexture = [device newTextureWithDescriptor:texDesc];
從紋理復制圖像數(shù)據(jù)

要將圖像數(shù)據(jù)同步復制到或從MTLTexture對象的存儲分配中復制數(shù)據(jù),請使用以下方法:

清單3-3顯示了如何replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:從系統(tǒng)內(nèi)存textureData中的slice 0和mipmap級別的源數(shù)據(jù)中調(diào)用指定紋理圖像0拜银。

清單3-3 將圖像數(shù)據(jù)復制到紋理中

// 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];

紋理的像素格式

MTLPixelFormat指定MTLTexture對象的各個像素中的顏色,深度和模板數(shù)據(jù)存儲的組織遭垛。像素格式有三種:普通尼桶,打包,壓縮锯仪。

  • 普通格式只有常規(guī)的8位泵督,16位或32位顏色組件。每個組件被布置在增加的存儲器地址中庶喜,其中第一個列出的組件處于最低地址小腊。例如,MTLPixelFormatRGBA8Unorm是一個32位格式久窟,每個顏色分量有8位; 最低的地址包含紅色秩冈,下一個地址包含綠色,依此類推斥扛。相比之下入问,對于MTLPixelFormatBGRA8Unorm,最低的地址包含藍色犹赖,下一個地址包含綠色队他,依此類推卷仑。

  • 打包格式將多個組件組合成一個16位或32位值峻村,其中組件從最低位到最高有效位(LSB到MSB)存儲。例如锡凝,MTLPixelFormatRGB10A2Uint是一個32位打包格式粘昨,由三個10位通道(用于R,G和B)和兩位用于alpha窜锯。

  • 壓縮格式以像素塊排列张肾,每個塊的布局特定于該像素格式。壓縮像素格式只能用于2D锚扎,2D陣列或多維數(shù)據(jù)集紋理類型吞瞪。壓縮的格式不能用于創(chuàng)建1D,2DMultisample或3D紋理驾孔。

MTLPixelFormatGBGR422MTLPixelFormatBGRG422是被用于存儲像素的YUV色彩空間特殊的像素格式芍秆。這些格式僅支持2D紋理(但不包括2D數(shù)組惯疙,也不是立方體類型),沒有mipmap妖啥,甚至是偶數(shù)width霉颠。

幾個像素格式存儲具有sRGB顏色空間值的顏色組件(例如,MTLPixelFormatRGBA8Unorm_sRGBMTLPixelFormatETC2_RGB8_sRGB)荆虱。當采樣操作以sRGB像素格式引用紋理時蒿偎,Metal實現(xiàn)在采樣操作發(fā)生之前將sRGB顏色空間分量轉換為線性顏色空間。從sRGB組件S到線性分量L的轉換如下所示:

  • 如果S <= 0.04045怀读,L = S / 12.92

  • 如果S> 0.04045诉位,L =((S + 0.055)/1.055)^2.4

相反,當渲染到使用具有sRGB像素格式的紋理的可呈現(xiàn)顏色的附件時菜枷,實現(xiàn)將線性顏色值轉換為sRGB不从,如下所示:

  • 如果L <= 0.0031308,則S = L * 12.92

  • 如果L> 0.0031308犁跪,S =(1.055 * L 0.41667)^-0.055

有關渲染的像素格式的更多信息椿息,請參閱創(chuàng)建渲染通過描述符

創(chuàng)建用于紋理查找的采樣器狀態(tài)對象

一個MTLSamplerState對象定義了圖形或計算函數(shù)對MTLTexture對象執(zhí)行紋理采樣操作時使用的尋址坷衍,過濾和其他屬性寝优。采樣器描述符定義采樣器狀態(tài)對象的屬性。要創(chuàng)建采樣器狀態(tài)對象:

1: 調(diào)用對象的newSamplerStateWithDescriptor:方法MTLDevice來創(chuàng)建一個MTLSamplerDescriptor對象枫耳。

2:在MTLSamplerDescriptor對象中設置所需的值乏矾,包括過濾選項,尋址模式迁杨,最大各向異性和詳細級參數(shù)钻心。

3:MTLSamplerState通過調(diào)用創(chuàng)建描述符newSamplerStateWithDescriptor:的MTLDevice對象的方法,從采樣器描述符創(chuàng)建一個對象铅协。

您可以重用采樣器描述符對象來創(chuàng)建更多的MTLSamplerState對象捷沸,根據(jù)需要修改描述符的屬性值。描述符的屬性僅在對象創(chuàng)建過程中使用狐史。在創(chuàng)建采樣器狀態(tài)之后痒给,更改其描述符中的屬性將不再對該采樣器狀態(tài)產(chǎn)生影響。

清單3-4是一個代碼示例骏全,它創(chuàng)建MTLSamplerDescriptor并配置它以創(chuàng)建一個MTLSamplerState苍柏。非默認值為描述符對象的過濾器和地址模式屬性設置。然后該newSamplerStateWithDescriptor:方法使用采樣器描述符來創(chuàng)建采樣器狀態(tài)對象姜贡。

清單3-4 創(chuàng)建采樣器狀態(tài)對象

//創(chuàng)建MTLSamplerDescriptor

MTLSamplerDescriptor * desc = [[MTLSamplerDescriptor alloc] init];

desc.minFilter = MTLSamplerMinMagFilterLinear;

desc.magFilter = MTLSamplerMinMagFilterLinear;

desc.sAddressMode = MTLSamplerAddressModeRepeat;

desc.tAddressMode = MTLSamplerAddressModeRepeat;

//以下所有屬性都有默認值

desc.mipFilter = MTLSamplerMipFilterNotMipmapped;

desc.maxAnisotropy = 1U;

desc.normalizedCoords = YES;

desc.lodMinClamp = 0.0f;

desc.lodMaxClamp = FLT_MAX;

//創(chuàng)建MTLSamplerState

id <MTLSamplerState> sampler = [device newSamplerStateWithDescriptor:desc];

保持CPU和GPU內(nèi)存之間的一致性

CPU和GPU都可以訪問MTLResource對象的底層存儲试吁。但是,GPU從主機CPU異步運行楼咳,因此在使用主機CPU訪問這些資源的存儲時熄捍,請注意以下幾點律秃。

執(zhí)行MTLCommandBuffer對象時,MTLDevice只有在對象提交之前(并且只有這些更改)由主機CPU進行時治唤,對象才能保證觀察到主機CPU對MTLResource由該MTLCommandBuffer對象引用的任何對象的存儲分配所做的任何更改MTLCommandBuffer棒动。也就是說,MTLDevice對象可能不會觀察到主機CPU在MTLCommandBuffer對象被提交后所做的資源的更改(即對象的status屬性)宾添。MTLCommandBufferMTLCommandBufferStatusCommitted

類似地船惨,在MTLDevice對象執(zhí)行MTLCommandBuffer對象之后,MTLDevice如果命令緩沖區(qū)已經(jīng)完成執(zhí)行(即缕陕,對象的status屬性)粱锐,則主機CPU只能保證觀察對象對該命令緩沖區(qū)引用的任何資源的存儲分配的任何更改MTLCommandBuffer是MTLCommandBufferStatusCompleted)。

下一頁

上一頁

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扛邑,一起剝皮案震驚了整個濱河市怜浅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔬崩,老刑警劉巖恶座,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沥阳,居然都是意外死亡跨琳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門桐罕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脉让,“玉大人,你說我怎么就攤上這事功炮〗η保” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵薪伏,是天一觀的道長滚澜。 經(jīng)常有香客問我,道長毅该,這世上最難降的妖魔是什么博秫? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任潦牛,我火速辦了婚禮眶掌,結果婚禮上,老公的妹妹穿的比我還像新娘巴碗。我一直安慰自己朴爬,他們只是感情好,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布橡淆。 她就那樣靜靜地躺著召噩,像睡著了一般母赵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上具滴,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天凹嘲,我揣著相機與錄音,去河邊找鬼构韵。 笑死周蹭,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的疲恢。 我是一名探鬼主播凶朗,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼显拳!你這毒婦竟也來了棚愤?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤杂数,失蹤者是張志新(化名)和其女友劉穎宛畦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揍移,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡刃永,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了羊精。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斯够。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喧锦,靈堂內(nèi)的尸體忽然破棺而出读规,到底是詐尸還是另有隱情,我是刑警寧澤燃少,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布束亏,位于F島的核電站,受9級特大地震影響阵具,放射性物質發(fā)生泄漏碍遍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一阳液、第九天 我趴在偏房一處隱蔽的房頂上張望怕敬。 院中可真熱鬧,春花似錦帘皿、人聲如沸东跪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虽填。三九已至丁恭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間斋日,已是汗流浹背牲览。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恶守,地道東北人竭恬。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像熬的,于是被迫代替她去往敵國和親痊硕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容