regs_texturing.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include "common/assert.h"
  7. #include "common/bit_field.h"
  8. #include "common/common_funcs.h"
  9. #include "common/common_types.h"
  10. namespace Pica {
  11. struct TexturingRegs {
  12. struct TextureConfig {
  13. enum TextureType : u32 {
  14. Texture2D = 0,
  15. TextureCube = 1,
  16. Shadow2D = 2,
  17. Projection2D = 3,
  18. ShadowCube = 4,
  19. Disabled = 5,
  20. };
  21. enum WrapMode : u32 {
  22. ClampToEdge = 0,
  23. ClampToBorder = 1,
  24. Repeat = 2,
  25. MirroredRepeat = 3,
  26. };
  27. enum TextureFilter : u32 {
  28. Nearest = 0,
  29. Linear = 1,
  30. };
  31. union {
  32. u32 raw;
  33. BitField<0, 8, u32> r;
  34. BitField<8, 8, u32> g;
  35. BitField<16, 8, u32> b;
  36. BitField<24, 8, u32> a;
  37. } border_color;
  38. union {
  39. BitField<0, 16, u32> height;
  40. BitField<16, 16, u32> width;
  41. };
  42. union {
  43. BitField<1, 1, TextureFilter> mag_filter;
  44. BitField<2, 1, TextureFilter> min_filter;
  45. BitField<8, 2, WrapMode> wrap_t;
  46. BitField<12, 2, WrapMode> wrap_s;
  47. BitField<28, 2, TextureType>
  48. type; ///< @note Only valid for texture 0 according to 3DBrew.
  49. };
  50. INSERT_PADDING_WORDS(0x1);
  51. u32 address;
  52. PAddr GetPhysicalAddress() const {
  53. return address * 8;
  54. }
  55. // texture1 and texture2 store the texture format directly after the address
  56. // whereas texture0 inserts some additional flags inbetween.
  57. // Hence, we store the format separately so that all other parameters can be described
  58. // in a single structure.
  59. };
  60. enum class TextureFormat : u32 {
  61. RGBA8 = 0,
  62. RGB8 = 1,
  63. RGB5A1 = 2,
  64. RGB565 = 3,
  65. RGBA4 = 4,
  66. IA8 = 5,
  67. RG8 = 6, ///< @note Also called HILO8 in 3DBrew.
  68. I8 = 7,
  69. A8 = 8,
  70. IA4 = 9,
  71. I4 = 10,
  72. A4 = 11,
  73. ETC1 = 12, // compressed
  74. ETC1A4 = 13, // compressed
  75. };
  76. static unsigned NibblesPerPixel(TextureFormat format) {
  77. switch (format) {
  78. case TextureFormat::RGBA8:
  79. return 8;
  80. case TextureFormat::RGB8:
  81. return 6;
  82. case TextureFormat::RGB5A1:
  83. case TextureFormat::RGB565:
  84. case TextureFormat::RGBA4:
  85. case TextureFormat::IA8:
  86. case TextureFormat::RG8:
  87. return 4;
  88. case TextureFormat::I4:
  89. case TextureFormat::A4:
  90. return 1;
  91. case TextureFormat::I8:
  92. case TextureFormat::A8:
  93. case TextureFormat::IA4:
  94. default: // placeholder for yet unknown formats
  95. UNIMPLEMENTED();
  96. return 0;
  97. }
  98. }
  99. union {
  100. BitField<0, 1, u32> texture0_enable;
  101. BitField<1, 1, u32> texture1_enable;
  102. BitField<2, 1, u32> texture2_enable;
  103. BitField<8, 2, u32> texture3_coordinates; // TODO: unimplemented
  104. BitField<10, 1, u32> texture3_enable; // TODO: unimplemented
  105. BitField<13, 1, u32> texture2_use_coord1;
  106. BitField<16, 1, u32> clear_texture_cache; // TODO: unimplemented
  107. } main_config;
  108. TextureConfig texture0;
  109. INSERT_PADDING_WORDS(0x8);
  110. BitField<0, 4, TextureFormat> texture0_format;
  111. BitField<0, 1, u32> fragment_lighting_enable;
  112. INSERT_PADDING_WORDS(0x1);
  113. TextureConfig texture1;
  114. BitField<0, 4, TextureFormat> texture1_format;
  115. INSERT_PADDING_WORDS(0x2);
  116. TextureConfig texture2;
  117. BitField<0, 4, TextureFormat> texture2_format;
  118. INSERT_PADDING_WORDS(0x21);
  119. struct FullTextureConfig {
  120. const bool enabled;
  121. const TextureConfig config;
  122. const TextureFormat format;
  123. };
  124. const std::array<FullTextureConfig, 3> GetTextures() const {
  125. return {{
  126. {main_config.texture0_enable.ToBool(), texture0, texture0_format},
  127. {main_config.texture1_enable.ToBool(), texture1, texture1_format},
  128. {main_config.texture2_enable.ToBool(), texture2, texture2_format},
  129. }};
  130. }
  131. // 0xc0-0xff: Texture Combiner (akin to glTexEnv)
  132. struct TevStageConfig {
  133. enum class Source : u32 {
  134. PrimaryColor = 0x0,
  135. PrimaryFragmentColor = 0x1,
  136. SecondaryFragmentColor = 0x2,
  137. Texture0 = 0x3,
  138. Texture1 = 0x4,
  139. Texture2 = 0x5,
  140. Texture3 = 0x6,
  141. PreviousBuffer = 0xd,
  142. Constant = 0xe,
  143. Previous = 0xf,
  144. };
  145. enum class ColorModifier : u32 {
  146. SourceColor = 0x0,
  147. OneMinusSourceColor = 0x1,
  148. SourceAlpha = 0x2,
  149. OneMinusSourceAlpha = 0x3,
  150. SourceRed = 0x4,
  151. OneMinusSourceRed = 0x5,
  152. SourceGreen = 0x8,
  153. OneMinusSourceGreen = 0x9,
  154. SourceBlue = 0xc,
  155. OneMinusSourceBlue = 0xd,
  156. };
  157. enum class AlphaModifier : u32 {
  158. SourceAlpha = 0x0,
  159. OneMinusSourceAlpha = 0x1,
  160. SourceRed = 0x2,
  161. OneMinusSourceRed = 0x3,
  162. SourceGreen = 0x4,
  163. OneMinusSourceGreen = 0x5,
  164. SourceBlue = 0x6,
  165. OneMinusSourceBlue = 0x7,
  166. };
  167. enum class Operation : u32 {
  168. Replace = 0,
  169. Modulate = 1,
  170. Add = 2,
  171. AddSigned = 3,
  172. Lerp = 4,
  173. Subtract = 5,
  174. Dot3_RGB = 6,
  175. Dot3_RGBA = 7,
  176. MultiplyThenAdd = 8,
  177. AddThenMultiply = 9,
  178. };
  179. union {
  180. u32 sources_raw;
  181. BitField<0, 4, Source> color_source1;
  182. BitField<4, 4, Source> color_source2;
  183. BitField<8, 4, Source> color_source3;
  184. BitField<16, 4, Source> alpha_source1;
  185. BitField<20, 4, Source> alpha_source2;
  186. BitField<24, 4, Source> alpha_source3;
  187. };
  188. union {
  189. u32 modifiers_raw;
  190. BitField<0, 4, ColorModifier> color_modifier1;
  191. BitField<4, 4, ColorModifier> color_modifier2;
  192. BitField<8, 4, ColorModifier> color_modifier3;
  193. BitField<12, 3, AlphaModifier> alpha_modifier1;
  194. BitField<16, 3, AlphaModifier> alpha_modifier2;
  195. BitField<20, 3, AlphaModifier> alpha_modifier3;
  196. };
  197. union {
  198. u32 ops_raw;
  199. BitField<0, 4, Operation> color_op;
  200. BitField<16, 4, Operation> alpha_op;
  201. };
  202. union {
  203. u32 const_color;
  204. BitField<0, 8, u32> const_r;
  205. BitField<8, 8, u32> const_g;
  206. BitField<16, 8, u32> const_b;
  207. BitField<24, 8, u32> const_a;
  208. };
  209. union {
  210. u32 scales_raw;
  211. BitField<0, 2, u32> color_scale;
  212. BitField<16, 2, u32> alpha_scale;
  213. };
  214. inline unsigned GetColorMultiplier() const {
  215. return (color_scale < 3) ? (1 << color_scale) : 1;
  216. }
  217. inline unsigned GetAlphaMultiplier() const {
  218. return (alpha_scale < 3) ? (1 << alpha_scale) : 1;
  219. }
  220. };
  221. TevStageConfig tev_stage0;
  222. INSERT_PADDING_WORDS(0x3);
  223. TevStageConfig tev_stage1;
  224. INSERT_PADDING_WORDS(0x3);
  225. TevStageConfig tev_stage2;
  226. INSERT_PADDING_WORDS(0x3);
  227. TevStageConfig tev_stage3;
  228. INSERT_PADDING_WORDS(0x3);
  229. enum class FogMode : u32 {
  230. None = 0,
  231. Fog = 5,
  232. Gas = 7,
  233. };
  234. union {
  235. BitField<0, 3, FogMode> fog_mode;
  236. BitField<16, 1, u32> fog_flip;
  237. union {
  238. // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in
  239. // these masks are set
  240. BitField<8, 4, u32> update_mask_rgb;
  241. BitField<12, 4, u32> update_mask_a;
  242. bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const {
  243. return (stage_index < 4) && (update_mask_rgb & (1 << stage_index));
  244. }
  245. bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const {
  246. return (stage_index < 4) && (update_mask_a & (1 << stage_index));
  247. }
  248. } tev_combiner_buffer_input;
  249. };
  250. union {
  251. u32 raw;
  252. BitField<0, 8, u32> r;
  253. BitField<8, 8, u32> g;
  254. BitField<16, 8, u32> b;
  255. } fog_color;
  256. INSERT_PADDING_WORDS(0x4);
  257. BitField<0, 16, u32> fog_lut_offset;
  258. INSERT_PADDING_WORDS(0x1);
  259. u32 fog_lut_data[8];
  260. TevStageConfig tev_stage4;
  261. INSERT_PADDING_WORDS(0x3);
  262. TevStageConfig tev_stage5;
  263. union {
  264. u32 raw;
  265. BitField<0, 8, u32> r;
  266. BitField<8, 8, u32> g;
  267. BitField<16, 8, u32> b;
  268. BitField<24, 8, u32> a;
  269. } tev_combiner_buffer_color;
  270. INSERT_PADDING_WORDS(0x2);
  271. const std::array<TevStageConfig, 6> GetTevStages() const {
  272. return {{tev_stage0, tev_stage1, tev_stage2, tev_stage3, tev_stage4, tev_stage5}};
  273. };
  274. };
  275. static_assert(sizeof(TexturingRegs) == 0x80 * sizeof(u32),
  276. "TexturingRegs struct has incorrect size");
  277. } // namespace Pica