surface.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <climits>
  6. #include <utility>
  7. #include "common/assert.h"
  8. #include "common/common_types.h"
  9. #include "common/logging/log.h"
  10. #include "video_core/gpu.h"
  11. #include "video_core/textures/texture.h"
  12. namespace VideoCore::Surface {
  13. enum class PixelFormat {
  14. ABGR8U = 0,
  15. ABGR8S = 1,
  16. ABGR8UI = 2,
  17. B5G6R5U = 3,
  18. A2B10G10R10U = 4,
  19. A1B5G5R5U = 5,
  20. R8U = 6,
  21. R8UI = 7,
  22. RGBA16F = 8,
  23. RGBA16U = 9,
  24. RGBA16UI = 10,
  25. R11FG11FB10F = 11,
  26. RGBA32UI = 12,
  27. DXT1 = 13,
  28. DXT23 = 14,
  29. DXT45 = 15,
  30. DXN1 = 16, // This is also known as BC4
  31. DXN2UNORM = 17,
  32. DXN2SNORM = 18,
  33. BC7U = 19,
  34. BC6H_UF16 = 20,
  35. BC6H_SF16 = 21,
  36. ASTC_2D_4X4 = 22,
  37. BGRA8 = 23,
  38. RGBA32F = 24,
  39. RG32F = 25,
  40. R32F = 26,
  41. R16F = 27,
  42. R16U = 28,
  43. R16S = 29,
  44. R16UI = 30,
  45. R16I = 31,
  46. RG16 = 32,
  47. RG16F = 33,
  48. RG16UI = 34,
  49. RG16I = 35,
  50. RG16S = 36,
  51. RGB32F = 37,
  52. RGBA8_SRGB = 38,
  53. RG8U = 39,
  54. RG8S = 40,
  55. RG32UI = 41,
  56. R32UI = 42,
  57. ASTC_2D_8X8 = 43,
  58. ASTC_2D_8X5 = 44,
  59. ASTC_2D_5X4 = 45,
  60. BGRA8_SRGB = 46,
  61. DXT1_SRGB = 47,
  62. DXT23_SRGB = 48,
  63. DXT45_SRGB = 49,
  64. BC7U_SRGB = 50,
  65. ASTC_2D_4X4_SRGB = 51,
  66. ASTC_2D_8X8_SRGB = 52,
  67. ASTC_2D_8X5_SRGB = 53,
  68. ASTC_2D_5X4_SRGB = 54,
  69. ASTC_2D_5X5 = 55,
  70. ASTC_2D_5X5_SRGB = 56,
  71. ASTC_2D_10X8 = 57,
  72. ASTC_2D_10X8_SRGB = 58,
  73. MaxColorFormat,
  74. // Depth formats
  75. Z32F = 59,
  76. Z16 = 60,
  77. MaxDepthFormat,
  78. // DepthStencil formats
  79. Z24S8 = 61,
  80. S8Z24 = 62,
  81. Z32FS8 = 63,
  82. MaxDepthStencilFormat,
  83. Max = MaxDepthStencilFormat,
  84. Invalid = 255,
  85. };
  86. static constexpr std::size_t MaxPixelFormat = static_cast<std::size_t>(PixelFormat::Max);
  87. enum class ComponentType {
  88. Invalid = 0,
  89. SNorm = 1,
  90. UNorm = 2,
  91. SInt = 3,
  92. UInt = 4,
  93. Float = 5,
  94. };
  95. enum class SurfaceType {
  96. ColorTexture = 0,
  97. Depth = 1,
  98. DepthStencil = 2,
  99. Invalid = 3,
  100. };
  101. enum class SurfaceTarget {
  102. Texture1D,
  103. TextureBuffer,
  104. Texture2D,
  105. Texture3D,
  106. Texture1DArray,
  107. Texture2DArray,
  108. TextureCubemap,
  109. TextureCubeArray,
  110. };
  111. constexpr std::array<u32, MaxPixelFormat> compression_factor_shift_table = {{
  112. 0, // ABGR8U
  113. 0, // ABGR8S
  114. 0, // ABGR8UI
  115. 0, // B5G6R5U
  116. 0, // A2B10G10R10U
  117. 0, // A1B5G5R5U
  118. 0, // R8U
  119. 0, // R8UI
  120. 0, // RGBA16F
  121. 0, // RGBA16U
  122. 0, // RGBA16UI
  123. 0, // R11FG11FB10F
  124. 0, // RGBA32UI
  125. 2, // DXT1
  126. 2, // DXT23
  127. 2, // DXT45
  128. 2, // DXN1
  129. 2, // DXN2UNORM
  130. 2, // DXN2SNORM
  131. 2, // BC7U
  132. 2, // BC6H_UF16
  133. 2, // BC6H_SF16
  134. 2, // ASTC_2D_4X4
  135. 0, // BGRA8
  136. 0, // RGBA32F
  137. 0, // RG32F
  138. 0, // R32F
  139. 0, // R16F
  140. 0, // R16U
  141. 0, // R16S
  142. 0, // R16UI
  143. 0, // R16I
  144. 0, // RG16
  145. 0, // RG16F
  146. 0, // RG16UI
  147. 0, // RG16I
  148. 0, // RG16S
  149. 0, // RGB32F
  150. 0, // RGBA8_SRGB
  151. 0, // RG8U
  152. 0, // RG8S
  153. 0, // RG32UI
  154. 0, // R32UI
  155. 2, // ASTC_2D_8X8
  156. 2, // ASTC_2D_8X5
  157. 2, // ASTC_2D_5X4
  158. 0, // BGRA8_SRGB
  159. 2, // DXT1_SRGB
  160. 2, // DXT23_SRGB
  161. 2, // DXT45_SRGB
  162. 2, // BC7U_SRGB
  163. 2, // ASTC_2D_4X4_SRGB
  164. 2, // ASTC_2D_8X8_SRGB
  165. 2, // ASTC_2D_8X5_SRGB
  166. 2, // ASTC_2D_5X4_SRGB
  167. 2, // ASTC_2D_5X5
  168. 2, // ASTC_2D_5X5_SRGB
  169. 2, // ASTC_2D_10X8
  170. 2, // ASTC_2D_10X8_SRGB
  171. 0, // Z32F
  172. 0, // Z16
  173. 0, // Z24S8
  174. 0, // S8Z24
  175. 0, // Z32FS8
  176. }};
  177. /**
  178. * Gets the compression factor for the specified PixelFormat. This applies to just the
  179. * "compressed width" and "compressed height", not the overall compression factor of a
  180. * compressed image. This is used for maintaining proper surface sizes for compressed
  181. * texture formats.
  182. */
  183. inline constexpr u32 GetCompressionFactorShift(PixelFormat format) {
  184. DEBUG_ASSERT(format != PixelFormat::Invalid);
  185. DEBUG_ASSERT(static_cast<std::size_t>(format) < compression_factor_shift_table.size());
  186. return compression_factor_shift_table[static_cast<std::size_t>(format)];
  187. }
  188. inline constexpr u32 GetCompressionFactor(PixelFormat format) {
  189. return 1U << GetCompressionFactorShift(format);
  190. }
  191. constexpr std::array<u32, MaxPixelFormat> block_width_table = {{
  192. 1, // ABGR8U
  193. 1, // ABGR8S
  194. 1, // ABGR8UI
  195. 1, // B5G6R5U
  196. 1, // A2B10G10R10U
  197. 1, // A1B5G5R5U
  198. 1, // R8U
  199. 1, // R8UI
  200. 1, // RGBA16F
  201. 1, // RGBA16U
  202. 1, // RGBA16UI
  203. 1, // R11FG11FB10F
  204. 1, // RGBA32UI
  205. 4, // DXT1
  206. 4, // DXT23
  207. 4, // DXT45
  208. 4, // DXN1
  209. 4, // DXN2UNORM
  210. 4, // DXN2SNORM
  211. 4, // BC7U
  212. 4, // BC6H_UF16
  213. 4, // BC6H_SF16
  214. 4, // ASTC_2D_4X4
  215. 1, // BGRA8
  216. 1, // RGBA32F
  217. 1, // RG32F
  218. 1, // R32F
  219. 1, // R16F
  220. 1, // R16U
  221. 1, // R16S
  222. 1, // R16UI
  223. 1, // R16I
  224. 1, // RG16
  225. 1, // RG16F
  226. 1, // RG16UI
  227. 1, // RG16I
  228. 1, // RG16S
  229. 1, // RGB32F
  230. 1, // RGBA8_SRGB
  231. 1, // RG8U
  232. 1, // RG8S
  233. 1, // RG32UI
  234. 1, // R32UI
  235. 8, // ASTC_2D_8X8
  236. 8, // ASTC_2D_8X5
  237. 5, // ASTC_2D_5X4
  238. 1, // BGRA8_SRGB
  239. 4, // DXT1_SRGB
  240. 4, // DXT23_SRGB
  241. 4, // DXT45_SRGB
  242. 4, // BC7U_SRGB
  243. 4, // ASTC_2D_4X4_SRGB
  244. 8, // ASTC_2D_8X8_SRGB
  245. 8, // ASTC_2D_8X5_SRGB
  246. 5, // ASTC_2D_5X4_SRGB
  247. 5, // ASTC_2D_5X5
  248. 5, // ASTC_2D_5X5_SRGB
  249. 10, // ASTC_2D_10X8
  250. 10, // ASTC_2D_10X8_SRGB
  251. 1, // Z32F
  252. 1, // Z16
  253. 1, // Z24S8
  254. 1, // S8Z24
  255. 1, // Z32FS8
  256. }};
  257. static constexpr u32 GetDefaultBlockWidth(PixelFormat format) {
  258. if (format == PixelFormat::Invalid)
  259. return 0;
  260. ASSERT(static_cast<std::size_t>(format) < block_width_table.size());
  261. return block_width_table[static_cast<std::size_t>(format)];
  262. }
  263. constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
  264. 1, // ABGR8U
  265. 1, // ABGR8S
  266. 1, // ABGR8UI
  267. 1, // B5G6R5U
  268. 1, // A2B10G10R10U
  269. 1, // A1B5G5R5U
  270. 1, // R8U
  271. 1, // R8UI
  272. 1, // RGBA16F
  273. 1, // RGBA16U
  274. 1, // RGBA16UI
  275. 1, // R11FG11FB10F
  276. 1, // RGBA32UI
  277. 4, // DXT1
  278. 4, // DXT23
  279. 4, // DXT45
  280. 4, // DXN1
  281. 4, // DXN2UNORM
  282. 4, // DXN2SNORM
  283. 4, // BC7U
  284. 4, // BC6H_UF16
  285. 4, // BC6H_SF16
  286. 4, // ASTC_2D_4X4
  287. 1, // BGRA8
  288. 1, // RGBA32F
  289. 1, // RG32F
  290. 1, // R32F
  291. 1, // R16F
  292. 1, // R16U
  293. 1, // R16S
  294. 1, // R16UI
  295. 1, // R16I
  296. 1, // RG16
  297. 1, // RG16F
  298. 1, // RG16UI
  299. 1, // RG16I
  300. 1, // RG16S
  301. 1, // RGB32F
  302. 1, // RGBA8_SRGB
  303. 1, // RG8U
  304. 1, // RG8S
  305. 1, // RG32UI
  306. 1, // R32UI
  307. 8, // ASTC_2D_8X8
  308. 5, // ASTC_2D_8X5
  309. 4, // ASTC_2D_5X4
  310. 1, // BGRA8_SRGB
  311. 4, // DXT1_SRGB
  312. 4, // DXT23_SRGB
  313. 4, // DXT45_SRGB
  314. 4, // BC7U_SRGB
  315. 4, // ASTC_2D_4X4_SRGB
  316. 8, // ASTC_2D_8X8_SRGB
  317. 5, // ASTC_2D_8X5_SRGB
  318. 4, // ASTC_2D_5X4_SRGB
  319. 5, // ASTC_2D_5X5
  320. 5, // ASTC_2D_5X5_SRGB
  321. 8, // ASTC_2D_10X8
  322. 8, // ASTC_2D_10X8_SRGB
  323. 1, // Z32F
  324. 1, // Z16
  325. 1, // Z24S8
  326. 1, // S8Z24
  327. 1, // Z32FS8
  328. }};
  329. static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
  330. if (format == PixelFormat::Invalid)
  331. return 0;
  332. ASSERT(static_cast<std::size_t>(format) < block_height_table.size());
  333. return block_height_table[static_cast<std::size_t>(format)];
  334. }
  335. constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
  336. 32, // ABGR8U
  337. 32, // ABGR8S
  338. 32, // ABGR8UI
  339. 16, // B5G6R5U
  340. 32, // A2B10G10R10U
  341. 16, // A1B5G5R5U
  342. 8, // R8U
  343. 8, // R8UI
  344. 64, // RGBA16F
  345. 64, // RGBA16U
  346. 64, // RGBA16UI
  347. 32, // R11FG11FB10F
  348. 128, // RGBA32UI
  349. 64, // DXT1
  350. 128, // DXT23
  351. 128, // DXT45
  352. 64, // DXN1
  353. 128, // DXN2UNORM
  354. 128, // DXN2SNORM
  355. 128, // BC7U
  356. 128, // BC6H_UF16
  357. 128, // BC6H_SF16
  358. 128, // ASTC_2D_4X4
  359. 32, // BGRA8
  360. 128, // RGBA32F
  361. 64, // RG32F
  362. 32, // R32F
  363. 16, // R16F
  364. 16, // R16U
  365. 16, // R16S
  366. 16, // R16UI
  367. 16, // R16I
  368. 32, // RG16
  369. 32, // RG16F
  370. 32, // RG16UI
  371. 32, // RG16I
  372. 32, // RG16S
  373. 96, // RGB32F
  374. 32, // RGBA8_SRGB
  375. 16, // RG8U
  376. 16, // RG8S
  377. 64, // RG32UI
  378. 32, // R32UI
  379. 128, // ASTC_2D_8X8
  380. 128, // ASTC_2D_8X5
  381. 128, // ASTC_2D_5X4
  382. 32, // BGRA8_SRGB
  383. 64, // DXT1_SRGB
  384. 128, // DXT23_SRGB
  385. 128, // DXT45_SRGB
  386. 128, // BC7U
  387. 128, // ASTC_2D_4X4_SRGB
  388. 128, // ASTC_2D_8X8_SRGB
  389. 128, // ASTC_2D_8X5_SRGB
  390. 128, // ASTC_2D_5X4_SRGB
  391. 128, // ASTC_2D_5X5
  392. 128, // ASTC_2D_5X5_SRGB
  393. 128, // ASTC_2D_10X8
  394. 128, // ASTC_2D_10X8_SRGB
  395. 32, // Z32F
  396. 16, // Z16
  397. 32, // Z24S8
  398. 32, // S8Z24
  399. 64, // Z32FS8
  400. }};
  401. static constexpr u32 GetFormatBpp(PixelFormat format) {
  402. if (format == PixelFormat::Invalid)
  403. return 0;
  404. ASSERT(static_cast<std::size_t>(format) < bpp_table.size());
  405. return bpp_table[static_cast<std::size_t>(format)];
  406. }
  407. /// Returns the sizer in bytes of the specified pixel format
  408. static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) {
  409. if (pixel_format == PixelFormat::Invalid) {
  410. return 0;
  411. }
  412. return GetFormatBpp(pixel_format) / CHAR_BIT;
  413. }
  414. enum class SurfaceCompression : u8 {
  415. None = 0,
  416. Compressed = 1,
  417. Converted = 2,
  418. Rearranged = 3,
  419. };
  420. constexpr std::array<SurfaceCompression, MaxPixelFormat> compression_type_table = {{
  421. SurfaceCompression::None, // ABGR8U
  422. SurfaceCompression::None, // ABGR8S
  423. SurfaceCompression::None, // ABGR8UI
  424. SurfaceCompression::None, // B5G6R5U
  425. SurfaceCompression::None, // A2B10G10R10U
  426. SurfaceCompression::None, // A1B5G5R5U
  427. SurfaceCompression::None, // R8U
  428. SurfaceCompression::None, // R8UI
  429. SurfaceCompression::None, // RGBA16F
  430. SurfaceCompression::None, // RGBA16U
  431. SurfaceCompression::None, // RGBA16UI
  432. SurfaceCompression::None, // R11FG11FB10F
  433. SurfaceCompression::None, // RGBA32UI
  434. SurfaceCompression::Compressed, // DXT1
  435. SurfaceCompression::Compressed, // DXT23
  436. SurfaceCompression::Compressed, // DXT45
  437. SurfaceCompression::Compressed, // DXN1
  438. SurfaceCompression::Compressed, // DXN2UNORM
  439. SurfaceCompression::Compressed, // DXN2SNORM
  440. SurfaceCompression::Compressed, // BC7U
  441. SurfaceCompression::Compressed, // BC6H_UF16
  442. SurfaceCompression::Compressed, // BC6H_SF16
  443. SurfaceCompression::Converted, // ASTC_2D_4X4
  444. SurfaceCompression::None, // BGRA8
  445. SurfaceCompression::None, // RGBA32F
  446. SurfaceCompression::None, // RG32F
  447. SurfaceCompression::None, // R32F
  448. SurfaceCompression::None, // R16F
  449. SurfaceCompression::None, // R16U
  450. SurfaceCompression::None, // R16S
  451. SurfaceCompression::None, // R16UI
  452. SurfaceCompression::None, // R16I
  453. SurfaceCompression::None, // RG16
  454. SurfaceCompression::None, // RG16F
  455. SurfaceCompression::None, // RG16UI
  456. SurfaceCompression::None, // RG16I
  457. SurfaceCompression::None, // RG16S
  458. SurfaceCompression::None, // RGB32F
  459. SurfaceCompression::None, // RGBA8_SRGB
  460. SurfaceCompression::None, // RG8U
  461. SurfaceCompression::None, // RG8S
  462. SurfaceCompression::None, // RG32UI
  463. SurfaceCompression::None, // R32UI
  464. SurfaceCompression::Converted, // ASTC_2D_8X8
  465. SurfaceCompression::Converted, // ASTC_2D_8X5
  466. SurfaceCompression::Converted, // ASTC_2D_5X4
  467. SurfaceCompression::None, // BGRA8_SRGB
  468. SurfaceCompression::Compressed, // DXT1_SRGB
  469. SurfaceCompression::Compressed, // DXT23_SRGB
  470. SurfaceCompression::Compressed, // DXT45_SRGB
  471. SurfaceCompression::Compressed, // BC7U_SRGB
  472. SurfaceCompression::Converted, // ASTC_2D_4X4_SRGB
  473. SurfaceCompression::Converted, // ASTC_2D_8X8_SRGB
  474. SurfaceCompression::Converted, // ASTC_2D_8X5_SRGB
  475. SurfaceCompression::Converted, // ASTC_2D_5X4_SRGB
  476. SurfaceCompression::Converted, // ASTC_2D_5X5
  477. SurfaceCompression::Converted, // ASTC_2D_5X5_SRGB
  478. SurfaceCompression::Converted, // ASTC_2D_10X8
  479. SurfaceCompression::Converted, // ASTC_2D_10X8_SRGB
  480. SurfaceCompression::None, // Z32F
  481. SurfaceCompression::None, // Z16
  482. SurfaceCompression::None, // Z24S8
  483. SurfaceCompression::Rearranged, // S8Z24
  484. SurfaceCompression::None, // Z32FS8
  485. }};
  486. static constexpr SurfaceCompression GetFormatCompressionType(PixelFormat format) {
  487. if (format == PixelFormat::Invalid)
  488. return SurfaceCompression::None;
  489. ASSERT(static_cast<std::size_t>(format) < compression_type_table.size());
  490. return compression_type_table[static_cast<std::size_t>(format)];
  491. }
  492. SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type);
  493. bool SurfaceTargetIsLayered(SurfaceTarget target);
  494. bool SurfaceTargetIsArray(SurfaceTarget target);
  495. PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format);
  496. PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format);
  497. PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
  498. Tegra::Texture::ComponentType component_type,
  499. bool is_srgb);
  500. ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type);
  501. ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format);
  502. PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format);
  503. ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format);
  504. SurfaceType GetFormatType(PixelFormat pixel_format);
  505. bool IsPixelFormatASTC(PixelFormat format);
  506. std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
  507. /// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
  508. bool IsFormatBCn(PixelFormat format);
  509. } // namespace VideoCore::Surface