texture.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include "common/assert.h"
  6. #include "common/bit_field.h"
  7. #include "common/common_types.h"
  8. namespace Tegra::Texture {
  9. enum class TextureFormat : u32 {
  10. R32G32B32A32 = 0x01,
  11. R32G32B32 = 0x02,
  12. R16G16B16A16 = 0x03,
  13. R32G32 = 0x04,
  14. R32_B24G8 = 0x05,
  15. ETC2_RGB = 0x06,
  16. X8B8G8R8 = 0x07,
  17. A8R8G8B8 = 0x08,
  18. A2B10G10R10 = 0x09,
  19. ETC2_RGB_PTA = 0x0a,
  20. ETC2_RGBA = 0x0b,
  21. R16G16 = 0x0c,
  22. R24G8 = 0x0d,
  23. R8G24 = 0x0e,
  24. R32 = 0x0f,
  25. BC6H_SFLOAT = 0x10,
  26. BC6H_UFLOAT = 0x11,
  27. A4B4G4R4 = 0x12,
  28. A5B5G5R1 = 0x13,
  29. A1B5G5R5 = 0x14,
  30. B5G6R5 = 0x15,
  31. B6G5R5 = 0x16,
  32. BC7 = 0x17,
  33. R8G8 = 0x18,
  34. EAC = 0x19,
  35. EACX2 = 0x1a,
  36. R16 = 0x1b,
  37. Y8_VIDEO = 0x1c,
  38. R8 = 0x1d,
  39. G4R4 = 0x1e,
  40. R1 = 0x1f,
  41. E5B9G9R9 = 0x20,
  42. B10G11R11 = 0x21,
  43. G8B8G8R8 = 0x22,
  44. B8G8R8G8 = 0x23,
  45. BC1_RGBA = 0x24,
  46. BC2 = 0x25,
  47. BC3 = 0x26,
  48. BC4 = 0x27,
  49. BC5 = 0x28,
  50. S8D24 = 0x29,
  51. X8D24 = 0x2a,
  52. D24S8 = 0x2b,
  53. X4V4D24__COV4R4V = 0x2c,
  54. X4V4D24__COV8R8V = 0x2d,
  55. V8D24__COV4R12V = 0x2e,
  56. D32 = 0x2f,
  57. D32S8 = 0x30,
  58. X8D24_X20V4S8__COV4R4V = 0x31,
  59. X8D24_X20V4S8__COV8R8V = 0x32,
  60. D32_X20V4X8__COV4R4V = 0x33,
  61. D32_X20V4X8__COV8R8V = 0x34,
  62. D32_X20V4S8__COV4R4V = 0x35,
  63. D32_X20V4S8__COV8R8V = 0x36,
  64. X8D24_X16V8S8__COV4R12V = 0x37,
  65. D32_X16V8X8__COV4R12V = 0x38,
  66. D32_X16V8S8__COV4R12V = 0x39,
  67. D16 = 0x3a,
  68. V8D24__COV8R24V = 0x3b,
  69. X8D24_X16V8S8__COV8R24V = 0x3c,
  70. D32_X16V8X8__COV8R24V = 0x3d,
  71. D32_X16V8S8__COV8R24V = 0x3e,
  72. ASTC_2D_4X4 = 0x40,
  73. ASTC_2D_5X5 = 0x41,
  74. ASTC_2D_6X6 = 0x42,
  75. ASTC_2D_8X8 = 0x44,
  76. ASTC_2D_10X10 = 0x45,
  77. ASTC_2D_12X12 = 0x46,
  78. ASTC_2D_5X4 = 0x50,
  79. ASTC_2D_6X5 = 0x51,
  80. ASTC_2D_8X6 = 0x52,
  81. ASTC_2D_10X8 = 0x53,
  82. ASTC_2D_12X10 = 0x54,
  83. ASTC_2D_8X5 = 0x55,
  84. ASTC_2D_10X5 = 0x56,
  85. ASTC_2D_10X6 = 0x57,
  86. };
  87. enum class TextureType : u32 {
  88. Texture1D = 0,
  89. Texture2D = 1,
  90. Texture3D = 2,
  91. TextureCubemap = 3,
  92. Texture1DArray = 4,
  93. Texture2DArray = 5,
  94. Texture1DBuffer = 6,
  95. Texture2DNoMipmap = 7,
  96. TextureCubeArray = 8,
  97. };
  98. enum class TICHeaderVersion : u32 {
  99. OneDBuffer = 0,
  100. PitchColorKey = 1,
  101. Pitch = 2,
  102. BlockLinear = 3,
  103. BlockLinearColorKey = 4,
  104. };
  105. enum class ComponentType : u32 {
  106. SNORM = 1,
  107. UNORM = 2,
  108. SINT = 3,
  109. UINT = 4,
  110. SNORM_FORCE_FP16 = 5,
  111. UNORM_FORCE_FP16 = 6,
  112. FLOAT = 7
  113. };
  114. enum class SwizzleSource : u32 {
  115. Zero = 0,
  116. R = 2,
  117. G = 3,
  118. B = 4,
  119. A = 5,
  120. OneInt = 6,
  121. OneFloat = 7,
  122. };
  123. enum class MsaaMode : u32 {
  124. Msaa1x1 = 0,
  125. Msaa2x1 = 1,
  126. Msaa2x2 = 2,
  127. Msaa4x2 = 3,
  128. Msaa4x2_D3D = 4,
  129. Msaa2x1_D3D = 5,
  130. Msaa4x4 = 6,
  131. Msaa2x2_VC4 = 8,
  132. Msaa2x2_VC12 = 9,
  133. Msaa4x2_VC8 = 10,
  134. Msaa4x2_VC24 = 11,
  135. };
  136. union TextureHandle {
  137. /* implicit */ constexpr TextureHandle(u32 raw_) : raw{raw_} {}
  138. u32 raw;
  139. BitField<0, 20, u32> tic_id;
  140. BitField<20, 12, u32> tsc_id;
  141. };
  142. static_assert(sizeof(TextureHandle) == 4, "TextureHandle has wrong size");
  143. [[nodiscard]] inline std::pair<u32, u32> TexturePair(u32 raw, bool via_header_index) {
  144. if (via_header_index) {
  145. return {raw, raw};
  146. } else {
  147. const Tegra::Texture::TextureHandle handle{raw};
  148. return {handle.tic_id, handle.tsc_id};
  149. }
  150. }
  151. struct TICEntry {
  152. union {
  153. struct {
  154. union {
  155. BitField<0, 7, TextureFormat> format;
  156. BitField<7, 3, ComponentType> r_type;
  157. BitField<10, 3, ComponentType> g_type;
  158. BitField<13, 3, ComponentType> b_type;
  159. BitField<16, 3, ComponentType> a_type;
  160. BitField<19, 3, SwizzleSource> x_source;
  161. BitField<22, 3, SwizzleSource> y_source;
  162. BitField<25, 3, SwizzleSource> z_source;
  163. BitField<28, 3, SwizzleSource> w_source;
  164. };
  165. u32 address_low;
  166. union {
  167. BitField<0, 16, u32> address_high;
  168. BitField<16, 5, u32> layer_base_3_7;
  169. BitField<21, 3, TICHeaderVersion> header_version;
  170. BitField<24, 1, u32> load_store_hint;
  171. BitField<25, 4, u32> view_coherency_hash;
  172. BitField<29, 3, u32> layer_base_8_10;
  173. };
  174. union {
  175. BitField<0, 3, u32> block_width;
  176. BitField<3, 3, u32> block_height;
  177. BitField<6, 3, u32> block_depth;
  178. BitField<10, 3, u32> tile_width_spacing;
  179. // High 16 bits of the pitch value
  180. BitField<0, 16, u32> pitch_high;
  181. BitField<26, 1, u32> use_header_opt_control;
  182. BitField<27, 1, u32> depth_texture;
  183. BitField<28, 4, u32> max_mip_level;
  184. BitField<0, 16, u32> buffer_high_width_minus_one;
  185. };
  186. union {
  187. BitField<0, 16, u32> width_minus_one;
  188. BitField<16, 3, u32> layer_base_0_2;
  189. BitField<22, 1, u32> srgb_conversion;
  190. BitField<23, 4, TextureType> texture_type;
  191. BitField<29, 3, u32> border_size;
  192. BitField<0, 16, u32> buffer_low_width_minus_one;
  193. };
  194. union {
  195. BitField<0, 16, u32> height_minus_1;
  196. BitField<16, 14, u32> depth_minus_1;
  197. BitField<30, 1, u32> is_sparse;
  198. BitField<31, 1, u32> normalized_coords;
  199. };
  200. union {
  201. BitField<6, 13, u32> mip_lod_bias;
  202. BitField<27, 3, u32> max_anisotropy;
  203. };
  204. union {
  205. BitField<0, 4, u32> res_min_mip_level;
  206. BitField<4, 4, u32> res_max_mip_level;
  207. BitField<8, 4, MsaaMode> msaa_mode;
  208. BitField<12, 12, u32> min_lod_clamp;
  209. };
  210. };
  211. std::array<u64, 4> raw;
  212. };
  213. constexpr bool operator==(const TICEntry& rhs) const noexcept {
  214. return raw == rhs.raw;
  215. }
  216. constexpr bool operator!=(const TICEntry& rhs) const noexcept {
  217. return raw != rhs.raw;
  218. }
  219. constexpr GPUVAddr Address() const {
  220. return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low);
  221. }
  222. constexpr u32 Pitch() const {
  223. ASSERT(header_version == TICHeaderVersion::Pitch ||
  224. header_version == TICHeaderVersion::PitchColorKey);
  225. // The pitch value is 21 bits, and is 32B aligned.
  226. return pitch_high << 5;
  227. }
  228. constexpr u32 Width() const {
  229. if (header_version != TICHeaderVersion::OneDBuffer) {
  230. return width_minus_one + 1;
  231. }
  232. return (buffer_high_width_minus_one << 16 | buffer_low_width_minus_one) + 1;
  233. }
  234. constexpr u32 Height() const {
  235. return height_minus_1 + 1;
  236. }
  237. constexpr u32 Depth() const {
  238. return depth_minus_1 + 1;
  239. }
  240. constexpr u32 BaseLayer() const {
  241. return layer_base_0_2 | layer_base_3_7 << 3 | layer_base_8_10 << 8;
  242. }
  243. constexpr bool IsBlockLinear() const {
  244. return header_version == TICHeaderVersion::BlockLinear ||
  245. header_version == TICHeaderVersion::BlockLinearColorKey;
  246. }
  247. constexpr bool IsPitchLinear() const {
  248. return header_version == TICHeaderVersion::Pitch ||
  249. header_version == TICHeaderVersion::PitchColorKey;
  250. }
  251. constexpr bool IsBuffer() const {
  252. return header_version == TICHeaderVersion::OneDBuffer;
  253. }
  254. };
  255. static_assert(sizeof(TICEntry) == 0x20, "TICEntry has wrong size");
  256. enum class WrapMode : u32 {
  257. Wrap = 0,
  258. Mirror = 1,
  259. ClampToEdge = 2,
  260. Border = 3,
  261. Clamp = 4,
  262. MirrorOnceClampToEdge = 5,
  263. MirrorOnceBorder = 6,
  264. MirrorOnceClampOGL = 7,
  265. };
  266. enum class DepthCompareFunc : u32 {
  267. Never = 0,
  268. Less = 1,
  269. Equal = 2,
  270. LessEqual = 3,
  271. Greater = 4,
  272. NotEqual = 5,
  273. GreaterEqual = 6,
  274. Always = 7,
  275. };
  276. enum class TextureFilter : u32 {
  277. Nearest = 1,
  278. Linear = 2,
  279. };
  280. enum class TextureMipmapFilter : u32 {
  281. None = 1,
  282. Nearest = 2,
  283. Linear = 3,
  284. };
  285. enum class SamplerReduction : u32 {
  286. WeightedAverage = 0,
  287. Min = 1,
  288. Max = 2,
  289. };
  290. enum class Anisotropy {
  291. Default,
  292. Filter2x,
  293. Filter4x,
  294. Filter8x,
  295. Filter16x,
  296. };
  297. struct TSCEntry {
  298. union {
  299. struct {
  300. union {
  301. BitField<0, 3, WrapMode> wrap_u;
  302. BitField<3, 3, WrapMode> wrap_v;
  303. BitField<6, 3, WrapMode> wrap_p;
  304. BitField<9, 1, u32> depth_compare_enabled;
  305. BitField<10, 3, DepthCompareFunc> depth_compare_func;
  306. BitField<13, 1, u32> srgb_conversion;
  307. BitField<20, 3, u32> max_anisotropy;
  308. };
  309. union {
  310. BitField<0, 2, TextureFilter> mag_filter;
  311. BitField<4, 2, TextureFilter> min_filter;
  312. BitField<6, 2, TextureMipmapFilter> mipmap_filter;
  313. BitField<8, 1, u32> cubemap_anisotropy;
  314. BitField<9, 1, u32> cubemap_interface_filtering;
  315. BitField<10, 2, SamplerReduction> reduction_filter;
  316. BitField<12, 13, u32> mip_lod_bias;
  317. BitField<25, 1, u32> float_coord_normalization;
  318. BitField<26, 5, u32> trilin_opt;
  319. };
  320. union {
  321. BitField<0, 12, u32> min_lod_clamp;
  322. BitField<12, 12, u32> max_lod_clamp;
  323. BitField<24, 8, u32> srgb_border_color_r;
  324. };
  325. union {
  326. BitField<12, 8, u32> srgb_border_color_g;
  327. BitField<20, 8, u32> srgb_border_color_b;
  328. };
  329. std::array<f32, 4> border_color;
  330. };
  331. std::array<u64, 4> raw;
  332. };
  333. constexpr bool operator==(const TSCEntry& rhs) const noexcept {
  334. return raw == rhs.raw;
  335. }
  336. constexpr bool operator!=(const TSCEntry& rhs) const noexcept {
  337. return raw != rhs.raw;
  338. }
  339. std::array<float, 4> BorderColor() const noexcept;
  340. float MaxAnisotropy() const noexcept;
  341. float MinLod() const {
  342. return static_cast<float>(min_lod_clamp) / 256.0f;
  343. }
  344. float MaxLod() const {
  345. return static_cast<float>(max_lod_clamp) / 256.0f;
  346. }
  347. float LodBias() const {
  348. // Sign extend the 13-bit value.
  349. static constexpr u32 mask = 1U << (13 - 1);
  350. return static_cast<float>(static_cast<s32>((mip_lod_bias ^ mask) - mask)) / 256.0f;
  351. }
  352. };
  353. static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size");
  354. } // namespace Tegra::Texture
  355. template <>
  356. struct std::hash<Tegra::Texture::TICEntry> {
  357. size_t operator()(const Tegra::Texture::TICEntry& tic) const noexcept;
  358. };
  359. template <>
  360. struct std::hash<Tegra::Texture::TSCEntry> {
  361. size_t operator()(const Tegra::Texture::TSCEntry& tsc) const noexcept;
  362. };