surface.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  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. Texture2D,
  104. Texture3D,
  105. Texture1DArray,
  106. Texture2DArray,
  107. TextureCubemap,
  108. TextureCubeArray,
  109. };
  110. constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{
  111. 1, // ABGR8U
  112. 1, // ABGR8S
  113. 1, // ABGR8UI
  114. 1, // B5G6R5U
  115. 1, // A2B10G10R10U
  116. 1, // A1B5G5R5U
  117. 1, // R8U
  118. 1, // R8UI
  119. 1, // RGBA16F
  120. 1, // RGBA16U
  121. 1, // RGBA16UI
  122. 1, // R11FG11FB10F
  123. 1, // RGBA32UI
  124. 4, // DXT1
  125. 4, // DXT23
  126. 4, // DXT45
  127. 4, // DXN1
  128. 4, // DXN2UNORM
  129. 4, // DXN2SNORM
  130. 4, // BC7U
  131. 4, // BC6H_UF16
  132. 4, // BC6H_SF16
  133. 4, // ASTC_2D_4X4
  134. 1, // BGRA8
  135. 1, // RGBA32F
  136. 1, // RG32F
  137. 1, // R32F
  138. 1, // R16F
  139. 1, // R16U
  140. 1, // R16S
  141. 1, // R16UI
  142. 1, // R16I
  143. 1, // RG16
  144. 1, // RG16F
  145. 1, // RG16UI
  146. 1, // RG16I
  147. 1, // RG16S
  148. 1, // RGB32F
  149. 1, // RGBA8_SRGB
  150. 1, // RG8U
  151. 1, // RG8S
  152. 1, // RG32UI
  153. 1, // R32UI
  154. 4, // ASTC_2D_8X8
  155. 4, // ASTC_2D_8X5
  156. 4, // ASTC_2D_5X4
  157. 1, // BGRA8_SRGB
  158. 4, // DXT1_SRGB
  159. 4, // DXT23_SRGB
  160. 4, // DXT45_SRGB
  161. 4, // BC7U_SRGB
  162. 4, // ASTC_2D_4X4_SRGB
  163. 4, // ASTC_2D_8X8_SRGB
  164. 4, // ASTC_2D_8X5_SRGB
  165. 4, // ASTC_2D_5X4_SRGB
  166. 4, // ASTC_2D_5X5
  167. 4, // ASTC_2D_5X5_SRGB
  168. 4, // ASTC_2D_10X8
  169. 4, // ASTC_2D_10X8_SRGB
  170. 1, // Z32F
  171. 1, // Z16
  172. 1, // Z24S8
  173. 1, // S8Z24
  174. 1, // Z32FS8
  175. }};
  176. /**
  177. * Gets the compression factor for the specified PixelFormat. This applies to just the
  178. * "compressed width" and "compressed height", not the overall compression factor of a
  179. * compressed image. This is used for maintaining proper surface sizes for compressed
  180. * texture formats.
  181. */
  182. static constexpr u32 GetCompressionFactor(PixelFormat format) {
  183. if (format == PixelFormat::Invalid)
  184. return 0;
  185. ASSERT(static_cast<std::size_t>(format) < compression_factor_table.size());
  186. return compression_factor_table[static_cast<std::size_t>(format)];
  187. }
  188. constexpr std::array<u32, MaxPixelFormat> block_width_table = {{
  189. 1, // ABGR8U
  190. 1, // ABGR8S
  191. 1, // ABGR8UI
  192. 1, // B5G6R5U
  193. 1, // A2B10G10R10U
  194. 1, // A1B5G5R5U
  195. 1, // R8U
  196. 1, // R8UI
  197. 1, // RGBA16F
  198. 1, // RGBA16U
  199. 1, // RGBA16UI
  200. 1, // R11FG11FB10F
  201. 1, // RGBA32UI
  202. 4, // DXT1
  203. 4, // DXT23
  204. 4, // DXT45
  205. 4, // DXN1
  206. 4, // DXN2UNORM
  207. 4, // DXN2SNORM
  208. 4, // BC7U
  209. 4, // BC6H_UF16
  210. 4, // BC6H_SF16
  211. 4, // ASTC_2D_4X4
  212. 1, // BGRA8
  213. 1, // RGBA32F
  214. 1, // RG32F
  215. 1, // R32F
  216. 1, // R16F
  217. 1, // R16U
  218. 1, // R16S
  219. 1, // R16UI
  220. 1, // R16I
  221. 1, // RG16
  222. 1, // RG16F
  223. 1, // RG16UI
  224. 1, // RG16I
  225. 1, // RG16S
  226. 1, // RGB32F
  227. 1, // RGBA8_SRGB
  228. 1, // RG8U
  229. 1, // RG8S
  230. 1, // RG32UI
  231. 1, // R32UI
  232. 8, // ASTC_2D_8X8
  233. 8, // ASTC_2D_8X5
  234. 5, // ASTC_2D_5X4
  235. 1, // BGRA8_SRGB
  236. 4, // DXT1_SRGB
  237. 4, // DXT23_SRGB
  238. 4, // DXT45_SRGB
  239. 4, // BC7U_SRGB
  240. 4, // ASTC_2D_4X4_SRGB
  241. 8, // ASTC_2D_8X8_SRGB
  242. 8, // ASTC_2D_8X5_SRGB
  243. 5, // ASTC_2D_5X4_SRGB
  244. 5, // ASTC_2D_5X5
  245. 5, // ASTC_2D_5X5_SRGB
  246. 10, // ASTC_2D_10X8
  247. 10, // ASTC_2D_10X8_SRGB
  248. 1, // Z32F
  249. 1, // Z16
  250. 1, // Z24S8
  251. 1, // S8Z24
  252. 1, // Z32FS8
  253. }};
  254. static constexpr u32 GetDefaultBlockWidth(PixelFormat format) {
  255. if (format == PixelFormat::Invalid)
  256. return 0;
  257. ASSERT(static_cast<std::size_t>(format) < block_width_table.size());
  258. return block_width_table[static_cast<std::size_t>(format)];
  259. }
  260. constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
  261. 1, // ABGR8U
  262. 1, // ABGR8S
  263. 1, // ABGR8UI
  264. 1, // B5G6R5U
  265. 1, // A2B10G10R10U
  266. 1, // A1B5G5R5U
  267. 1, // R8U
  268. 1, // R8UI
  269. 1, // RGBA16F
  270. 1, // RGBA16U
  271. 1, // RGBA16UI
  272. 1, // R11FG11FB10F
  273. 1, // RGBA32UI
  274. 4, // DXT1
  275. 4, // DXT23
  276. 4, // DXT45
  277. 4, // DXN1
  278. 4, // DXN2UNORM
  279. 4, // DXN2SNORM
  280. 4, // BC7U
  281. 4, // BC6H_UF16
  282. 4, // BC6H_SF16
  283. 4, // ASTC_2D_4X4
  284. 1, // BGRA8
  285. 1, // RGBA32F
  286. 1, // RG32F
  287. 1, // R32F
  288. 1, // R16F
  289. 1, // R16U
  290. 1, // R16S
  291. 1, // R16UI
  292. 1, // R16I
  293. 1, // RG16
  294. 1, // RG16F
  295. 1, // RG16UI
  296. 1, // RG16I
  297. 1, // RG16S
  298. 1, // RGB32F
  299. 1, // RGBA8_SRGB
  300. 1, // RG8U
  301. 1, // RG8S
  302. 1, // RG32UI
  303. 1, // R32UI
  304. 8, // ASTC_2D_8X8
  305. 5, // ASTC_2D_8X5
  306. 4, // ASTC_2D_5X4
  307. 1, // BGRA8_SRGB
  308. 4, // DXT1_SRGB
  309. 4, // DXT23_SRGB
  310. 4, // DXT45_SRGB
  311. 4, // BC7U_SRGB
  312. 4, // ASTC_2D_4X4_SRGB
  313. 8, // ASTC_2D_8X8_SRGB
  314. 5, // ASTC_2D_8X5_SRGB
  315. 4, // ASTC_2D_5X4_SRGB
  316. 5, // ASTC_2D_5X5
  317. 5, // ASTC_2D_5X5_SRGB
  318. 8, // ASTC_2D_10X8
  319. 8, // ASTC_2D_10X8_SRGB
  320. 1, // Z32F
  321. 1, // Z16
  322. 1, // Z24S8
  323. 1, // S8Z24
  324. 1, // Z32FS8
  325. }};
  326. static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
  327. if (format == PixelFormat::Invalid)
  328. return 0;
  329. ASSERT(static_cast<std::size_t>(format) < block_height_table.size());
  330. return block_height_table[static_cast<std::size_t>(format)];
  331. }
  332. constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
  333. 32, // ABGR8U
  334. 32, // ABGR8S
  335. 32, // ABGR8UI
  336. 16, // B5G6R5U
  337. 32, // A2B10G10R10U
  338. 16, // A1B5G5R5U
  339. 8, // R8U
  340. 8, // R8UI
  341. 64, // RGBA16F
  342. 64, // RGBA16U
  343. 64, // RGBA16UI
  344. 32, // R11FG11FB10F
  345. 128, // RGBA32UI
  346. 64, // DXT1
  347. 128, // DXT23
  348. 128, // DXT45
  349. 64, // DXN1
  350. 128, // DXN2UNORM
  351. 128, // DXN2SNORM
  352. 128, // BC7U
  353. 128, // BC6H_UF16
  354. 128, // BC6H_SF16
  355. 128, // ASTC_2D_4X4
  356. 32, // BGRA8
  357. 128, // RGBA32F
  358. 64, // RG32F
  359. 32, // R32F
  360. 16, // R16F
  361. 16, // R16U
  362. 16, // R16S
  363. 16, // R16UI
  364. 16, // R16I
  365. 32, // RG16
  366. 32, // RG16F
  367. 32, // RG16UI
  368. 32, // RG16I
  369. 32, // RG16S
  370. 96, // RGB32F
  371. 32, // RGBA8_SRGB
  372. 16, // RG8U
  373. 16, // RG8S
  374. 64, // RG32UI
  375. 32, // R32UI
  376. 128, // ASTC_2D_8X8
  377. 128, // ASTC_2D_8X5
  378. 128, // ASTC_2D_5X4
  379. 32, // BGRA8_SRGB
  380. 64, // DXT1_SRGB
  381. 128, // DXT23_SRGB
  382. 128, // DXT45_SRGB
  383. 128, // BC7U
  384. 128, // ASTC_2D_4X4_SRGB
  385. 128, // ASTC_2D_8X8_SRGB
  386. 128, // ASTC_2D_8X5_SRGB
  387. 128, // ASTC_2D_5X4_SRGB
  388. 128, // ASTC_2D_5X5
  389. 128, // ASTC_2D_5X5_SRGB
  390. 128, // ASTC_2D_10X8
  391. 128, // ASTC_2D_10X8_SRGB
  392. 32, // Z32F
  393. 16, // Z16
  394. 32, // Z24S8
  395. 32, // S8Z24
  396. 64, // Z32FS8
  397. }};
  398. static constexpr u32 GetFormatBpp(PixelFormat format) {
  399. if (format == PixelFormat::Invalid)
  400. return 0;
  401. ASSERT(static_cast<std::size_t>(format) < bpp_table.size());
  402. return bpp_table[static_cast<std::size_t>(format)];
  403. }
  404. /// Returns the sizer in bytes of the specified pixel format
  405. static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) {
  406. if (pixel_format == PixelFormat::Invalid) {
  407. return 0;
  408. }
  409. return GetFormatBpp(pixel_format) / CHAR_BIT;
  410. }
  411. SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type);
  412. bool SurfaceTargetIsLayered(SurfaceTarget target);
  413. bool SurfaceTargetIsArray(SurfaceTarget target);
  414. PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format);
  415. PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format);
  416. PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
  417. Tegra::Texture::ComponentType component_type,
  418. bool is_srgb);
  419. ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type);
  420. ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format);
  421. PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format);
  422. ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format);
  423. SurfaceType GetFormatType(PixelFormat pixel_format);
  424. bool IsPixelFormatASTC(PixelFormat format);
  425. std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
  426. /// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
  427. bool IsFormatBCn(PixelFormat format);
  428. } // namespace VideoCore::Surface