3
0

DdsFile.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/Utils/DdsFile.h>
  9. #include <Atom/RHI.Reflect/ImageSubresource.h>
  10. #include <AzCore/IO/FileIO.h>
  11. #include <AzCore/IO/GenericStreams.h>
  12. namespace AZ
  13. {
  14. namespace
  15. {
  16. // Flags to indicate which members contain valid data
  17. enum DdsFlags : uint32_t
  18. {
  19. Unknown = 0x00000000,
  20. Caps = 0x00000001, // DDSD_CAPS
  21. Height = 0x00000002, // DDSD_HEIGHT
  22. Width = 0x00000004, // DDSD_WIDTH
  23. Pitch = 0x00000008, // DDSD_PITCH
  24. PixelFormat = 0x00001000, // DDSD_PIXELFORMAT
  25. MipmapCount = 0x00020000, // DDSD_MIPMAPCOUNT
  26. LinearSize = 0x00080000, // DDSD_LINEARSIZE
  27. Depth = 0x00800000, // DDSD_DEPTH
  28. };
  29. // Specifies the complexity of the surfaces stored
  30. enum DdsCaps : uint32_t
  31. {
  32. Complex = 0x00000008, // DDSCAPS_COMPLEX
  33. Mipmap = 0x00400000, // DDSCAPS_MIPMAP
  34. Texture = 0x00001000, // DDSCAPS_TEXTURE
  35. };
  36. // Additional detail about the surfaces stored.
  37. enum DdsCaps2 : uint32_t
  38. {
  39. Cubemap = 0x00000200, // DDSCAPS2_CUBEMAP
  40. PositiveX = 0x00000400, // DDSCAPS2_CUBEMAP_POSITIVEX
  41. NegativeX = 0x00000800, // DDSCAPS2_CUBEMAP_NEGATIVEX
  42. PositiveY = 0x00001000, // DDSCAPS2_CUBEMAP_POSITIVEY
  43. NegativeY = 0x00002000, // DDSCAPS2_CUBEMAP_NEGATIVEY
  44. PositiveZ = 0x00004000, // DDSCAPS2_CUBEMAP_POSITIVEZ
  45. NegativeZ = 0x00008000, // DDSCAPS2_CUBEMAP_NEGATIVEZ
  46. CubemapAll = Cubemap | PositiveX | NegativeX | PositiveY | NegativeY | PositiveZ | NegativeZ, //DDS_CUBEMAP_ALLFACES
  47. Volume = 0x00200000, // DDSCAPS2_VOLUME
  48. };
  49. enum PixelFormatFlags : uint32_t
  50. {
  51. AlphaPixels = 0x00000001, // DDPF_ALPHAPIXELS
  52. Alpha = 0x00000002, // DDPF_ALPHA
  53. FourCC = 0x00000004, // DDPF_FOURCC
  54. RGB = 0x00000040, // DDPF_RGB
  55. YUV = 0x00000200, // DDPF_YUV
  56. Luminance = 0x00020000, // DDPF_LUMINANCE
  57. };
  58. enum class ResourceDimension : uint32_t
  59. {
  60. Unknown = 0, // D3D10_RESOURCE_DIMENSION_UNKNOWN
  61. Buffer = 1, // D3D10_RESOURCE_DIMENSION_BUFFER
  62. Texture1D = 2, // D3D10_RESOURCE_DIMENSION_TEXTURE1D
  63. Texture2D = 3, // D3D10_RESOURCE_DIMENSION_TEXTURE2D
  64. Texture3D = 4, // D3D10_RESOURCE_DIMENSION_TEXTURE3D
  65. };
  66. enum Dx10MiscFlags : uint32_t
  67. {
  68. TextureCube = 0x4, // DDS_RESOURCE_MISC_TEXTURECUBE
  69. };
  70. enum class DxgiFormat : uint32_t
  71. {
  72. UNKNOWN = 0,
  73. R32G32B32A32_TYPELESS = 1,
  74. R32G32B32A32_FLOAT = 2,
  75. R32G32B32A32_UINT = 3,
  76. R32G32B32A32_SINT = 4,
  77. R32G32B32_TYPELESS = 5,
  78. R32G32B32_FLOAT = 6,
  79. R32G32B32_UINT = 7,
  80. R32G32B32_SINT = 8,
  81. R16G16B16A16_TYPELESS = 9,
  82. R16G16B16A16_FLOAT = 10,
  83. R16G16B16A16_UNORM = 11,
  84. R16G16B16A16_UINT = 12,
  85. R16G16B16A16_SNORM = 13,
  86. R16G16B16A16_SINT = 14,
  87. R32G32_TYPELESS = 15,
  88. R32G32_FLOAT = 16,
  89. R32G32_UINT = 17,
  90. R32G32_SINT = 18,
  91. R32G8X24_TYPELESS = 19,
  92. D32_FLOAT_S8X24_UINT = 20,
  93. R32_FLOAT_X8X24_TYPELESS = 21,
  94. X32_TYPELESS_G8X24_UINT = 22,
  95. R10G10B10A2_TYPELESS = 23,
  96. R10G10B10A2_UNORM = 24,
  97. R10G10B10A2_UINT = 25,
  98. R11G11B10_FLOAT = 26,
  99. R8G8B8A8_TYPELESS = 27,
  100. R8G8B8A8_UNORM = 28,
  101. R8G8B8A8_UNORM_SRGB = 29,
  102. R8G8B8A8_UINT = 30,
  103. R8G8B8A8_SNORM = 31,
  104. R8G8B8A8_SINT = 32,
  105. R16G16_TYPELESS = 33,
  106. R16G16_FLOAT = 34,
  107. R16G16_UNORM = 35,
  108. R16G16_UINT = 36,
  109. R16G16_SNORM = 37,
  110. R16G16_SINT = 38,
  111. R32_TYPELESS = 39,
  112. D32_FLOAT = 40,
  113. R32_FLOAT = 41,
  114. R32_UINT = 42,
  115. R32_SINT = 43,
  116. R24G8_TYPELESS = 44,
  117. D24_UNORM_S8_UINT = 45,
  118. R24_UNORM_X8_TYPELESS = 46,
  119. X24_TYPELESS_G8_UINT = 47,
  120. R8G8_TYPELESS = 48,
  121. R8G8_UNORM = 49,
  122. R8G8_UINT = 50,
  123. R8G8_SNORM = 51,
  124. R8G8_SINT = 52,
  125. R16_TYPELESS = 53,
  126. R16_FLOAT = 54,
  127. D16_UNORM = 55,
  128. R16_UNORM = 56,
  129. R16_UINT = 57,
  130. R16_SNORM = 58,
  131. R16_SINT = 59,
  132. R8_TYPELESS = 60,
  133. R8_UNORM = 61,
  134. R8_UINT = 62,
  135. R8_SNORM = 63,
  136. R8_SINT = 64,
  137. A8_UNORM = 65,
  138. R1_UNORM = 66,
  139. R9G9B9E5_SHAREDEXP = 67,
  140. R8G8_B8G8_UNORM = 68,
  141. G8R8_G8B8_UNORM = 69,
  142. BC1_TYPELESS = 70,
  143. BC1_UNORM = 71,
  144. BC1_UNORM_SRGB = 72,
  145. BC2_TYPELESS = 73,
  146. BC2_UNORM = 74,
  147. BC2_UNORM_SRGB = 75,
  148. BC3_TYPELESS = 76,
  149. BC3_UNORM = 77,
  150. BC3_UNORM_SRGB = 78,
  151. BC4_TYPELESS = 79,
  152. BC4_UNORM = 80,
  153. BC4_SNORM = 81,
  154. BC5_TYPELESS = 82,
  155. BC5_UNORM = 83,
  156. BC5_SNORM = 84,
  157. B5G6R5_UNORM = 85,
  158. B5G5R5A1_UNORM = 86,
  159. B8G8R8A8_UNORM = 87,
  160. B8G8R8X8_UNORM = 88,
  161. R10G10B10_XR_BIAS_A2_UNORM = 89,
  162. B8G8R8A8_TYPELESS = 90,
  163. B8G8R8A8_UNORM_SRGB = 91,
  164. B8G8R8X8_TYPELESS = 92,
  165. B8G8R8X8_UNORM_SRGB = 93,
  166. BC6H_TYPELESS = 94,
  167. BC6H_UF16 = 95,
  168. BC6H_SF16 = 96,
  169. BC7_TYPELESS = 97,
  170. BC7_UNORM = 98,
  171. BC7_UNORM_SRGB = 99,
  172. AYUV = 100,
  173. Y410 = 101,
  174. Y416 = 102,
  175. NV12 = 103,
  176. P010 = 104,
  177. P016 = 105,
  178. _420_OPAQUE = 106,
  179. YUY2 = 107,
  180. Y210 = 108,
  181. Y216 = 109,
  182. NV11 = 110,
  183. AI44 = 111,
  184. IA44 = 112,
  185. P8 = 113,
  186. A8P8 = 114,
  187. B4G4R4A4_UNORM = 115,
  188. // Hardware specific
  189. R10G10B10_7E3_A2_FLOAT = 116,
  190. R10G10B10_6E4_A2_FLOAT = 117,
  191. D16_UNORM_S8_UINT = 118,
  192. X16_TYPELESS_G8_UINT = 120,
  193. // Dxgi 3.1 specific
  194. P208 = 130,
  195. V208 = 131,
  196. V408 = 132,
  197. };
  198. constexpr uint32_t MakeFourCC(char ch0 = ' ', char ch1 = ' ', char ch2 = ' ', char ch3 = ' ')
  199. {
  200. return ((uint32_t)(uint8_t)(ch0)
  201. | ((uint32_t)(uint8_t)(ch1) << 8)
  202. | ((uint32_t)(uint8_t)(ch2) << 16)
  203. | ((uint32_t)(uint8_t)(ch3) << 24));
  204. }
  205. }
  206. DxgiFormat DxgiFormatFromRhiFormat(const RHI::Format format)
  207. {
  208. switch (format)
  209. {
  210. case RHI::Format::R32G32B32A32_FLOAT:
  211. return DxgiFormat::R32G32B32A32_FLOAT;
  212. case RHI::Format::R32G32B32A32_UINT:
  213. return DxgiFormat::R32G32B32A32_UINT;
  214. case RHI::Format::R32G32B32A32_SINT:
  215. return DxgiFormat::R32G32B32A32_SINT;
  216. case RHI::Format::R32G32B32_FLOAT:
  217. return DxgiFormat::R32G32B32_FLOAT;
  218. case RHI::Format::R32G32B32_UINT:
  219. return DxgiFormat::R32G32B32_UINT;
  220. case RHI::Format::R32G32B32_SINT:
  221. return DxgiFormat::R32G32B32_SINT;
  222. case RHI::Format::R16G16B16A16_FLOAT:
  223. return DxgiFormat::R16G16B16A16_FLOAT;
  224. case RHI::Format::R16G16B16A16_UNORM:
  225. return DxgiFormat::R16G16B16A16_UNORM;
  226. case RHI::Format::R16G16B16A16_UINT:
  227. return DxgiFormat::R16G16B16A16_UINT;
  228. case RHI::Format::R16G16B16A16_SNORM:
  229. return DxgiFormat::R16G16B16A16_SNORM;
  230. case RHI::Format::R16G16B16A16_SINT:
  231. return DxgiFormat::R16G16B16A16_SINT;
  232. case RHI::Format::R32G32_FLOAT:
  233. return DxgiFormat::R32G32_FLOAT;
  234. case RHI::Format::R32G32_UINT:
  235. return DxgiFormat::R32G32_UINT;
  236. case RHI::Format::R32G32_SINT:
  237. return DxgiFormat::R32G32_SINT;
  238. case RHI::Format::D32_FLOAT_S8X24_UINT:
  239. return DxgiFormat::D32_FLOAT_S8X24_UINT;
  240. case RHI::Format::R10G10B10A2_UNORM:
  241. return DxgiFormat::R10G10B10A2_UNORM;
  242. case RHI::Format::R10G10B10A2_UINT:
  243. return DxgiFormat::R10G10B10A2_UINT;
  244. case RHI::Format::R11G11B10_FLOAT:
  245. return DxgiFormat::R11G11B10_FLOAT;
  246. case RHI::Format::R8G8B8A8_UNORM:
  247. return DxgiFormat::R8G8B8A8_UNORM;
  248. case RHI::Format::R8G8B8A8_UNORM_SRGB:
  249. return DxgiFormat::R8G8B8A8_UNORM_SRGB;
  250. case RHI::Format::R8G8B8A8_UINT:
  251. return DxgiFormat::R8G8B8A8_UINT;
  252. case RHI::Format::R8G8B8A8_SNORM:
  253. return DxgiFormat::R8G8B8A8_SNORM;
  254. case RHI::Format::R8G8B8A8_SINT:
  255. return DxgiFormat::R8G8B8A8_SINT;
  256. case RHI::Format::R16G16_FLOAT:
  257. return DxgiFormat::R16G16_FLOAT;
  258. case RHI::Format::R16G16_UNORM:
  259. return DxgiFormat::R16G16_UNORM;
  260. case RHI::Format::R16G16_UINT:
  261. return DxgiFormat::R16G16_UINT;
  262. case RHI::Format::R16G16_SNORM:
  263. return DxgiFormat::R16G16_SNORM;
  264. case RHI::Format::R16G16_SINT:
  265. return DxgiFormat::R16G16_SINT;
  266. case RHI::Format::D32_FLOAT:
  267. return DxgiFormat::D32_FLOAT;
  268. case RHI::Format::R32_FLOAT:
  269. return DxgiFormat::R32_FLOAT;
  270. case RHI::Format::R32_UINT:
  271. return DxgiFormat::R32_UINT;
  272. case RHI::Format::R32_SINT:
  273. return DxgiFormat::R32_SINT;
  274. case RHI::Format::D24_UNORM_S8_UINT:
  275. return DxgiFormat::D24_UNORM_S8_UINT;
  276. case RHI::Format::R8G8_UNORM:
  277. return DxgiFormat::R8G8_UNORM;
  278. case RHI::Format::R8G8_UINT:
  279. return DxgiFormat::R8G8_UINT;
  280. case RHI::Format::R8G8_SNORM:
  281. return DxgiFormat::R8G8_SNORM;
  282. case RHI::Format::R8G8_SINT:
  283. return DxgiFormat::R8G8_SINT;
  284. case RHI::Format::R16_FLOAT:
  285. return DxgiFormat::R16_FLOAT;
  286. case RHI::Format::D16_UNORM:
  287. return DxgiFormat::D16_UNORM;
  288. case RHI::Format::R16_UNORM:
  289. return DxgiFormat::R16_UNORM;
  290. case RHI::Format::R16_UINT:
  291. return DxgiFormat::R16_UINT;
  292. case RHI::Format::R16_SNORM:
  293. return DxgiFormat::R16_SNORM;
  294. case RHI::Format::R16_SINT:
  295. return DxgiFormat::R16_SINT;
  296. case RHI::Format::R8_UNORM:
  297. return DxgiFormat::R8_UNORM;
  298. case RHI::Format::R8_UINT:
  299. return DxgiFormat::R8_UINT;
  300. case RHI::Format::R8_SNORM:
  301. return DxgiFormat::R8_SNORM;
  302. case RHI::Format::R8_SINT:
  303. return DxgiFormat::R8_SINT;
  304. case RHI::Format::A8_UNORM:
  305. return DxgiFormat::A8_UNORM;
  306. case RHI::Format::R1_UNORM:
  307. return DxgiFormat::R1_UNORM;
  308. case RHI::Format::R9G9B9E5_SHAREDEXP:
  309. return DxgiFormat::R9G9B9E5_SHAREDEXP;
  310. case RHI::Format::R8G8_B8G8_UNORM:
  311. return DxgiFormat::R8G8_B8G8_UNORM;
  312. case RHI::Format::G8R8_G8B8_UNORM:
  313. return DxgiFormat::G8R8_G8B8_UNORM;
  314. case RHI::Format::BC1_UNORM:
  315. return DxgiFormat::BC1_UNORM;
  316. case RHI::Format::BC1_UNORM_SRGB:
  317. return DxgiFormat::BC1_UNORM_SRGB;
  318. case RHI::Format::BC2_UNORM:
  319. return DxgiFormat::BC2_UNORM;
  320. case RHI::Format::BC2_UNORM_SRGB:
  321. return DxgiFormat::BC2_UNORM_SRGB;
  322. case RHI::Format::BC3_UNORM:
  323. return DxgiFormat::BC3_UNORM;
  324. case RHI::Format::BC3_UNORM_SRGB:
  325. return DxgiFormat::BC3_UNORM_SRGB;
  326. case RHI::Format::BC4_UNORM:
  327. return DxgiFormat::BC4_UNORM;
  328. case RHI::Format::BC4_SNORM:
  329. return DxgiFormat::BC4_SNORM;
  330. case RHI::Format::BC5_UNORM:
  331. return DxgiFormat::BC5_UNORM;
  332. case RHI::Format::BC5_SNORM:
  333. return DxgiFormat::BC5_SNORM;
  334. case RHI::Format::B5G6R5_UNORM:
  335. return DxgiFormat::B5G6R5_UNORM;
  336. case RHI::Format::B5G5R5A1_UNORM:
  337. return DxgiFormat::B5G5R5A1_UNORM;
  338. case RHI::Format::B8G8R8A8_UNORM:
  339. return DxgiFormat::B8G8R8A8_UNORM;
  340. case RHI::Format::B8G8R8X8_UNORM:
  341. return DxgiFormat::B8G8R8X8_UNORM;
  342. case RHI::Format::R10G10B10_XR_BIAS_A2_UNORM:
  343. return DxgiFormat::R10G10B10_XR_BIAS_A2_UNORM;
  344. case RHI::Format::B8G8R8A8_UNORM_SRGB:
  345. return DxgiFormat::B8G8R8A8_UNORM_SRGB;
  346. case RHI::Format::B8G8R8X8_UNORM_SRGB:
  347. return DxgiFormat::B8G8R8X8_UNORM_SRGB;
  348. case RHI::Format::BC6H_UF16:
  349. return DxgiFormat::BC6H_UF16;
  350. case RHI::Format::BC6H_SF16:
  351. return DxgiFormat::BC6H_SF16;
  352. case RHI::Format::BC7_UNORM:
  353. return DxgiFormat::BC7_UNORM;
  354. case RHI::Format::BC7_UNORM_SRGB:
  355. return DxgiFormat::BC7_UNORM_SRGB;
  356. case RHI::Format::AYUV:
  357. return DxgiFormat::AYUV;
  358. case RHI::Format::Y410:
  359. return DxgiFormat::Y410;
  360. case RHI::Format::Y416:
  361. return DxgiFormat::Y416;
  362. case RHI::Format::NV12:
  363. return DxgiFormat::NV12;
  364. case RHI::Format::P010:
  365. return DxgiFormat::P010;
  366. case RHI::Format::P016:
  367. return DxgiFormat::P016;
  368. case RHI::Format::YUY2:
  369. return DxgiFormat::YUY2;
  370. case RHI::Format::Y210:
  371. return DxgiFormat::Y210;
  372. case RHI::Format::Y216:
  373. return DxgiFormat::Y216;
  374. case RHI::Format::NV11:
  375. return DxgiFormat::NV11;
  376. case RHI::Format::AI44:
  377. return DxgiFormat::AI44;
  378. case RHI::Format::IA44:
  379. return DxgiFormat::IA44;
  380. case RHI::Format::P8:
  381. return DxgiFormat::P8;
  382. case RHI::Format::A8P8:
  383. return DxgiFormat::A8P8;
  384. case RHI::Format::B4G4R4A4_UNORM:
  385. return DxgiFormat::B4G4R4A4_UNORM;
  386. case RHI::Format::R10G10B10_7E3_A2_FLOAT:
  387. return DxgiFormat::R10G10B10_7E3_A2_FLOAT;
  388. case RHI::Format::R10G10B10_6E4_A2_FLOAT:
  389. return DxgiFormat::R10G10B10_6E4_A2_FLOAT;
  390. case RHI::Format::D16_UNORM_S8_UINT:
  391. return DxgiFormat::D16_UNORM_S8_UINT;
  392. case RHI::Format::X16_TYPELESS_G8_UINT:
  393. return DxgiFormat::X16_TYPELESS_G8_UINT;
  394. case RHI::Format::P208:
  395. return DxgiFormat::P208;
  396. case RHI::Format::V208:
  397. return DxgiFormat::V208;
  398. case RHI::Format::V408:
  399. return DxgiFormat::V408;
  400. case RHI::Format::EAC_R11_UNORM:
  401. case RHI::Format::EAC_R11_SNORM:
  402. case RHI::Format::EAC_RG11_UNORM:
  403. case RHI::Format::EAC_RG11_SNORM:
  404. case RHI::Format::ETC2_UNORM:
  405. case RHI::Format::ETC2_UNORM_SRGB:
  406. case RHI::Format::ETC2A_UNORM:
  407. case RHI::Format::ETC2A_UNORM_SRGB:
  408. case RHI::Format::ETC2A1_UNORM:
  409. case RHI::Format::ETC2A1_UNORM_SRGB:
  410. return DxgiFormat::UNKNOWN; // Not supported by dds
  411. case RHI::Format::PVRTC2_UNORM:
  412. case RHI::Format::PVRTC2_UNORM_SRGB:
  413. case RHI::Format::PVRTC4_UNORM:
  414. case RHI::Format::PVRTC4_UNORM_SRGB:
  415. return DxgiFormat::UNKNOWN; // Not supported by dds
  416. case RHI::Format::ASTC_4x4_UNORM:
  417. case RHI::Format::ASTC_4x4_UNORM_SRGB:
  418. case RHI::Format::ASTC_5x4_UNORM:
  419. case RHI::Format::ASTC_5x4_UNORM_SRGB:
  420. case RHI::Format::ASTC_5x5_UNORM:
  421. case RHI::Format::ASTC_5x5_UNORM_SRGB:
  422. case RHI::Format::ASTC_6x5_UNORM:
  423. case RHI::Format::ASTC_6x5_UNORM_SRGB:
  424. case RHI::Format::ASTC_6x6_UNORM:
  425. case RHI::Format::ASTC_6x6_UNORM_SRGB:
  426. case RHI::Format::ASTC_8x5_UNORM:
  427. case RHI::Format::ASTC_8x5_UNORM_SRGB:
  428. case RHI::Format::ASTC_8x6_UNORM:
  429. case RHI::Format::ASTC_8x6_UNORM_SRGB:
  430. case RHI::Format::ASTC_8x8_UNORM:
  431. case RHI::Format::ASTC_8x8_UNORM_SRGB:
  432. case RHI::Format::ASTC_10x5_UNORM:
  433. case RHI::Format::ASTC_10x5_UNORM_SRGB:
  434. case RHI::Format::ASTC_10x6_UNORM:
  435. case RHI::Format::ASTC_10x6_UNORM_SRGB:
  436. case RHI::Format::ASTC_10x8_UNORM:
  437. case RHI::Format::ASTC_10x8_UNORM_SRGB:
  438. case RHI::Format::ASTC_10x10_UNORM:
  439. case RHI::Format::ASTC_10x10_UNORM_SRGB:
  440. case RHI::Format::ASTC_12x10_UNORM:
  441. case RHI::Format::ASTC_12x10_UNORM_SRGB:
  442. case RHI::Format::ASTC_12x12_UNORM:
  443. case RHI::Format::ASTC_12x12_UNORM_SRGB:
  444. return DxgiFormat::UNKNOWN; // Not supported by dds
  445. default:
  446. return DxgiFormat::UNKNOWN;
  447. }
  448. }
  449. DdsFlags PitchOrLinearSizeFromFormat(const RHI::Format format)
  450. {
  451. switch (format)
  452. {
  453. case RHI::Format::R32G32B32A32_FLOAT:
  454. case RHI::Format::R32G32B32A32_UINT:
  455. case RHI::Format::R32G32B32A32_SINT:
  456. case RHI::Format::R32G32B32_FLOAT:
  457. case RHI::Format::R32G32B32_UINT:
  458. case RHI::Format::R32G32B32_SINT:
  459. case RHI::Format::R16G16B16A16_FLOAT:
  460. case RHI::Format::R16G16B16A16_UNORM:
  461. case RHI::Format::R16G16B16A16_UINT:
  462. case RHI::Format::R16G16B16A16_SNORM:
  463. case RHI::Format::R16G16B16A16_SINT:
  464. case RHI::Format::R32G32_FLOAT:
  465. case RHI::Format::R32G32_UINT:
  466. case RHI::Format::R32G32_SINT:
  467. case RHI::Format::D32_FLOAT_S8X24_UINT:
  468. case RHI::Format::R10G10B10A2_UNORM:
  469. case RHI::Format::R10G10B10A2_UINT:
  470. case RHI::Format::R11G11B10_FLOAT:
  471. case RHI::Format::R8G8B8A8_UNORM:
  472. case RHI::Format::R8G8B8A8_UNORM_SRGB:
  473. case RHI::Format::R8G8B8A8_UINT:
  474. case RHI::Format::R8G8B8A8_SNORM:
  475. case RHI::Format::R8G8B8A8_SINT:
  476. case RHI::Format::R16G16_FLOAT:
  477. case RHI::Format::R16G16_UNORM:
  478. case RHI::Format::R16G16_UINT:
  479. case RHI::Format::R16G16_SNORM:
  480. case RHI::Format::R16G16_SINT:
  481. case RHI::Format::D32_FLOAT:
  482. case RHI::Format::R32_FLOAT:
  483. case RHI::Format::R32_UINT:
  484. case RHI::Format::R32_SINT:
  485. case RHI::Format::D24_UNORM_S8_UINT:
  486. case RHI::Format::R8G8_UNORM:
  487. case RHI::Format::R8G8_UINT:
  488. case RHI::Format::R8G8_SNORM:
  489. case RHI::Format::R8G8_SINT:
  490. case RHI::Format::R16_FLOAT:
  491. case RHI::Format::D16_UNORM:
  492. case RHI::Format::R16_UNORM:
  493. case RHI::Format::R16_UINT:
  494. case RHI::Format::R16_SNORM:
  495. case RHI::Format::R16_SINT:
  496. case RHI::Format::R8_UNORM:
  497. case RHI::Format::R8_UINT:
  498. case RHI::Format::R8_SNORM:
  499. case RHI::Format::R8_SINT:
  500. case RHI::Format::A8_UNORM:
  501. case RHI::Format::R1_UNORM:
  502. case RHI::Format::R9G9B9E5_SHAREDEXP:
  503. case RHI::Format::R8G8_B8G8_UNORM:
  504. case RHI::Format::G8R8_G8B8_UNORM:
  505. return DdsFlags::Pitch;
  506. case RHI::Format::BC1_UNORM:
  507. case RHI::Format::BC1_UNORM_SRGB:
  508. case RHI::Format::BC2_UNORM:
  509. case RHI::Format::BC2_UNORM_SRGB:
  510. case RHI::Format::BC3_UNORM:
  511. case RHI::Format::BC3_UNORM_SRGB:
  512. case RHI::Format::BC4_UNORM:
  513. case RHI::Format::BC4_SNORM:
  514. case RHI::Format::BC5_UNORM:
  515. case RHI::Format::BC5_SNORM:
  516. return DdsFlags::LinearSize;
  517. case RHI::Format::B5G6R5_UNORM:
  518. case RHI::Format::B5G5R5A1_UNORM:
  519. case RHI::Format::B8G8R8A8_UNORM:
  520. case RHI::Format::B8G8R8X8_UNORM:
  521. case RHI::Format::R10G10B10_XR_BIAS_A2_UNORM:
  522. case RHI::Format::B8G8R8A8_UNORM_SRGB:
  523. case RHI::Format::B8G8R8X8_UNORM_SRGB:
  524. return DdsFlags::Pitch;
  525. case RHI::Format::BC6H_UF16:
  526. case RHI::Format::BC6H_SF16:
  527. case RHI::Format::BC7_UNORM:
  528. case RHI::Format::BC7_UNORM_SRGB:
  529. return DdsFlags::LinearSize;
  530. case RHI::Format::AYUV:
  531. case RHI::Format::Y410:
  532. case RHI::Format::Y416:
  533. case RHI::Format::NV12:
  534. case RHI::Format::P010:
  535. case RHI::Format::P016:
  536. case RHI::Format::YUY2:
  537. case RHI::Format::Y210:
  538. case RHI::Format::Y216:
  539. case RHI::Format::NV11:
  540. case RHI::Format::AI44:
  541. case RHI::Format::IA44:
  542. case RHI::Format::P8:
  543. case RHI::Format::A8P8:
  544. case RHI::Format::B4G4R4A4_UNORM:
  545. case RHI::Format::R10G10B10_7E3_A2_FLOAT:
  546. case RHI::Format::R10G10B10_6E4_A2_FLOAT:
  547. case RHI::Format::D16_UNORM_S8_UINT:
  548. case RHI::Format::X16_TYPELESS_G8_UINT:
  549. case RHI::Format::P208:
  550. case RHI::Format::V208:
  551. case RHI::Format::V408:
  552. return DdsFlags::Pitch;
  553. case RHI::Format::EAC_R11_UNORM:
  554. case RHI::Format::EAC_R11_SNORM:
  555. case RHI::Format::EAC_RG11_UNORM:
  556. case RHI::Format::EAC_RG11_SNORM:
  557. case RHI::Format::ETC2_UNORM:
  558. case RHI::Format::ETC2_UNORM_SRGB:
  559. case RHI::Format::ETC2A_UNORM:
  560. case RHI::Format::ETC2A_UNORM_SRGB:
  561. case RHI::Format::ETC2A1_UNORM:
  562. case RHI::Format::ETC2A1_UNORM_SRGB:
  563. return DdsFlags::Unknown; // Not supported by dds
  564. case RHI::Format::PVRTC2_UNORM:
  565. case RHI::Format::PVRTC2_UNORM_SRGB:
  566. case RHI::Format::PVRTC4_UNORM:
  567. case RHI::Format::PVRTC4_UNORM_SRGB:
  568. return DdsFlags::Unknown; // Not supported by dds
  569. case RHI::Format::ASTC_4x4_UNORM:
  570. case RHI::Format::ASTC_4x4_UNORM_SRGB:
  571. case RHI::Format::ASTC_5x4_UNORM:
  572. case RHI::Format::ASTC_5x4_UNORM_SRGB:
  573. case RHI::Format::ASTC_5x5_UNORM:
  574. case RHI::Format::ASTC_5x5_UNORM_SRGB:
  575. case RHI::Format::ASTC_6x5_UNORM:
  576. case RHI::Format::ASTC_6x5_UNORM_SRGB:
  577. case RHI::Format::ASTC_6x6_UNORM:
  578. case RHI::Format::ASTC_6x6_UNORM_SRGB:
  579. case RHI::Format::ASTC_8x5_UNORM:
  580. case RHI::Format::ASTC_8x5_UNORM_SRGB:
  581. case RHI::Format::ASTC_8x6_UNORM:
  582. case RHI::Format::ASTC_8x6_UNORM_SRGB:
  583. case RHI::Format::ASTC_8x8_UNORM:
  584. case RHI::Format::ASTC_8x8_UNORM_SRGB:
  585. case RHI::Format::ASTC_10x5_UNORM:
  586. case RHI::Format::ASTC_10x5_UNORM_SRGB:
  587. case RHI::Format::ASTC_10x6_UNORM:
  588. case RHI::Format::ASTC_10x6_UNORM_SRGB:
  589. case RHI::Format::ASTC_10x8_UNORM:
  590. case RHI::Format::ASTC_10x8_UNORM_SRGB:
  591. case RHI::Format::ASTC_10x10_UNORM:
  592. case RHI::Format::ASTC_10x10_UNORM_SRGB:
  593. case RHI::Format::ASTC_12x10_UNORM:
  594. case RHI::Format::ASTC_12x10_UNORM_SRGB:
  595. case RHI::Format::ASTC_12x12_UNORM:
  596. case RHI::Format::ASTC_12x12_UNORM_SRGB:
  597. return DdsFlags::Unknown; // Not supported by dds
  598. default:
  599. return DdsFlags::Unknown;
  600. }
  601. }
  602. // DdsFile function definitions
  603. DdsFile::DdsFile()
  604. : m_magic(MakeFourCC('D', 'D', 'S'))
  605. {
  606. }
  607. DdsFile::~DdsFile()
  608. {
  609. }
  610. void DdsFile::SetSize(RHI::Size size)
  611. {
  612. m_header.m_width = size.m_width;
  613. m_header.m_height = size.m_height;
  614. if (size.m_depth > 1)
  615. {
  616. m_header.m_flags |= DdsFlags::Depth;
  617. m_header.m_depth = size.m_depth;
  618. SetAsVolumeTexture();
  619. }
  620. else
  621. {
  622. m_header.m_flags &= ~DdsFlags::Depth;
  623. m_header.m_depth = 1;
  624. }
  625. m_headerDx10.m_arraySize = 1;
  626. if (size.m_width > 1 && size.m_height > 1 && size.m_depth > 1)
  627. {
  628. m_headerDx10.m_resourceDimension = static_cast<uint32_t>(ResourceDimension::Texture3D);
  629. }
  630. else if (size.m_width > 1 && size.m_height > 1)
  631. {
  632. m_headerDx10.m_resourceDimension = static_cast<uint32_t>(ResourceDimension::Texture2D);
  633. }
  634. else if (size.m_width > 1)
  635. {
  636. m_headerDx10.m_resourceDimension = static_cast<uint32_t>(ResourceDimension::Texture1D);
  637. }
  638. else
  639. {
  640. m_headerDx10.m_resourceDimension = static_cast<uint32_t>(ResourceDimension::Unknown);
  641. }
  642. ResolvePitch();
  643. }
  644. RHI::Size DdsFile::GetSize()
  645. {
  646. return RHI::Size(m_header.m_width, m_header.m_height, m_header.m_depth);
  647. }
  648. void DdsFile::SetFormat(RHI::Format format)
  649. {
  650. m_externalFormat = format;
  651. m_headerDx10.m_dxgiFormat = static_cast<uint32_t>(DxgiFormatFromRhiFormat(format));
  652. ResolvePitch();
  653. }
  654. RHI::Format DdsFile::GetFormat()
  655. {
  656. return m_externalFormat;
  657. }
  658. void DdsFile::SetAsCubemap()
  659. {
  660. m_header.m_caps |= DdsCaps::Complex;
  661. m_header.m_caps_2 |= DdsCaps2::CubemapAll;
  662. m_headerDx10.m_miscFlag |= Dx10MiscFlags::TextureCube;
  663. }
  664. void DdsFile::SetAsVolumeTexture()
  665. {
  666. m_header.m_caps |= DdsCaps::Complex;
  667. m_header.m_caps_2 |= DdsCaps2::Volume;
  668. }
  669. void DdsFile::SetMipLevels(uint32_t mipLevels)
  670. {
  671. m_header.m_mipMapCount = mipLevels;
  672. if (mipLevels > 1)
  673. {
  674. m_header.m_mipMapCount = mipLevels;
  675. m_header.m_caps |= DdsCaps::Complex | DdsCaps::Mipmap;
  676. m_header.m_flags |= DdsFlags::MipmapCount;
  677. }
  678. }
  679. uint32_t DdsFile::GetMipLevels()
  680. {
  681. return m_header.m_mipMapCount;
  682. }
  683. AZ::Outcome<void, DdsFile::DdsFailure> DdsFile::WriteHeaderToStream(AZ::IO::GenericStream& stream)
  684. {
  685. size_t bytesWritten = 0;
  686. bytesWritten += stream.Write(sizeof(m_magic), &m_magic);
  687. bytesWritten += stream.Write(sizeof(m_header), &m_header);
  688. bytesWritten += stream.Write(sizeof(m_headerDx10), &m_headerDx10);
  689. if (bytesWritten != sizeof(m_magic) + sizeof(m_header) + sizeof(m_headerDx10))
  690. {
  691. DdsFailure failure;
  692. failure.m_code = DdsFailure::Code::WriteFailed;
  693. failure.m_message.format("Failed to write all data to the stream");
  694. return AZ::Failure(failure);
  695. }
  696. return AZ::Success();
  697. }
  698. void DdsFile::ResolvePitch()
  699. {
  700. if (m_externalFormat != RHI::Format::Unknown)
  701. {
  702. m_header.m_flags &= ~(DdsFlags::Pitch | DdsFlags::LinearSize); // clear out the flags first.
  703. DdsFlags pitchOrLinearSize = PitchOrLinearSizeFromFormat(m_externalFormat);
  704. m_header.m_flags |= pitchOrLinearSize;
  705. RHI::ImageSubresourceLayout layout = RHI::GetImageSubresourceLayout(GetSize(), m_externalFormat);
  706. m_header.m_pitchOrLinearSize = layout.m_bytesPerRow;
  707. }
  708. }
  709. AZ::Outcome<void, DdsFile::DdsFailure> DdsFile::WriteFile(const AZStd::string& filePath, const DdsFileData& ddsFiledata)
  710. {
  711. DdsFile ddsFile;
  712. ddsFile.SetSize(ddsFiledata.m_size);
  713. ddsFile.SetFormat(ddsFiledata.m_format);
  714. if (ddsFiledata.m_isCubemap)
  715. {
  716. ddsFile.SetAsCubemap();
  717. }
  718. ddsFile.SetMipLevels(ddsFiledata.m_mipLevels);
  719. IO::FileIOStream fileStream(filePath.c_str(), IO::OpenMode::ModeWrite| IO::OpenMode::ModeCreatePath);
  720. if (!fileStream.IsOpen())
  721. {
  722. DdsFailure failure;
  723. failure.m_code = DdsFailure::Code::OpenFileFailed;
  724. failure.m_message.format("Failed to open \"%s\" for writing.", filePath.c_str());
  725. return AZ::Failure(failure);
  726. }
  727. auto outcome = ddsFile.WriteHeaderToStream(fileStream);
  728. size_t bytesWritten = fileStream.Write(ddsFiledata.m_buffer->size(), ddsFiledata.m_buffer->data());
  729. if (!outcome || bytesWritten != ddsFiledata.m_buffer->size())
  730. {
  731. DdsFailure failure;
  732. failure.m_code = DdsFailure::Code::WriteFailed;
  733. failure.m_message.format("Failed to write all data to \"%s\"", filePath.c_str());
  734. return AZ::Failure(failure);
  735. }
  736. return AZ::Success();
  737. }
  738. bool DdsFile::DoesSupportFormat(RHI::Format format)
  739. {
  740. return DxgiFormatFromRhiFormat(format) != DxgiFormat::UNKNOWN;
  741. }
  742. DdsFile::DdsPixelFormat::DdsPixelFormat()
  743. // By default, the pixel format struct is only there to point to the dx10 header by setting the fourCC to 'DX10'
  744. : m_fourCC(MakeFourCC('D', 'X', '1', '0'))
  745. , m_flags(PixelFormatFlags::FourCC)
  746. {
  747. }
  748. DdsFile::DdsHeader::DdsHeader()
  749. : m_flags(DdsFlags::Caps | DdsFlags::Height | DdsFlags::Width | DdsFlags::PixelFormat) // Set flags required by the DDS spec
  750. , m_caps(DdsCaps::Texture) // the texture flag is required by the DDS spec
  751. {
  752. }
  753. }// namespace AZ