pixel_formats.mm 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. /**************************************************************************/
  2. /* pixel_formats.mm */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. /**************************************************************************/
  31. /* */
  32. /* Portions of this code were derived from MoltenVK. */
  33. /* */
  34. /* Copyright (c) 2015-2023 The Brenwill Workshop Ltd. */
  35. /* (http://www.brenwill.com) */
  36. /* */
  37. /* Licensed under the Apache License, Version 2.0 (the "License"); */
  38. /* you may not use this file except in compliance with the License. */
  39. /* You may obtain a copy of the License at */
  40. /* */
  41. /* http://www.apache.org/licenses/LICENSE-2.0 */
  42. /* */
  43. /* Unless required by applicable law or agreed to in writing, software */
  44. /* distributed under the License is distributed on an "AS IS" BASIS, */
  45. /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
  46. /* implied. See the License for the specific language governing */
  47. /* permissions and limitations under the License. */
  48. /**************************************************************************/
  49. #import "pixel_formats.h"
  50. #import "metal_utils.h"
  51. #if TARGET_OS_IPHONE || TARGET_OS_TV
  52. #if !(__IPHONE_OS_VERSION_MAX_ALLOWED >= 160400) // iOS/tvOS 16.4
  53. #define MTLPixelFormatBC1_RGBA MTLPixelFormatInvalid
  54. #define MTLPixelFormatBC1_RGBA_sRGB MTLPixelFormatInvalid
  55. #define MTLPixelFormatBC2_RGBA MTLPixelFormatInvalid
  56. #define MTLPixelFormatBC2_RGBA_sRGB MTLPixelFormatInvalid
  57. #define MTLPixelFormatBC3_RGBA MTLPixelFormatInvalid
  58. #define MTLPixelFormatBC3_RGBA_sRGB MTLPixelFormatInvalid
  59. #define MTLPixelFormatBC4_RUnorm MTLPixelFormatInvalid
  60. #define MTLPixelFormatBC4_RSnorm MTLPixelFormatInvalid
  61. #define MTLPixelFormatBC5_RGUnorm MTLPixelFormatInvalid
  62. #define MTLPixelFormatBC5_RGSnorm MTLPixelFormatInvalid
  63. #define MTLPixelFormatBC6H_RGBUfloat MTLPixelFormatInvalid
  64. #define MTLPixelFormatBC6H_RGBFloat MTLPixelFormatInvalid
  65. #define MTLPixelFormatBC7_RGBAUnorm MTLPixelFormatInvalid
  66. #define MTLPixelFormatBC7_RGBAUnorm_sRGB MTLPixelFormatInvalid
  67. #endif
  68. #define MTLPixelFormatDepth16Unorm_Stencil8 MTLPixelFormatDepth32Float_Stencil8
  69. #define MTLPixelFormatDepth24Unorm_Stencil8 MTLPixelFormatInvalid
  70. #define MTLPixelFormatX24_Stencil8 MTLPixelFormatInvalid
  71. #endif
  72. #if TARGET_OS_TV
  73. #define MTLPixelFormatASTC_4x4_HDR MTLPixelFormatInvalid
  74. #define MTLPixelFormatASTC_5x4_HDR MTLPixelFormatInvalid
  75. #define MTLPixelFormatASTC_5x5_HDR MTLPixelFormatInvalid
  76. #define MTLPixelFormatASTC_6x5_HDR MTLPixelFormatInvalid
  77. #define MTLPixelFormatASTC_6x6_HDR MTLPixelFormatInvalid
  78. #define MTLPixelFormatASTC_8x5_HDR MTLPixelFormatInvalid
  79. #define MTLPixelFormatASTC_8x6_HDR MTLPixelFormatInvalid
  80. #define MTLPixelFormatASTC_8x8_HDR MTLPixelFormatInvalid
  81. #define MTLPixelFormatASTC_10x5_HDR MTLPixelFormatInvalid
  82. #define MTLPixelFormatASTC_10x6_HDR MTLPixelFormatInvalid
  83. #define MTLPixelFormatASTC_10x8_HDR MTLPixelFormatInvalid
  84. #define MTLPixelFormatASTC_10x10_HDR MTLPixelFormatInvalid
  85. #define MTLPixelFormatASTC_12x10_HDR MTLPixelFormatInvalid
  86. #define MTLPixelFormatASTC_12x12_HDR MTLPixelFormatInvalid
  87. #endif
  88. #if !((__MAC_OS_X_VERSION_MAX_ALLOWED >= 140000) || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 170000)) // Xcode 15
  89. #define MTLVertexFormatFloatRG11B10 MTLVertexFormatInvalid
  90. #define MTLVertexFormatFloatRGB9E5 MTLVertexFormatInvalid
  91. #endif
  92. template <typename T>
  93. void clear(T *p_val, size_t p_count = 1) {
  94. memset(p_val, 0, sizeof(T) * p_count);
  95. }
  96. #pragma mark -
  97. #pragma mark PixelFormats
  98. bool PixelFormats::isSupported(DataFormat p_format) {
  99. return getDataFormatDesc(p_format).isSupported();
  100. }
  101. bool PixelFormats::isSupportedOrSubstitutable(DataFormat p_format) {
  102. return getDataFormatDesc(p_format).isSupportedOrSubstitutable();
  103. }
  104. bool PixelFormats::isPVRTCFormat(MTLPixelFormat p_format) {
  105. switch (p_format) {
  106. case MTLPixelFormatPVRTC_RGBA_2BPP:
  107. case MTLPixelFormatPVRTC_RGBA_2BPP_sRGB:
  108. case MTLPixelFormatPVRTC_RGBA_4BPP:
  109. case MTLPixelFormatPVRTC_RGBA_4BPP_sRGB:
  110. case MTLPixelFormatPVRTC_RGB_2BPP:
  111. case MTLPixelFormatPVRTC_RGB_2BPP_sRGB:
  112. case MTLPixelFormatPVRTC_RGB_4BPP:
  113. case MTLPixelFormatPVRTC_RGB_4BPP_sRGB:
  114. return true;
  115. default:
  116. return false;
  117. }
  118. }
  119. MTLFormatType PixelFormats::getFormatType(DataFormat p_format) {
  120. return getDataFormatDesc(p_format).formatType;
  121. }
  122. MTLFormatType PixelFormats::getFormatType(MTLPixelFormat p_format) {
  123. return getDataFormatDesc(p_format).formatType;
  124. }
  125. MTLPixelFormat PixelFormats::getMTLPixelFormat(DataFormat p_format) {
  126. DataFormatDesc &dfDesc = getDataFormatDesc(p_format);
  127. MTLPixelFormat mtlPixFmt = dfDesc.mtlPixelFormat;
  128. // If the MTLPixelFormat is not supported but DataFormat is valid,
  129. // attempt to substitute a different format.
  130. if (mtlPixFmt == MTLPixelFormatInvalid && p_format != RD::DATA_FORMAT_MAX && dfDesc.chromaSubsamplingPlaneCount <= 1) {
  131. mtlPixFmt = dfDesc.mtlPixelFormatSubstitute;
  132. }
  133. return mtlPixFmt;
  134. }
  135. RD::DataFormat PixelFormats::getDataFormat(MTLPixelFormat p_format) {
  136. return getMTLPixelFormatDesc(p_format).dataFormat;
  137. }
  138. uint32_t PixelFormats::getBytesPerBlock(DataFormat p_format) {
  139. return getDataFormatDesc(p_format).bytesPerBlock;
  140. }
  141. uint32_t PixelFormats::getBytesPerBlock(MTLPixelFormat p_format) {
  142. return getDataFormatDesc(p_format).bytesPerBlock;
  143. }
  144. uint8_t PixelFormats::getChromaSubsamplingPlaneCount(DataFormat p_format) {
  145. return getDataFormatDesc(p_format).chromaSubsamplingPlaneCount;
  146. }
  147. uint8_t PixelFormats::getChromaSubsamplingComponentBits(DataFormat p_format) {
  148. return getDataFormatDesc(p_format).chromaSubsamplingComponentBits;
  149. }
  150. float PixelFormats::getBytesPerTexel(DataFormat p_format) {
  151. return getDataFormatDesc(p_format).bytesPerTexel();
  152. }
  153. float PixelFormats::getBytesPerTexel(MTLPixelFormat p_format) {
  154. return getDataFormatDesc(p_format).bytesPerTexel();
  155. }
  156. size_t PixelFormats::getBytesPerRow(DataFormat p_format, uint32_t p_texels_per_row) {
  157. DataFormatDesc &dfDesc = getDataFormatDesc(p_format);
  158. return Math::division_round_up(p_texels_per_row, dfDesc.blockTexelSize.width) * dfDesc.bytesPerBlock;
  159. }
  160. size_t PixelFormats::getBytesPerRow(MTLPixelFormat p_format, uint32_t p_texels_per_row) {
  161. DataFormatDesc &dfDesc = getDataFormatDesc(p_format);
  162. return Math::division_round_up(p_texels_per_row, dfDesc.blockTexelSize.width) * dfDesc.bytesPerBlock;
  163. }
  164. size_t PixelFormats::getBytesPerLayer(DataFormat p_format, size_t p_bytes_per_row, uint32_t p_texel_rows_per_layer) {
  165. return Math::division_round_up(p_texel_rows_per_layer, getDataFormatDesc(p_format).blockTexelSize.height) * p_bytes_per_row;
  166. }
  167. size_t PixelFormats::getBytesPerLayer(MTLPixelFormat p_format, size_t p_bytes_per_row, uint32_t p_texel_rows_per_layer) {
  168. return Math::division_round_up(p_texel_rows_per_layer, getDataFormatDesc(p_format).blockTexelSize.height) * p_bytes_per_row;
  169. }
  170. bool PixelFormats::needsSwizzle(DataFormat p_format) {
  171. return getDataFormatDesc(p_format).needsSwizzle();
  172. }
  173. MTLFmtCaps PixelFormats::getCapabilities(DataFormat p_format, bool p_extended) {
  174. return getCapabilities(getDataFormatDesc(p_format).mtlPixelFormat, p_extended);
  175. }
  176. MTLFmtCaps PixelFormats::getCapabilities(MTLPixelFormat p_format, bool p_extended) {
  177. MTLFormatDesc &mtlDesc = getMTLPixelFormatDesc(p_format);
  178. MTLFmtCaps caps = mtlDesc.mtlFmtCaps;
  179. if (!p_extended || mtlDesc.mtlViewClass == MTLViewClass::None) {
  180. return caps;
  181. }
  182. // Now get caps of all formats in the view class.
  183. for (MTLFormatDesc &otherDesc : _mtl_vertex_format_descs) {
  184. if (otherDesc.mtlViewClass == mtlDesc.mtlViewClass) {
  185. caps |= otherDesc.mtlFmtCaps;
  186. }
  187. }
  188. return caps;
  189. }
  190. MTLVertexFormat PixelFormats::getMTLVertexFormat(DataFormat p_format) {
  191. DataFormatDesc &dfDesc = getDataFormatDesc(p_format);
  192. MTLVertexFormat format = dfDesc.mtlVertexFormat;
  193. if (format == MTLVertexFormatInvalid) {
  194. String errMsg;
  195. errMsg += "DataFormat ";
  196. errMsg += dfDesc.name;
  197. errMsg += " is not supported for vertex buffers on this device.";
  198. if (dfDesc.vertexIsSupportedOrSubstitutable()) {
  199. format = dfDesc.mtlVertexFormatSubstitute;
  200. DataFormatDesc &dfDescSubs = getDataFormatDesc(getMTLVertexFormatDesc(format).dataFormat);
  201. errMsg += " Using DataFormat ";
  202. errMsg += dfDescSubs.name;
  203. errMsg += " instead.";
  204. }
  205. WARN_PRINT(errMsg);
  206. }
  207. return format;
  208. }
  209. DataFormatDesc &PixelFormats::getDataFormatDesc(DataFormat p_format) {
  210. return _data_format_descs[p_format];
  211. }
  212. DataFormatDesc &PixelFormats::getDataFormatDesc(MTLPixelFormat p_format) {
  213. return getDataFormatDesc(getMTLPixelFormatDesc(p_format).dataFormat);
  214. }
  215. // Return a reference to the Metal format descriptor corresponding to the MTLPixelFormat.
  216. MTLFormatDesc &PixelFormats::getMTLPixelFormatDesc(MTLPixelFormat p_format) {
  217. return _mtl_pixel_format_descs[p_format];
  218. }
  219. // Return a reference to the Metal format descriptor corresponding to the MTLVertexFormat.
  220. MTLFormatDesc &PixelFormats::getMTLVertexFormatDesc(MTLVertexFormat p_format) {
  221. return _mtl_vertex_format_descs[p_format];
  222. }
  223. PixelFormats::PixelFormats(id<MTLDevice> p_device, const MetalFeatures &p_feat) :
  224. device(p_device) {
  225. initMTLPixelFormatCapabilities();
  226. initMTLVertexFormatCapabilities(p_feat);
  227. modifyMTLFormatCapabilities(p_feat);
  228. initDataFormatCapabilities();
  229. buildDFFormatMaps();
  230. }
  231. #define addDataFormatDescFull(DATA_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, SWIZ_R, SWIZ_G, SWIZ_B, SWIZ_A) \
  232. dfFmt = RD::DATA_FORMAT_##DATA_FMT; \
  233. _data_format_descs[dfFmt] = { dfFmt, MTLPixelFormat##MTL_FMT, MTLPixelFormat##MTL_FMT_ALT, MTLVertexFormat##MTL_VTX_FMT, MTLVertexFormat##MTL_VTX_FMT_ALT, \
  234. CSPC, CSCB, { BLK_W, BLK_H }, BLK_BYTE_CNT, MTLFormatType::MVK_FMT_TYPE, \
  235. { RD::TEXTURE_SWIZZLE_##SWIZ_R, RD::TEXTURE_SWIZZLE_##SWIZ_G, RD::TEXTURE_SWIZZLE_##SWIZ_B, RD::TEXTURE_SWIZZLE_##SWIZ_A }, \
  236. "DATA_FORMAT_" #DATA_FMT, false }
  237. #define addDataFormatDesc(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE) \
  238. addDataFormatDescFull(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, 0, 0, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, IDENTITY, IDENTITY, IDENTITY, IDENTITY)
  239. #define addDataFormatDescSwizzled(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, SWIZ_R, SWIZ_G, SWIZ_B, SWIZ_A) \
  240. addDataFormatDescFull(VK_FMT, MTL_FMT, MTL_FMT_ALT, MTL_VTX_FMT, MTL_VTX_FMT_ALT, 0, 0, BLK_W, BLK_H, BLK_BYTE_CNT, MVK_FMT_TYPE, SWIZ_R, SWIZ_G, SWIZ_B, SWIZ_A)
  241. #define addDfFormatDescChromaSubsampling(DATA_FMT, MTL_FMT, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT) \
  242. addDataFormatDescFull(DATA_FMT, MTL_FMT, Invalid, Invalid, Invalid, CSPC, CSCB, BLK_W, BLK_H, BLK_BYTE_CNT, ColorFloat, IDENTITY, IDENTITY, IDENTITY, IDENTITY)
  243. void PixelFormats::initDataFormatCapabilities() {
  244. _data_format_descs.reserve(RD::DATA_FORMAT_MAX + 1); // reserve enough space to avoid reallocs
  245. DataFormat dfFmt;
  246. addDataFormatDesc(R4G4_UNORM_PACK8, Invalid, Invalid, Invalid, Invalid, 1, 1, 1, ColorFloat);
  247. addDataFormatDesc(R4G4_UNORM_PACK8, Invalid, Invalid, Invalid, Invalid, 1, 1, 1, ColorFloat);
  248. addDataFormatDesc(R4G4B4A4_UNORM_PACK16, ABGR4Unorm, Invalid, Invalid, Invalid, 1, 1, 2, ColorFloat);
  249. addDataFormatDescSwizzled(B4G4R4A4_UNORM_PACK16, Invalid, Invalid, Invalid, Invalid, 1, 1, 2, ColorFloat, B, G, R, A);
  250. addDataFormatDesc(R5G6B5_UNORM_PACK16, B5G6R5Unorm, Invalid, Invalid, Invalid, 1, 1, 2, ColorFloat);
  251. addDataFormatDescSwizzled(B5G6R5_UNORM_PACK16, B5G6R5Unorm, Invalid, Invalid, Invalid, 1, 1, 2, ColorFloat, B, G, R, A);
  252. addDataFormatDesc(R5G5B5A1_UNORM_PACK16, A1BGR5Unorm, Invalid, Invalid, Invalid, 1, 1, 2, ColorFloat);
  253. addDataFormatDescSwizzled(B5G5R5A1_UNORM_PACK16, A1BGR5Unorm, Invalid, Invalid, Invalid, 1, 1, 2, ColorFloat, B, G, R, A);
  254. addDataFormatDesc(A1R5G5B5_UNORM_PACK16, BGR5A1Unorm, Invalid, Invalid, Invalid, 1, 1, 2, ColorFloat);
  255. addDataFormatDesc(R8_UNORM, R8Unorm, Invalid, UCharNormalized, UChar2Normalized, 1, 1, 1, ColorFloat);
  256. addDataFormatDesc(R8_SNORM, R8Snorm, Invalid, CharNormalized, Char2Normalized, 1, 1, 1, ColorFloat);
  257. addDataFormatDesc(R8_USCALED, Invalid, Invalid, UChar, UChar2, 1, 1, 1, ColorFloat);
  258. addDataFormatDesc(R8_SSCALED, Invalid, Invalid, Char, Char2, 1, 1, 1, ColorFloat);
  259. addDataFormatDesc(R8_UINT, R8Uint, Invalid, UChar, UChar2, 1, 1, 1, ColorUInt8);
  260. addDataFormatDesc(R8_SINT, R8Sint, Invalid, Char, Char2, 1, 1, 1, ColorInt8);
  261. addDataFormatDesc(R8_SRGB, R8Unorm_sRGB, Invalid, UCharNormalized, UChar2Normalized, 1, 1, 1, ColorFloat);
  262. addDataFormatDesc(R8G8_UNORM, RG8Unorm, Invalid, UChar2Normalized, Invalid, 1, 1, 2, ColorFloat);
  263. addDataFormatDesc(R8G8_SNORM, RG8Snorm, Invalid, Char2Normalized, Invalid, 1, 1, 2, ColorFloat);
  264. addDataFormatDesc(R8G8_USCALED, Invalid, Invalid, UChar2, Invalid, 1, 1, 2, ColorFloat);
  265. addDataFormatDesc(R8G8_SSCALED, Invalid, Invalid, Char2, Invalid, 1, 1, 2, ColorFloat);
  266. addDataFormatDesc(R8G8_UINT, RG8Uint, Invalid, UChar2, Invalid, 1, 1, 2, ColorUInt8);
  267. addDataFormatDesc(R8G8_SINT, RG8Sint, Invalid, Char2, Invalid, 1, 1, 2, ColorInt8);
  268. addDataFormatDesc(R8G8_SRGB, RG8Unorm_sRGB, Invalid, UChar2Normalized, Invalid, 1, 1, 2, ColorFloat);
  269. addDataFormatDesc(R8G8B8_UNORM, Invalid, Invalid, UChar3Normalized, Invalid, 1, 1, 3, ColorFloat);
  270. addDataFormatDesc(R8G8B8_SNORM, Invalid, Invalid, Char3Normalized, Invalid, 1, 1, 3, ColorFloat);
  271. addDataFormatDesc(R8G8B8_USCALED, Invalid, Invalid, UChar3, Invalid, 1, 1, 3, ColorFloat);
  272. addDataFormatDesc(R8G8B8_SSCALED, Invalid, Invalid, Char3, Invalid, 1, 1, 3, ColorFloat);
  273. addDataFormatDesc(R8G8B8_UINT, Invalid, Invalid, UChar3, Invalid, 1, 1, 3, ColorUInt8);
  274. addDataFormatDesc(R8G8B8_SINT, Invalid, Invalid, Char3, Invalid, 1, 1, 3, ColorInt8);
  275. addDataFormatDesc(R8G8B8_SRGB, Invalid, Invalid, UChar3Normalized, Invalid, 1, 1, 3, ColorFloat);
  276. addDataFormatDesc(B8G8R8_UNORM, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, ColorFloat);
  277. addDataFormatDesc(B8G8R8_SNORM, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, ColorFloat);
  278. addDataFormatDesc(B8G8R8_USCALED, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, ColorFloat);
  279. addDataFormatDesc(B8G8R8_SSCALED, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, ColorFloat);
  280. addDataFormatDesc(B8G8R8_UINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, ColorUInt8);
  281. addDataFormatDesc(B8G8R8_SINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, ColorInt8);
  282. addDataFormatDesc(B8G8R8_SRGB, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, ColorFloat);
  283. addDataFormatDesc(R8G8B8A8_UNORM, RGBA8Unorm, Invalid, UChar4Normalized, Invalid, 1, 1, 4, ColorFloat);
  284. addDataFormatDesc(R8G8B8A8_SNORM, RGBA8Snorm, Invalid, Char4Normalized, Invalid, 1, 1, 4, ColorFloat);
  285. addDataFormatDesc(R8G8B8A8_USCALED, Invalid, Invalid, UChar4, Invalid, 1, 1, 4, ColorFloat);
  286. addDataFormatDesc(R8G8B8A8_SSCALED, Invalid, Invalid, Char4, Invalid, 1, 1, 4, ColorFloat);
  287. addDataFormatDesc(R8G8B8A8_UINT, RGBA8Uint, Invalid, UChar4, Invalid, 1, 1, 4, ColorUInt8);
  288. addDataFormatDesc(R8G8B8A8_SINT, RGBA8Sint, Invalid, Char4, Invalid, 1, 1, 4, ColorInt8);
  289. addDataFormatDesc(R8G8B8A8_SRGB, RGBA8Unorm_sRGB, Invalid, UChar4Normalized, Invalid, 1, 1, 4, ColorFloat);
  290. addDataFormatDesc(B8G8R8A8_UNORM, BGRA8Unorm, Invalid, UChar4Normalized_BGRA, Invalid, 1, 1, 4, ColorFloat);
  291. addDataFormatDescSwizzled(B8G8R8A8_SNORM, RGBA8Snorm, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat, B, G, R, A);
  292. addDataFormatDesc(B8G8R8A8_USCALED, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  293. addDataFormatDesc(B8G8R8A8_SSCALED, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  294. addDataFormatDescSwizzled(B8G8R8A8_UINT, RGBA8Uint, Invalid, Invalid, Invalid, 1, 1, 4, ColorUInt8, B, G, R, A);
  295. addDataFormatDescSwizzled(B8G8R8A8_SINT, RGBA8Sint, Invalid, Invalid, Invalid, 1, 1, 4, ColorInt8, B, G, R, A);
  296. addDataFormatDesc(B8G8R8A8_SRGB, BGRA8Unorm_sRGB, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  297. addDataFormatDesc(A8B8G8R8_UNORM_PACK32, RGBA8Unorm, Invalid, UChar4Normalized, Invalid, 1, 1, 4, ColorFloat);
  298. addDataFormatDesc(A8B8G8R8_SNORM_PACK32, RGBA8Snorm, Invalid, Char4Normalized, Invalid, 1, 1, 4, ColorFloat);
  299. addDataFormatDesc(A8B8G8R8_USCALED_PACK32, Invalid, Invalid, UChar4, Invalid, 1, 1, 4, ColorFloat);
  300. addDataFormatDesc(A8B8G8R8_SSCALED_PACK32, Invalid, Invalid, Char4, Invalid, 1, 1, 4, ColorFloat);
  301. addDataFormatDesc(A8B8G8R8_UINT_PACK32, RGBA8Uint, Invalid, UChar4, Invalid, 1, 1, 4, ColorUInt8);
  302. addDataFormatDesc(A8B8G8R8_SINT_PACK32, RGBA8Sint, Invalid, Char4, Invalid, 1, 1, 4, ColorInt8);
  303. addDataFormatDesc(A8B8G8R8_SRGB_PACK32, RGBA8Unorm_sRGB, Invalid, UChar4Normalized, Invalid, 1, 1, 4, ColorFloat);
  304. addDataFormatDesc(A2R10G10B10_UNORM_PACK32, BGR10A2Unorm, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  305. addDataFormatDesc(A2R10G10B10_SNORM_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  306. addDataFormatDesc(A2R10G10B10_USCALED_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  307. addDataFormatDesc(A2R10G10B10_SSCALED_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  308. addDataFormatDesc(A2R10G10B10_UINT_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorUInt16);
  309. addDataFormatDesc(A2R10G10B10_SINT_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorInt16);
  310. addDataFormatDesc(A2B10G10R10_UNORM_PACK32, RGB10A2Unorm, Invalid, UInt1010102Normalized, Invalid, 1, 1, 4, ColorFloat);
  311. addDataFormatDesc(A2B10G10R10_SNORM_PACK32, Invalid, Invalid, Int1010102Normalized, Invalid, 1, 1, 4, ColorFloat);
  312. addDataFormatDesc(A2B10G10R10_USCALED_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  313. addDataFormatDesc(A2B10G10R10_SSCALED_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  314. addDataFormatDesc(A2B10G10R10_UINT_PACK32, RGB10A2Uint, Invalid, Invalid, Invalid, 1, 1, 4, ColorUInt16);
  315. addDataFormatDesc(A2B10G10R10_SINT_PACK32, Invalid, Invalid, Invalid, Invalid, 1, 1, 4, ColorInt16);
  316. addDataFormatDesc(R16_UNORM, R16Unorm, Invalid, UShortNormalized, UShort2Normalized, 1, 1, 2, ColorFloat);
  317. addDataFormatDesc(R16_SNORM, R16Snorm, Invalid, ShortNormalized, Short2Normalized, 1, 1, 2, ColorFloat);
  318. addDataFormatDesc(R16_USCALED, Invalid, Invalid, UShort, UShort2, 1, 1, 2, ColorFloat);
  319. addDataFormatDesc(R16_SSCALED, Invalid, Invalid, Short, Short2, 1, 1, 2, ColorFloat);
  320. addDataFormatDesc(R16_UINT, R16Uint, Invalid, UShort, UShort2, 1, 1, 2, ColorUInt16);
  321. addDataFormatDesc(R16_SINT, R16Sint, Invalid, Short, Short2, 1, 1, 2, ColorInt16);
  322. addDataFormatDesc(R16_SFLOAT, R16Float, Invalid, Half, Half2, 1, 1, 2, ColorFloat);
  323. addDataFormatDesc(R16G16_UNORM, RG16Unorm, Invalid, UShort2Normalized, Invalid, 1, 1, 4, ColorFloat);
  324. addDataFormatDesc(R16G16_SNORM, RG16Snorm, Invalid, Short2Normalized, Invalid, 1, 1, 4, ColorFloat);
  325. addDataFormatDesc(R16G16_USCALED, Invalid, Invalid, UShort2, Invalid, 1, 1, 4, ColorFloat);
  326. addDataFormatDesc(R16G16_SSCALED, Invalid, Invalid, Short2, Invalid, 1, 1, 4, ColorFloat);
  327. addDataFormatDesc(R16G16_UINT, RG16Uint, Invalid, UShort2, Invalid, 1, 1, 4, ColorUInt16);
  328. addDataFormatDesc(R16G16_SINT, RG16Sint, Invalid, Short2, Invalid, 1, 1, 4, ColorInt16);
  329. addDataFormatDesc(R16G16_SFLOAT, RG16Float, Invalid, Half2, Invalid, 1, 1, 4, ColorFloat);
  330. addDataFormatDesc(R16G16B16_UNORM, Invalid, Invalid, UShort3Normalized, Invalid, 1, 1, 6, ColorFloat);
  331. addDataFormatDesc(R16G16B16_SNORM, Invalid, Invalid, Short3Normalized, Invalid, 1, 1, 6, ColorFloat);
  332. addDataFormatDesc(R16G16B16_USCALED, Invalid, Invalid, UShort3, Invalid, 1, 1, 6, ColorFloat);
  333. addDataFormatDesc(R16G16B16_SSCALED, Invalid, Invalid, Short3, Invalid, 1, 1, 6, ColorFloat);
  334. addDataFormatDesc(R16G16B16_UINT, Invalid, Invalid, UShort3, Invalid, 1, 1, 6, ColorUInt16);
  335. addDataFormatDesc(R16G16B16_SINT, Invalid, Invalid, Short3, Invalid, 1, 1, 6, ColorInt16);
  336. addDataFormatDesc(R16G16B16_SFLOAT, Invalid, Invalid, Half3, Invalid, 1, 1, 6, ColorFloat);
  337. addDataFormatDesc(R16G16B16A16_UNORM, RGBA16Unorm, Invalid, UShort4Normalized, Invalid, 1, 1, 8, ColorFloat);
  338. addDataFormatDesc(R16G16B16A16_SNORM, RGBA16Snorm, Invalid, Short4Normalized, Invalid, 1, 1, 8, ColorFloat);
  339. addDataFormatDesc(R16G16B16A16_USCALED, Invalid, Invalid, UShort4, Invalid, 1, 1, 8, ColorFloat);
  340. addDataFormatDesc(R16G16B16A16_SSCALED, Invalid, Invalid, Short4, Invalid, 1, 1, 8, ColorFloat);
  341. addDataFormatDesc(R16G16B16A16_UINT, RGBA16Uint, Invalid, UShort4, Invalid, 1, 1, 8, ColorUInt16);
  342. addDataFormatDesc(R16G16B16A16_SINT, RGBA16Sint, Invalid, Short4, Invalid, 1, 1, 8, ColorInt16);
  343. addDataFormatDesc(R16G16B16A16_SFLOAT, RGBA16Float, Invalid, Half4, Invalid, 1, 1, 8, ColorFloat);
  344. addDataFormatDesc(R32_UINT, R32Uint, Invalid, UInt, Invalid, 1, 1, 4, ColorUInt32);
  345. addDataFormatDesc(R32_SINT, R32Sint, Invalid, Int, Invalid, 1, 1, 4, ColorInt32);
  346. addDataFormatDesc(R32_SFLOAT, R32Float, Invalid, Float, Invalid, 1, 1, 4, ColorFloat);
  347. addDataFormatDesc(R32G32_UINT, RG32Uint, Invalid, UInt2, Invalid, 1, 1, 8, ColorUInt32);
  348. addDataFormatDesc(R32G32_SINT, RG32Sint, Invalid, Int2, Invalid, 1, 1, 8, ColorInt32);
  349. addDataFormatDesc(R32G32_SFLOAT, RG32Float, Invalid, Float2, Invalid, 1, 1, 8, ColorFloat);
  350. addDataFormatDesc(R32G32B32_UINT, Invalid, Invalid, UInt3, Invalid, 1, 1, 12, ColorUInt32);
  351. addDataFormatDesc(R32G32B32_SINT, Invalid, Invalid, Int3, Invalid, 1, 1, 12, ColorInt32);
  352. addDataFormatDesc(R32G32B32_SFLOAT, Invalid, Invalid, Float3, Invalid, 1, 1, 12, ColorFloat);
  353. addDataFormatDesc(R32G32B32A32_UINT, RGBA32Uint, Invalid, UInt4, Invalid, 1, 1, 16, ColorUInt32);
  354. addDataFormatDesc(R32G32B32A32_SINT, RGBA32Sint, Invalid, Int4, Invalid, 1, 1, 16, ColorInt32);
  355. addDataFormatDesc(R32G32B32A32_SFLOAT, RGBA32Float, Invalid, Float4, Invalid, 1, 1, 16, ColorFloat);
  356. addDataFormatDesc(R64_UINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 8, ColorFloat);
  357. addDataFormatDesc(R64_SINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 8, ColorFloat);
  358. addDataFormatDesc(R64_SFLOAT, Invalid, Invalid, Invalid, Invalid, 1, 1, 8, ColorFloat);
  359. addDataFormatDesc(R64G64_UINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 16, ColorFloat);
  360. addDataFormatDesc(R64G64_SINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 16, ColorFloat);
  361. addDataFormatDesc(R64G64_SFLOAT, Invalid, Invalid, Invalid, Invalid, 1, 1, 16, ColorFloat);
  362. addDataFormatDesc(R64G64B64_UINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 24, ColorFloat);
  363. addDataFormatDesc(R64G64B64_SINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 24, ColorFloat);
  364. addDataFormatDesc(R64G64B64_SFLOAT, Invalid, Invalid, Invalid, Invalid, 1, 1, 24, ColorFloat);
  365. addDataFormatDesc(R64G64B64A64_UINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 32, ColorFloat);
  366. addDataFormatDesc(R64G64B64A64_SINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 32, ColorFloat);
  367. addDataFormatDesc(R64G64B64A64_SFLOAT, Invalid, Invalid, Invalid, Invalid, 1, 1, 32, ColorFloat);
  368. addDataFormatDesc(B10G11R11_UFLOAT_PACK32, RG11B10Float, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  369. addDataFormatDesc(E5B9G9R9_UFLOAT_PACK32, RGB9E5Float, Invalid, Invalid, Invalid, 1, 1, 4, ColorFloat);
  370. addDataFormatDesc(D32_SFLOAT, Depth32Float, Invalid, Invalid, Invalid, 1, 1, 4, DepthStencil);
  371. addDataFormatDesc(D32_SFLOAT_S8_UINT, Depth32Float_Stencil8, Invalid, Invalid, Invalid, 1, 1, 5, DepthStencil);
  372. addDataFormatDesc(S8_UINT, Stencil8, Invalid, Invalid, Invalid, 1, 1, 1, DepthStencil);
  373. addDataFormatDesc(D16_UNORM, Depth16Unorm, Depth32Float, Invalid, Invalid, 1, 1, 2, DepthStencil);
  374. addDataFormatDesc(D16_UNORM_S8_UINT, Invalid, Invalid, Invalid, Invalid, 1, 1, 3, DepthStencil);
  375. addDataFormatDesc(D24_UNORM_S8_UINT, Depth24Unorm_Stencil8, Depth32Float_Stencil8, Invalid, Invalid, 1, 1, 4, DepthStencil);
  376. addDataFormatDesc(X8_D24_UNORM_PACK32, Invalid, Depth24Unorm_Stencil8, Invalid, Invalid, 1, 1, 4, DepthStencil);
  377. #pragma clang diagnostic push
  378. #pragma clang diagnostic ignored "-Wunguarded-availability"
  379. addDataFormatDesc(BC1_RGB_UNORM_BLOCK, BC1_RGBA, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  380. addDataFormatDesc(BC1_RGB_SRGB_BLOCK, BC1_RGBA_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  381. addDataFormatDesc(BC1_RGBA_UNORM_BLOCK, BC1_RGBA, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  382. addDataFormatDesc(BC1_RGBA_SRGB_BLOCK, BC1_RGBA_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  383. addDataFormatDesc(BC2_UNORM_BLOCK, BC2_RGBA, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  384. addDataFormatDesc(BC2_SRGB_BLOCK, BC2_RGBA_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  385. addDataFormatDesc(BC3_UNORM_BLOCK, BC3_RGBA, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  386. addDataFormatDesc(BC3_SRGB_BLOCK, BC3_RGBA_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  387. addDataFormatDesc(BC4_UNORM_BLOCK, BC4_RUnorm, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  388. addDataFormatDesc(BC4_SNORM_BLOCK, BC4_RSnorm, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  389. addDataFormatDesc(BC5_UNORM_BLOCK, BC5_RGUnorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  390. addDataFormatDesc(BC5_SNORM_BLOCK, BC5_RGSnorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  391. addDataFormatDesc(BC6H_UFLOAT_BLOCK, BC6H_RGBUfloat, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  392. addDataFormatDesc(BC6H_SFLOAT_BLOCK, BC6H_RGBFloat, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  393. addDataFormatDesc(BC7_UNORM_BLOCK, BC7_RGBAUnorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  394. addDataFormatDesc(BC7_SRGB_BLOCK, BC7_RGBAUnorm_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  395. #pragma clang diagnostic pop
  396. addDataFormatDesc(ETC2_R8G8B8_UNORM_BLOCK, ETC2_RGB8, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  397. addDataFormatDesc(ETC2_R8G8B8_SRGB_BLOCK, ETC2_RGB8_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  398. addDataFormatDesc(ETC2_R8G8B8A1_UNORM_BLOCK, ETC2_RGB8A1, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  399. addDataFormatDesc(ETC2_R8G8B8A1_SRGB_BLOCK, ETC2_RGB8A1_sRGB, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  400. addDataFormatDesc(ETC2_R8G8B8A8_UNORM_BLOCK, EAC_RGBA8, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  401. addDataFormatDesc(ETC2_R8G8B8A8_SRGB_BLOCK, EAC_RGBA8_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  402. addDataFormatDesc(EAC_R11_UNORM_BLOCK, EAC_R11Unorm, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  403. addDataFormatDesc(EAC_R11_SNORM_BLOCK, EAC_R11Snorm, Invalid, Invalid, Invalid, 4, 4, 8, Compressed);
  404. addDataFormatDesc(EAC_R11G11_UNORM_BLOCK, EAC_RG11Unorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  405. addDataFormatDesc(EAC_R11G11_SNORM_BLOCK, EAC_RG11Snorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  406. addDataFormatDesc(ASTC_4x4_UNORM_BLOCK, ASTC_4x4_LDR, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  407. addDataFormatDesc(ASTC_4x4_SRGB_BLOCK, ASTC_4x4_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
  408. addDataFormatDesc(ASTC_5x4_UNORM_BLOCK, ASTC_5x4_LDR, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
  409. addDataFormatDesc(ASTC_5x4_SRGB_BLOCK, ASTC_5x4_sRGB, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
  410. addDataFormatDesc(ASTC_5x5_UNORM_BLOCK, ASTC_5x5_LDR, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
  411. addDataFormatDesc(ASTC_5x5_SRGB_BLOCK, ASTC_5x5_sRGB, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
  412. addDataFormatDesc(ASTC_6x5_UNORM_BLOCK, ASTC_6x5_LDR, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
  413. addDataFormatDesc(ASTC_6x5_SRGB_BLOCK, ASTC_6x5_sRGB, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
  414. addDataFormatDesc(ASTC_6x6_UNORM_BLOCK, ASTC_6x6_LDR, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
  415. addDataFormatDesc(ASTC_6x6_SRGB_BLOCK, ASTC_6x6_sRGB, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
  416. addDataFormatDesc(ASTC_8x5_UNORM_BLOCK, ASTC_8x5_LDR, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
  417. addDataFormatDesc(ASTC_8x5_SRGB_BLOCK, ASTC_8x5_sRGB, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
  418. addDataFormatDesc(ASTC_8x6_UNORM_BLOCK, ASTC_8x6_LDR, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
  419. addDataFormatDesc(ASTC_8x6_SRGB_BLOCK, ASTC_8x6_sRGB, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
  420. addDataFormatDesc(ASTC_8x8_UNORM_BLOCK, ASTC_8x8_LDR, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
  421. addDataFormatDesc(ASTC_8x8_SRGB_BLOCK, ASTC_8x8_sRGB, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
  422. addDataFormatDesc(ASTC_10x5_UNORM_BLOCK, ASTC_10x5_LDR, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
  423. addDataFormatDesc(ASTC_10x5_SRGB_BLOCK, ASTC_10x5_sRGB, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
  424. addDataFormatDesc(ASTC_10x6_UNORM_BLOCK, ASTC_10x6_LDR, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
  425. addDataFormatDesc(ASTC_10x6_SRGB_BLOCK, ASTC_10x6_sRGB, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
  426. addDataFormatDesc(ASTC_10x8_UNORM_BLOCK, ASTC_10x8_LDR, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
  427. addDataFormatDesc(ASTC_10x8_SRGB_BLOCK, ASTC_10x8_sRGB, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
  428. addDataFormatDesc(ASTC_10x10_UNORM_BLOCK, ASTC_10x10_LDR, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
  429. addDataFormatDesc(ASTC_10x10_SRGB_BLOCK, ASTC_10x10_sRGB, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
  430. addDataFormatDesc(ASTC_12x10_UNORM_BLOCK, ASTC_12x10_LDR, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
  431. addDataFormatDesc(ASTC_12x10_SRGB_BLOCK, ASTC_12x10_sRGB, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
  432. addDataFormatDesc(ASTC_12x12_UNORM_BLOCK, ASTC_12x12_LDR, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
  433. addDataFormatDesc(ASTC_12x12_SRGB_BLOCK, ASTC_12x12_sRGB, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
  434. addDfFormatDescChromaSubsampling(G8B8G8R8_422_UNORM, GBGR422, 1, 8, 2, 1, 4);
  435. addDfFormatDescChromaSubsampling(B8G8R8G8_422_UNORM, BGRG422, 1, 8, 2, 1, 4);
  436. addDfFormatDescChromaSubsampling(G8_B8_R8_3PLANE_420_UNORM, Invalid, 3, 8, 2, 2, 6);
  437. addDfFormatDescChromaSubsampling(G8_B8R8_2PLANE_420_UNORM, Invalid, 2, 8, 2, 2, 6);
  438. addDfFormatDescChromaSubsampling(G8_B8_R8_3PLANE_422_UNORM, Invalid, 3, 8, 2, 1, 4);
  439. addDfFormatDescChromaSubsampling(G8_B8R8_2PLANE_422_UNORM, Invalid, 2, 8, 2, 1, 4);
  440. addDfFormatDescChromaSubsampling(G8_B8_R8_3PLANE_444_UNORM, Invalid, 3, 8, 1, 1, 3);
  441. addDfFormatDescChromaSubsampling(R10X6_UNORM_PACK16, R16Unorm, 0, 10, 1, 1, 2);
  442. addDfFormatDescChromaSubsampling(R10X6G10X6_UNORM_2PACK16, RG16Unorm, 0, 10, 1, 1, 4);
  443. addDfFormatDescChromaSubsampling(R10X6G10X6B10X6A10X6_UNORM_4PACK16, RGBA16Unorm, 0, 10, 1, 1, 8);
  444. addDfFormatDescChromaSubsampling(G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, Invalid, 1, 10, 2, 1, 8);
  445. addDfFormatDescChromaSubsampling(B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, Invalid, 1, 10, 2, 1, 8);
  446. addDfFormatDescChromaSubsampling(G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, Invalid, 3, 10, 2, 2, 12);
  447. addDfFormatDescChromaSubsampling(G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, Invalid, 2, 10, 2, 2, 12);
  448. addDfFormatDescChromaSubsampling(G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, Invalid, 3, 10, 2, 1, 8);
  449. addDfFormatDescChromaSubsampling(G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, Invalid, 2, 10, 2, 1, 8);
  450. addDfFormatDescChromaSubsampling(G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, Invalid, 3, 10, 1, 1, 6);
  451. addDfFormatDescChromaSubsampling(R12X4_UNORM_PACK16, R16Unorm, 0, 12, 1, 1, 2);
  452. addDfFormatDescChromaSubsampling(R12X4G12X4_UNORM_2PACK16, RG16Unorm, 0, 12, 1, 1, 4);
  453. addDfFormatDescChromaSubsampling(R12X4G12X4B12X4A12X4_UNORM_4PACK16, RGBA16Unorm, 0, 12, 1, 1, 8);
  454. addDfFormatDescChromaSubsampling(G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, Invalid, 1, 12, 2, 1, 8);
  455. addDfFormatDescChromaSubsampling(B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, Invalid, 1, 12, 2, 1, 8);
  456. addDfFormatDescChromaSubsampling(G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, Invalid, 3, 12, 2, 2, 12);
  457. addDfFormatDescChromaSubsampling(G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, Invalid, 2, 12, 2, 2, 12);
  458. addDfFormatDescChromaSubsampling(G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, Invalid, 3, 12, 2, 1, 8);
  459. addDfFormatDescChromaSubsampling(G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, Invalid, 2, 12, 2, 1, 8);
  460. addDfFormatDescChromaSubsampling(G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, Invalid, 3, 12, 1, 1, 6);
  461. addDfFormatDescChromaSubsampling(G16B16G16R16_422_UNORM, Invalid, 1, 16, 2, 1, 8);
  462. addDfFormatDescChromaSubsampling(B16G16R16G16_422_UNORM, Invalid, 1, 16, 2, 1, 8);
  463. addDfFormatDescChromaSubsampling(G16_B16_R16_3PLANE_420_UNORM, Invalid, 3, 16, 2, 2, 12);
  464. addDfFormatDescChromaSubsampling(G16_B16R16_2PLANE_420_UNORM, Invalid, 2, 16, 2, 2, 12);
  465. addDfFormatDescChromaSubsampling(G16_B16_R16_3PLANE_422_UNORM, Invalid, 3, 16, 2, 1, 8);
  466. addDfFormatDescChromaSubsampling(G16_B16R16_2PLANE_422_UNORM, Invalid, 2, 16, 2, 1, 8);
  467. addDfFormatDescChromaSubsampling(G16_B16_R16_3PLANE_444_UNORM, Invalid, 3, 16, 1, 1, 6);
  468. }
  469. void PixelFormats::addMTLPixelFormatDescImpl(MTLPixelFormat p_pix_fmt, MTLPixelFormat p_pix_fmt_linear,
  470. MTLViewClass p_view_class, MTLFmtCaps p_fmt_caps, const char *p_name) {
  471. _mtl_pixel_format_descs[p_pix_fmt] = { .mtlPixelFormat = p_pix_fmt, DataFormat::DATA_FORMAT_MAX, p_fmt_caps, p_view_class, p_pix_fmt_linear, p_name };
  472. }
  473. #define addMTLPixelFormatDescFull(mtlFmt, mtlFmtLinear, viewClass, appleGPUCaps) \
  474. addMTLPixelFormatDescImpl(MTLPixelFormat##mtlFmt, MTLPixelFormat##mtlFmtLinear, MTLViewClass::viewClass, \
  475. appleGPUCaps, "MTLPixelFormat" #mtlFmt)
  476. #define addMTLPixelFormatDesc(mtlFmt, viewClass, appleGPUCaps) \
  477. addMTLPixelFormatDescFull(mtlFmt, mtlFmt, viewClass, kMTLFmtCaps##appleGPUCaps)
  478. #define addMTLPixelFormatDescSRGB(mtlFmt, viewClass, appleGPUCaps, mtlFmtLinear) \
  479. /* Cannot write to sRGB textures in the simulator */ \
  480. if (TARGET_OS_SIMULATOR) { \
  481. MTLFmtCaps appleFmtCaps = kMTLFmtCaps##appleGPUCaps; \
  482. flags::clear(appleFmtCaps, kMTLFmtCapsWrite); \
  483. addMTLPixelFormatDescFull(mtlFmt, mtlFmtLinear, viewClass, appleFmtCaps); \
  484. } else { \
  485. addMTLPixelFormatDescFull(mtlFmt, mtlFmtLinear, viewClass, kMTLFmtCaps##appleGPUCaps); \
  486. }
  487. void PixelFormats::initMTLPixelFormatCapabilities() {
  488. _mtl_pixel_format_descs.reserve(1024);
  489. // MTLPixelFormatInvalid must come first. Use addMTLPixelFormatDescImpl to avoid guard code.
  490. addMTLPixelFormatDescImpl(MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLViewClass::None, kMTLFmtCapsNone, "MTLPixelFormatInvalid");
  491. // Ordinary 8-bit pixel formats.
  492. addMTLPixelFormatDesc(A8Unorm, Color8, All);
  493. addMTLPixelFormatDesc(R8Unorm, Color8, All);
  494. addMTLPixelFormatDescSRGB(R8Unorm_sRGB, Color8, All, R8Unorm);
  495. addMTLPixelFormatDesc(R8Snorm, Color8, All);
  496. addMTLPixelFormatDesc(R8Uint, Color8, RWCM);
  497. addMTLPixelFormatDesc(R8Sint, Color8, RWCM);
  498. // Ordinary 16-bit pixel formats
  499. addMTLPixelFormatDesc(R16Unorm, Color16, RFWCMB);
  500. addMTLPixelFormatDesc(R16Snorm, Color16, RFWCMB);
  501. addMTLPixelFormatDesc(R16Uint, Color16, RWCM);
  502. addMTLPixelFormatDesc(R16Sint, Color16, RWCM);
  503. addMTLPixelFormatDesc(R16Float, Color16, All);
  504. addMTLPixelFormatDesc(RG8Unorm, Color16, All);
  505. addMTLPixelFormatDescSRGB(RG8Unorm_sRGB, Color16, All, RG8Unorm);
  506. addMTLPixelFormatDesc(RG8Snorm, Color16, All);
  507. addMTLPixelFormatDesc(RG8Uint, Color16, RWCM);
  508. addMTLPixelFormatDesc(RG8Sint, Color16, RWCM);
  509. // Packed 16-bit pixel formats
  510. addMTLPixelFormatDesc(B5G6R5Unorm, Color16, RFCMRB);
  511. addMTLPixelFormatDesc(A1BGR5Unorm, Color16, RFCMRB);
  512. addMTLPixelFormatDesc(ABGR4Unorm, Color16, RFCMRB);
  513. addMTLPixelFormatDesc(BGR5A1Unorm, Color16, RFCMRB);
  514. // Ordinary 32-bit pixel formats
  515. addMTLPixelFormatDesc(R32Uint, Color32, RWC);
  516. addMTLPixelFormatDesc(R32Sint, Color32, RWC);
  517. addMTLPixelFormatDesc(R32Float, Color32, All);
  518. addMTLPixelFormatDesc(RG16Unorm, Color32, RFWCMB);
  519. addMTLPixelFormatDesc(RG16Snorm, Color32, RFWCMB);
  520. addMTLPixelFormatDesc(RG16Uint, Color32, RWCM);
  521. addMTLPixelFormatDesc(RG16Sint, Color32, RWCM);
  522. addMTLPixelFormatDesc(RG16Float, Color32, All);
  523. addMTLPixelFormatDesc(RGBA8Unorm, Color32, All);
  524. addMTLPixelFormatDescSRGB(RGBA8Unorm_sRGB, Color32, All, RGBA8Unorm);
  525. addMTLPixelFormatDesc(RGBA8Snorm, Color32, All);
  526. addMTLPixelFormatDesc(RGBA8Uint, Color32, RWCM);
  527. addMTLPixelFormatDesc(RGBA8Sint, Color32, RWCM);
  528. addMTLPixelFormatDesc(BGRA8Unorm, Color32, All);
  529. addMTLPixelFormatDescSRGB(BGRA8Unorm_sRGB, Color32, All, BGRA8Unorm);
  530. // Packed 32-bit pixel formats
  531. addMTLPixelFormatDesc(RGB10A2Unorm, Color32, All);
  532. addMTLPixelFormatDesc(BGR10A2Unorm, Color32, All);
  533. addMTLPixelFormatDesc(RGB10A2Uint, Color32, RWCM);
  534. addMTLPixelFormatDesc(RG11B10Float, Color32, All);
  535. addMTLPixelFormatDesc(RGB9E5Float, Color32, All);
  536. // Ordinary 64-bit pixel formats
  537. addMTLPixelFormatDesc(RG32Uint, Color64, RWCM);
  538. addMTLPixelFormatDesc(RG32Sint, Color64, RWCM);
  539. addMTLPixelFormatDesc(RG32Float, Color64, All);
  540. addMTLPixelFormatDesc(RGBA16Unorm, Color64, RFWCMB);
  541. addMTLPixelFormatDesc(RGBA16Snorm, Color64, RFWCMB);
  542. addMTLPixelFormatDesc(RGBA16Uint, Color64, RWCM);
  543. addMTLPixelFormatDesc(RGBA16Sint, Color64, RWCM);
  544. addMTLPixelFormatDesc(RGBA16Float, Color64, All);
  545. // Ordinary 128-bit pixel formats
  546. addMTLPixelFormatDesc(RGBA32Uint, Color128, RWC);
  547. addMTLPixelFormatDesc(RGBA32Sint, Color128, RWC);
  548. addMTLPixelFormatDesc(RGBA32Float, Color128, All);
  549. // Compressed pixel formats
  550. addMTLPixelFormatDesc(PVRTC_RGBA_2BPP, PVRTC_RGBA_2BPP, RF);
  551. addMTLPixelFormatDescSRGB(PVRTC_RGBA_2BPP_sRGB, PVRTC_RGBA_2BPP, RF, PVRTC_RGBA_2BPP);
  552. addMTLPixelFormatDesc(PVRTC_RGBA_4BPP, PVRTC_RGBA_4BPP, RF);
  553. addMTLPixelFormatDescSRGB(PVRTC_RGBA_4BPP_sRGB, PVRTC_RGBA_4BPP, RF, PVRTC_RGBA_4BPP);
  554. addMTLPixelFormatDesc(ETC2_RGB8, ETC2_RGB8, RF);
  555. addMTLPixelFormatDescSRGB(ETC2_RGB8_sRGB, ETC2_RGB8, RF, ETC2_RGB8);
  556. addMTLPixelFormatDesc(ETC2_RGB8A1, ETC2_RGB8A1, RF);
  557. addMTLPixelFormatDescSRGB(ETC2_RGB8A1_sRGB, ETC2_RGB8A1, RF, ETC2_RGB8A1);
  558. addMTLPixelFormatDesc(EAC_RGBA8, EAC_RGBA8, RF);
  559. addMTLPixelFormatDescSRGB(EAC_RGBA8_sRGB, EAC_RGBA8, RF, EAC_RGBA8);
  560. addMTLPixelFormatDesc(EAC_R11Unorm, EAC_R11, RF);
  561. addMTLPixelFormatDesc(EAC_R11Snorm, EAC_R11, RF);
  562. addMTLPixelFormatDesc(EAC_RG11Unorm, EAC_RG11, RF);
  563. addMTLPixelFormatDesc(EAC_RG11Snorm, EAC_RG11, RF);
  564. addMTLPixelFormatDesc(ASTC_4x4_LDR, ASTC_4x4, RF);
  565. addMTLPixelFormatDescSRGB(ASTC_4x4_sRGB, ASTC_4x4, RF, ASTC_4x4_LDR);
  566. addMTLPixelFormatDesc(ASTC_4x4_HDR, ASTC_4x4, RF);
  567. addMTLPixelFormatDesc(ASTC_5x4_LDR, ASTC_5x4, RF);
  568. addMTLPixelFormatDescSRGB(ASTC_5x4_sRGB, ASTC_5x4, RF, ASTC_5x4_LDR);
  569. addMTLPixelFormatDesc(ASTC_5x4_HDR, ASTC_5x4, RF);
  570. addMTLPixelFormatDesc(ASTC_5x5_LDR, ASTC_5x5, RF);
  571. addMTLPixelFormatDescSRGB(ASTC_5x5_sRGB, ASTC_5x5, RF, ASTC_5x5_LDR);
  572. addMTLPixelFormatDesc(ASTC_5x5_HDR, ASTC_5x5, RF);
  573. addMTLPixelFormatDesc(ASTC_6x5_LDR, ASTC_6x5, RF);
  574. addMTLPixelFormatDescSRGB(ASTC_6x5_sRGB, ASTC_6x5, RF, ASTC_6x5_LDR);
  575. addMTLPixelFormatDesc(ASTC_6x5_HDR, ASTC_6x5, RF);
  576. addMTLPixelFormatDesc(ASTC_6x6_LDR, ASTC_6x6, RF);
  577. addMTLPixelFormatDescSRGB(ASTC_6x6_sRGB, ASTC_6x6, RF, ASTC_6x6_LDR);
  578. addMTLPixelFormatDesc(ASTC_6x6_HDR, ASTC_6x6, RF);
  579. addMTLPixelFormatDesc(ASTC_8x5_LDR, ASTC_8x5, RF);
  580. addMTLPixelFormatDescSRGB(ASTC_8x5_sRGB, ASTC_8x5, RF, ASTC_8x5_LDR);
  581. addMTLPixelFormatDesc(ASTC_8x5_HDR, ASTC_8x5, RF);
  582. addMTLPixelFormatDesc(ASTC_8x6_LDR, ASTC_8x6, RF);
  583. addMTLPixelFormatDescSRGB(ASTC_8x6_sRGB, ASTC_8x6, RF, ASTC_8x6_LDR);
  584. addMTLPixelFormatDesc(ASTC_8x6_HDR, ASTC_8x6, RF);
  585. addMTLPixelFormatDesc(ASTC_8x8_LDR, ASTC_8x8, RF);
  586. addMTLPixelFormatDescSRGB(ASTC_8x8_sRGB, ASTC_8x8, RF, ASTC_8x8_LDR);
  587. addMTLPixelFormatDesc(ASTC_8x8_HDR, ASTC_8x8, RF);
  588. addMTLPixelFormatDesc(ASTC_10x5_LDR, ASTC_10x5, RF);
  589. addMTLPixelFormatDescSRGB(ASTC_10x5_sRGB, ASTC_10x5, RF, ASTC_10x5_LDR);
  590. addMTLPixelFormatDesc(ASTC_10x5_HDR, ASTC_10x5, RF);
  591. addMTLPixelFormatDesc(ASTC_10x6_LDR, ASTC_10x6, RF);
  592. addMTLPixelFormatDescSRGB(ASTC_10x6_sRGB, ASTC_10x6, RF, ASTC_10x6_LDR);
  593. addMTLPixelFormatDesc(ASTC_10x6_HDR, ASTC_10x6, RF);
  594. addMTLPixelFormatDesc(ASTC_10x8_LDR, ASTC_10x8, RF);
  595. addMTLPixelFormatDescSRGB(ASTC_10x8_sRGB, ASTC_10x8, RF, ASTC_10x8_LDR);
  596. addMTLPixelFormatDesc(ASTC_10x8_HDR, ASTC_10x8, RF);
  597. addMTLPixelFormatDesc(ASTC_10x10_LDR, ASTC_10x10, RF);
  598. addMTLPixelFormatDescSRGB(ASTC_10x10_sRGB, ASTC_10x10, RF, ASTC_10x10_LDR);
  599. addMTLPixelFormatDesc(ASTC_10x10_HDR, ASTC_10x10, RF);
  600. addMTLPixelFormatDesc(ASTC_12x10_LDR, ASTC_12x10, RF);
  601. addMTLPixelFormatDescSRGB(ASTC_12x10_sRGB, ASTC_12x10, RF, ASTC_12x10_LDR);
  602. addMTLPixelFormatDesc(ASTC_12x10_HDR, ASTC_12x10, RF);
  603. addMTLPixelFormatDesc(ASTC_12x12_LDR, ASTC_12x12, RF);
  604. addMTLPixelFormatDescSRGB(ASTC_12x12_sRGB, ASTC_12x12, RF, ASTC_12x12_LDR);
  605. addMTLPixelFormatDesc(ASTC_12x12_HDR, ASTC_12x12, RF);
  606. #pragma clang diagnostic push
  607. #pragma clang diagnostic ignored "-Wunguarded-availability"
  608. addMTLPixelFormatDesc(BC1_RGBA, BC1_RGBA, RF);
  609. addMTLPixelFormatDescSRGB(BC1_RGBA_sRGB, BC1_RGBA, RF, BC1_RGBA);
  610. addMTLPixelFormatDesc(BC2_RGBA, BC2_RGBA, RF);
  611. addMTLPixelFormatDescSRGB(BC2_RGBA_sRGB, BC2_RGBA, RF, BC2_RGBA);
  612. addMTLPixelFormatDesc(BC3_RGBA, BC3_RGBA, RF);
  613. addMTLPixelFormatDescSRGB(BC3_RGBA_sRGB, BC3_RGBA, RF, BC3_RGBA);
  614. addMTLPixelFormatDesc(BC4_RUnorm, BC4_R, RF);
  615. addMTLPixelFormatDesc(BC4_RSnorm, BC4_R, RF);
  616. addMTLPixelFormatDesc(BC5_RGUnorm, BC5_RG, RF);
  617. addMTLPixelFormatDesc(BC5_RGSnorm, BC5_RG, RF);
  618. addMTLPixelFormatDesc(BC6H_RGBUfloat, BC6H_RGB, RF);
  619. addMTLPixelFormatDesc(BC6H_RGBFloat, BC6H_RGB, RF);
  620. addMTLPixelFormatDesc(BC7_RGBAUnorm, BC7_RGBA, RF);
  621. addMTLPixelFormatDescSRGB(BC7_RGBAUnorm_sRGB, BC7_RGBA, RF, BC7_RGBAUnorm);
  622. #pragma clang diagnostic pop
  623. // YUV pixel formats
  624. addMTLPixelFormatDesc(GBGR422, None, RF);
  625. addMTLPixelFormatDesc(BGRG422, None, RF);
  626. // Extended range and wide color pixel formats
  627. addMTLPixelFormatDesc(BGRA10_XR, BGRA10_XR, All);
  628. addMTLPixelFormatDescSRGB(BGRA10_XR_sRGB, BGRA10_XR, All, BGRA10_XR);
  629. addMTLPixelFormatDesc(BGR10_XR, BGR10_XR, All);
  630. addMTLPixelFormatDescSRGB(BGR10_XR_sRGB, BGR10_XR, All, BGR10_XR);
  631. // Depth and stencil pixel formats
  632. addMTLPixelFormatDesc(Depth16Unorm, None, DRFMR);
  633. addMTLPixelFormatDesc(Depth32Float, None, DRMR);
  634. addMTLPixelFormatDesc(Stencil8, None, DRM);
  635. addMTLPixelFormatDesc(Depth24Unorm_Stencil8, Depth24_Stencil8, None);
  636. addMTLPixelFormatDesc(Depth32Float_Stencil8, Depth32_Stencil8, DRMR);
  637. addMTLPixelFormatDesc(X24_Stencil8, Depth24_Stencil8, None);
  638. addMTLPixelFormatDesc(X32_Stencil8, Depth32_Stencil8, DRM);
  639. }
  640. // If necessary, resize vector with empty elements.
  641. void PixelFormats::addMTLVertexFormatDescImpl(MTLVertexFormat mtlVtxFmt, MTLFmtCaps vtxCap, const char *name) {
  642. if (mtlVtxFmt >= _mtl_vertex_format_descs.size()) {
  643. _mtl_vertex_format_descs.resize(mtlVtxFmt + 1);
  644. }
  645. _mtl_vertex_format_descs[mtlVtxFmt] = { .mtlVertexFormat = mtlVtxFmt, RD::DATA_FORMAT_MAX, vtxCap, MTLViewClass::None, MTLPixelFormatInvalid, name };
  646. }
  647. // Check mtlVtx exists on platform, to avoid overwriting the MTLVertexFormatInvalid entry.
  648. #define addMTLVertexFormatDesc(mtlVtx) \
  649. if (MTLVertexFormat##mtlVtx) { \
  650. addMTLVertexFormatDescImpl(MTLVertexFormat##mtlVtx, kMTLFmtCapsVertex, "MTLVertexFormat" #mtlVtx); \
  651. }
  652. void PixelFormats::initMTLVertexFormatCapabilities(const MetalFeatures &p_feat) {
  653. _mtl_vertex_format_descs.resize(MTLVertexFormatHalf + 3);
  654. // MTLVertexFormatInvalid must come first. Use addMTLVertexFormatDescImpl to avoid guard code.
  655. addMTLVertexFormatDescImpl(MTLVertexFormatInvalid, kMTLFmtCapsNone, "MTLVertexFormatInvalid");
  656. addMTLVertexFormatDesc(UChar2Normalized);
  657. addMTLVertexFormatDesc(Char2Normalized);
  658. addMTLVertexFormatDesc(UChar2);
  659. addMTLVertexFormatDesc(Char2);
  660. addMTLVertexFormatDesc(UChar3Normalized);
  661. addMTLVertexFormatDesc(Char3Normalized);
  662. addMTLVertexFormatDesc(UChar3);
  663. addMTLVertexFormatDesc(Char3);
  664. addMTLVertexFormatDesc(UChar4Normalized);
  665. addMTLVertexFormatDesc(Char4Normalized);
  666. addMTLVertexFormatDesc(UChar4);
  667. addMTLVertexFormatDesc(Char4);
  668. addMTLVertexFormatDesc(UInt1010102Normalized);
  669. addMTLVertexFormatDesc(Int1010102Normalized);
  670. addMTLVertexFormatDesc(UShort2Normalized);
  671. addMTLVertexFormatDesc(Short2Normalized);
  672. addMTLVertexFormatDesc(UShort2);
  673. addMTLVertexFormatDesc(Short2);
  674. addMTLVertexFormatDesc(Half2);
  675. addMTLVertexFormatDesc(UShort3Normalized);
  676. addMTLVertexFormatDesc(Short3Normalized);
  677. addMTLVertexFormatDesc(UShort3);
  678. addMTLVertexFormatDesc(Short3);
  679. addMTLVertexFormatDesc(Half3);
  680. addMTLVertexFormatDesc(UShort4Normalized);
  681. addMTLVertexFormatDesc(Short4Normalized);
  682. addMTLVertexFormatDesc(UShort4);
  683. addMTLVertexFormatDesc(Short4);
  684. addMTLVertexFormatDesc(Half4);
  685. addMTLVertexFormatDesc(UInt);
  686. addMTLVertexFormatDesc(Int);
  687. addMTLVertexFormatDesc(Float);
  688. addMTLVertexFormatDesc(UInt2);
  689. addMTLVertexFormatDesc(Int2);
  690. addMTLVertexFormatDesc(Float2);
  691. addMTLVertexFormatDesc(UInt3);
  692. addMTLVertexFormatDesc(Int3);
  693. addMTLVertexFormatDesc(Float3);
  694. addMTLVertexFormatDesc(UInt4);
  695. addMTLVertexFormatDesc(Int4);
  696. addMTLVertexFormatDesc(Float4);
  697. addMTLVertexFormatDesc(UCharNormalized);
  698. addMTLVertexFormatDesc(CharNormalized);
  699. addMTLVertexFormatDesc(UChar);
  700. addMTLVertexFormatDesc(Char);
  701. addMTLVertexFormatDesc(UShortNormalized);
  702. addMTLVertexFormatDesc(ShortNormalized);
  703. addMTLVertexFormatDesc(UShort);
  704. addMTLVertexFormatDesc(Short);
  705. addMTLVertexFormatDesc(Half);
  706. addMTLVertexFormatDesc(UChar4Normalized_BGRA);
  707. if (@available(macos 14.0, ios 17.0, tvos 17.0, *)) {
  708. if (p_feat.highestFamily >= MTLGPUFamilyApple5) {
  709. addMTLVertexFormatDesc(FloatRG11B10);
  710. addMTLVertexFormatDesc(FloatRGB9E5);
  711. }
  712. }
  713. }
  714. // Return a reference to the format capabilities, so the caller can manipulate them.
  715. // Check mtlPixFmt exists on platform, to avoid overwriting the MTLPixelFormatInvalid entry.
  716. // When returning the dummy, reset it on each access because it can be written to by caller.
  717. MTLFmtCaps &PixelFormats::getMTLPixelFormatCapsIf(MTLPixelFormat mtlPixFmt, bool cond) {
  718. static MTLFmtCaps dummyFmtCaps;
  719. if (mtlPixFmt && cond) {
  720. return getMTLPixelFormatDesc(mtlPixFmt).mtlFmtCaps;
  721. } else {
  722. dummyFmtCaps = kMTLFmtCapsNone;
  723. return dummyFmtCaps;
  724. }
  725. }
  726. #define setMTLPixFmtCapsIf(cond, mtlFmt, caps) getMTLPixelFormatCapsIf(MTLPixelFormat##mtlFmt, cond) = kMTLFmtCaps##caps;
  727. #define setMTLPixFmtCapsIfGPU(gpuFam, mtlFmt, caps) setMTLPixFmtCapsIf(gpuCaps.supports##gpuFam, mtlFmt, caps)
  728. #define enableMTLPixFmtCapsIf(cond, mtlFmt, caps) flags::set(getMTLPixelFormatCapsIf(MTLPixelFormat##mtlFmt, cond), kMTLFmtCaps##caps);
  729. #define enableMTLPixFmtCapsIfGPU(gpuFam, mtlFmt, caps) enableMTLPixFmtCapsIf(p_feat.highestFamily >= MTLGPUFamily##gpuFam, mtlFmt, caps)
  730. #define disableMTLPixFmtCapsIf(cond, mtlFmt, caps) flags::clear(getMTLPixelFormatCapsIf(MTLPixelFormat##mtlFmt, cond), kMTLFmtCaps##caps);
  731. // Modifies the format capability tables based on the capabilities of the specific MTLDevice.
  732. void PixelFormats::modifyMTLFormatCapabilities(const MetalFeatures &p_feat) {
  733. bool noVulkanSupport = false; // Indicated supported in Metal but not Vulkan or SPIR-V.
  734. bool notMac = !p_feat.supportsMac;
  735. bool iosOnly1 = notMac && p_feat.highestFamily < MTLGPUFamilyApple2;
  736. bool iosOnly2 = notMac && p_feat.highestFamily < MTLGPUFamilyApple3;
  737. bool iosOnly6 = notMac && p_feat.highestFamily < MTLGPUFamilyApple7;
  738. bool iosOnly8 = notMac && p_feat.highestFamily < MTLGPUFamilyApple9;
  739. setMTLPixFmtCapsIf(iosOnly2, A8Unorm, RF);
  740. setMTLPixFmtCapsIf(iosOnly1, R8Unorm_sRGB, RFCMRB);
  741. setMTLPixFmtCapsIf(iosOnly1, R8Snorm, RFWCMB);
  742. setMTLPixFmtCapsIf(iosOnly1, RG8Unorm_sRGB, RFCMRB);
  743. setMTLPixFmtCapsIf(iosOnly1, RG8Snorm, RFWCMB);
  744. enableMTLPixFmtCapsIfGPU(Apple6, R32Uint, Atomic);
  745. enableMTLPixFmtCapsIfGPU(Apple6, R32Sint, Atomic);
  746. setMTLPixFmtCapsIf(iosOnly8, R32Float, RWCMB);
  747. setMTLPixFmtCapsIf(iosOnly1, RGBA8Unorm_sRGB, RFCMRB);
  748. setMTLPixFmtCapsIf(iosOnly1, RGBA8Snorm, RFWCMB);
  749. setMTLPixFmtCapsIf(iosOnly1, BGRA8Unorm_sRGB, RFCMRB);
  750. setMTLPixFmtCapsIf(iosOnly2, RGB10A2Unorm, RFCMRB);
  751. setMTLPixFmtCapsIf(iosOnly2, RGB10A2Uint, RCM);
  752. setMTLPixFmtCapsIf(iosOnly2, RG11B10Float, RFCMRB);
  753. setMTLPixFmtCapsIf(iosOnly2, RGB9E5Float, RFCMRB);
  754. // Blending is actually supported for RGB9E5Float, but format channels cannot
  755. // be individually write-enabled during blending on macOS. Disabling blending
  756. // on macOS is the least-intrusive way to handle this in a Vulkan-friendly way.
  757. disableMTLPixFmtCapsIf(p_feat.supportsMac, RGB9E5Float, Blend);
  758. // RGB9E5Float cannot be used as a render target on the simulator.
  759. disableMTLPixFmtCapsIf(TARGET_OS_SIMULATOR, RGB9E5Float, ColorAtt);
  760. setMTLPixFmtCapsIf(iosOnly6, RG32Uint, RWC);
  761. setMTLPixFmtCapsIf(iosOnly6, RG32Sint, RWC);
  762. // Metal supports reading both R&G into as one 64-bit atomic operation, but Vulkan and SPIR-V do not.
  763. // Including this here so we remember to update this if support is added to Vulkan in the future.
  764. bool atomic64 = noVulkanSupport && (p_feat.highestFamily >= MTLGPUFamilyApple9 || (p_feat.highestFamily >= MTLGPUFamilyApple8 && p_feat.supportsMac));
  765. enableMTLPixFmtCapsIf(atomic64, RG32Uint, Atomic);
  766. enableMTLPixFmtCapsIf(atomic64, RG32Sint, Atomic);
  767. setMTLPixFmtCapsIf(iosOnly8, RG32Float, RWCMB);
  768. setMTLPixFmtCapsIf(iosOnly6, RG32Float, RWCB);
  769. setMTLPixFmtCapsIf(iosOnly8, RGBA32Float, RWCM);
  770. setMTLPixFmtCapsIf(iosOnly6, RGBA32Float, RWC);
  771. bool msaa32 = p_feat.supports32BitMSAA;
  772. enableMTLPixFmtCapsIf(msaa32, R32Uint, MSAA);
  773. enableMTLPixFmtCapsIf(msaa32, R32Sint, MSAA);
  774. enableMTLPixFmtCapsIf(msaa32, R32Float, Resolve);
  775. enableMTLPixFmtCapsIf(msaa32, RG32Uint, MSAA);
  776. enableMTLPixFmtCapsIf(msaa32, RG32Sint, MSAA);
  777. enableMTLPixFmtCapsIf(msaa32, RG32Float, Resolve);
  778. enableMTLPixFmtCapsIf(msaa32, RGBA32Uint, MSAA);
  779. enableMTLPixFmtCapsIf(msaa32, RGBA32Sint, MSAA);
  780. enableMTLPixFmtCapsIf(msaa32, RGBA32Float, Resolve);
  781. bool floatFB = p_feat.supports32BitFloatFiltering;
  782. enableMTLPixFmtCapsIf(floatFB, R32Float, Filter);
  783. enableMTLPixFmtCapsIf(floatFB, RG32Float, Filter);
  784. enableMTLPixFmtCapsIf(floatFB, RGBA32Float, Filter);
  785. enableMTLPixFmtCapsIf(floatFB, RGBA32Float, Blend); // Undocumented by confirmed through testing.
  786. bool noHDR_ASTC = p_feat.highestFamily < MTLGPUFamilyApple6;
  787. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_4x4_HDR, None);
  788. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_5x4_HDR, None);
  789. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_5x5_HDR, None);
  790. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_6x5_HDR, None);
  791. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_6x6_HDR, None);
  792. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_8x5_HDR, None);
  793. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_8x6_HDR, None);
  794. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_8x8_HDR, None);
  795. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x5_HDR, None);
  796. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x6_HDR, None);
  797. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x8_HDR, None);
  798. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x10_HDR, None);
  799. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x10_HDR, None);
  800. setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x12_HDR, None);
  801. #pragma clang diagnostic push
  802. #pragma clang diagnostic ignored "-Wunguarded-availability"
  803. bool noBC = !p_feat.supportsBCTextureCompression;
  804. setMTLPixFmtCapsIf(noBC, BC1_RGBA, None);
  805. setMTLPixFmtCapsIf(noBC, BC1_RGBA_sRGB, None);
  806. setMTLPixFmtCapsIf(noBC, BC2_RGBA, None);
  807. setMTLPixFmtCapsIf(noBC, BC2_RGBA_sRGB, None);
  808. setMTLPixFmtCapsIf(noBC, BC3_RGBA, None);
  809. setMTLPixFmtCapsIf(noBC, BC3_RGBA_sRGB, None);
  810. setMTLPixFmtCapsIf(noBC, BC4_RUnorm, None);
  811. setMTLPixFmtCapsIf(noBC, BC4_RSnorm, None);
  812. setMTLPixFmtCapsIf(noBC, BC5_RGUnorm, None);
  813. setMTLPixFmtCapsIf(noBC, BC5_RGSnorm, None);
  814. setMTLPixFmtCapsIf(noBC, BC6H_RGBUfloat, None);
  815. setMTLPixFmtCapsIf(noBC, BC6H_RGBFloat, None);
  816. setMTLPixFmtCapsIf(noBC, BC7_RGBAUnorm, None);
  817. setMTLPixFmtCapsIf(noBC, BC7_RGBAUnorm_sRGB, None);
  818. #pragma clang diagnostic pop
  819. setMTLPixFmtCapsIf(iosOnly2, BGRA10_XR, None);
  820. setMTLPixFmtCapsIf(iosOnly2, BGRA10_XR_sRGB, None);
  821. setMTLPixFmtCapsIf(iosOnly2, BGR10_XR, None);
  822. setMTLPixFmtCapsIf(iosOnly2, BGR10_XR_sRGB, None);
  823. setMTLPixFmtCapsIf(iosOnly2, Depth16Unorm, DRFM);
  824. setMTLPixFmtCapsIf(iosOnly2, Depth32Float, DRM);
  825. setMTLPixFmtCapsIf(!p_feat.supportsDepth24Stencil8, Depth24Unorm_Stencil8, None);
  826. setMTLPixFmtCapsIf(iosOnly2, Depth32Float_Stencil8, DRM);
  827. }
  828. // Populates the DataFormat lookup maps and connects Godot and Metal pixel formats to one-another.
  829. void PixelFormats::buildDFFormatMaps() {
  830. for (DataFormatDesc &dfDesc : _data_format_descs) {
  831. // Populate the back reference from the Metal formats to the Godot format.
  832. // Validate the corresponding Metal formats for the platform, and clear them
  833. // in the Godot format if not supported.
  834. if (dfDesc.mtlPixelFormat) {
  835. MTLFormatDesc &mtlDesc = getMTLPixelFormatDesc(dfDesc.mtlPixelFormat);
  836. if (mtlDesc.dataFormat == RD::DATA_FORMAT_MAX) {
  837. mtlDesc.dataFormat = dfDesc.dataFormat;
  838. }
  839. if (!mtlDesc.isSupported()) {
  840. dfDesc.mtlPixelFormat = MTLPixelFormatInvalid;
  841. }
  842. }
  843. if (dfDesc.mtlPixelFormatSubstitute) {
  844. MTLFormatDesc &mtlDesc = getMTLPixelFormatDesc(dfDesc.mtlPixelFormatSubstitute);
  845. if (!mtlDesc.isSupported()) {
  846. dfDesc.mtlPixelFormatSubstitute = MTLPixelFormatInvalid;
  847. }
  848. }
  849. if (dfDesc.mtlVertexFormat) {
  850. MTLFormatDesc &mtlDesc = getMTLVertexFormatDesc(dfDesc.mtlVertexFormat);
  851. if (mtlDesc.dataFormat == RD::DATA_FORMAT_MAX) {
  852. mtlDesc.dataFormat = dfDesc.dataFormat;
  853. }
  854. if (!mtlDesc.isSupported()) {
  855. dfDesc.mtlVertexFormat = MTLVertexFormatInvalid;
  856. }
  857. }
  858. if (dfDesc.mtlVertexFormatSubstitute) {
  859. MTLFormatDesc &mtlDesc = getMTLVertexFormatDesc(dfDesc.mtlVertexFormatSubstitute);
  860. if (!mtlDesc.isSupported()) {
  861. dfDesc.mtlVertexFormatSubstitute = MTLVertexFormatInvalid;
  862. }
  863. }
  864. }
  865. }