regs_texturing.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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. };
  104. TextureConfig texture0;
  105. INSERT_PADDING_WORDS(0x8);
  106. BitField<0, 4, TextureFormat> texture0_format;
  107. BitField<0, 1, u32> fragment_lighting_enable;
  108. INSERT_PADDING_WORDS(0x1);
  109. TextureConfig texture1;
  110. BitField<0, 4, TextureFormat> texture1_format;
  111. INSERT_PADDING_WORDS(0x2);
  112. TextureConfig texture2;
  113. BitField<0, 4, TextureFormat> texture2_format;
  114. INSERT_PADDING_WORDS(0x21);
  115. struct FullTextureConfig {
  116. const bool enabled;
  117. const TextureConfig config;
  118. const TextureFormat format;
  119. };
  120. const std::array<FullTextureConfig, 3> GetTextures() const {
  121. return {{
  122. {texture0_enable.ToBool(), texture0, texture0_format},
  123. {texture1_enable.ToBool(), texture1, texture1_format},
  124. {texture2_enable.ToBool(), texture2, texture2_format},
  125. }};
  126. }
  127. // 0xc0-0xff: Texture Combiner (akin to glTexEnv)
  128. struct TevStageConfig {
  129. enum class Source : u32 {
  130. PrimaryColor = 0x0,
  131. PrimaryFragmentColor = 0x1,
  132. SecondaryFragmentColor = 0x2,
  133. Texture0 = 0x3,
  134. Texture1 = 0x4,
  135. Texture2 = 0x5,
  136. Texture3 = 0x6,
  137. PreviousBuffer = 0xd,
  138. Constant = 0xe,
  139. Previous = 0xf,
  140. };
  141. enum class ColorModifier : u32 {
  142. SourceColor = 0x0,
  143. OneMinusSourceColor = 0x1,
  144. SourceAlpha = 0x2,
  145. OneMinusSourceAlpha = 0x3,
  146. SourceRed = 0x4,
  147. OneMinusSourceRed = 0x5,
  148. SourceGreen = 0x8,
  149. OneMinusSourceGreen = 0x9,
  150. SourceBlue = 0xc,
  151. OneMinusSourceBlue = 0xd,
  152. };
  153. enum class AlphaModifier : u32 {
  154. SourceAlpha = 0x0,
  155. OneMinusSourceAlpha = 0x1,
  156. SourceRed = 0x2,
  157. OneMinusSourceRed = 0x3,
  158. SourceGreen = 0x4,
  159. OneMinusSourceGreen = 0x5,
  160. SourceBlue = 0x6,
  161. OneMinusSourceBlue = 0x7,
  162. };
  163. enum class Operation : u32 {
  164. Replace = 0,
  165. Modulate = 1,
  166. Add = 2,
  167. AddSigned = 3,
  168. Lerp = 4,
  169. Subtract = 5,
  170. Dot3_RGB = 6,
  171. MultiplyThenAdd = 8,
  172. AddThenMultiply = 9,
  173. };
  174. union {
  175. u32 sources_raw;
  176. BitField<0, 4, Source> color_source1;
  177. BitField<4, 4, Source> color_source2;
  178. BitField<8, 4, Source> color_source3;
  179. BitField<16, 4, Source> alpha_source1;
  180. BitField<20, 4, Source> alpha_source2;
  181. BitField<24, 4, Source> alpha_source3;
  182. };
  183. union {
  184. u32 modifiers_raw;
  185. BitField<0, 4, ColorModifier> color_modifier1;
  186. BitField<4, 4, ColorModifier> color_modifier2;
  187. BitField<8, 4, ColorModifier> color_modifier3;
  188. BitField<12, 3, AlphaModifier> alpha_modifier1;
  189. BitField<16, 3, AlphaModifier> alpha_modifier2;
  190. BitField<20, 3, AlphaModifier> alpha_modifier3;
  191. };
  192. union {
  193. u32 ops_raw;
  194. BitField<0, 4, Operation> color_op;
  195. BitField<16, 4, Operation> alpha_op;
  196. };
  197. union {
  198. u32 const_color;
  199. BitField<0, 8, u32> const_r;
  200. BitField<8, 8, u32> const_g;
  201. BitField<16, 8, u32> const_b;
  202. BitField<24, 8, u32> const_a;
  203. };
  204. union {
  205. u32 scales_raw;
  206. BitField<0, 2, u32> color_scale;
  207. BitField<16, 2, u32> alpha_scale;
  208. };
  209. inline unsigned GetColorMultiplier() const {
  210. return (color_scale < 3) ? (1 << color_scale) : 1;
  211. }
  212. inline unsigned GetAlphaMultiplier() const {
  213. return (alpha_scale < 3) ? (1 << alpha_scale) : 1;
  214. }
  215. };
  216. TevStageConfig tev_stage0;
  217. INSERT_PADDING_WORDS(0x3);
  218. TevStageConfig tev_stage1;
  219. INSERT_PADDING_WORDS(0x3);
  220. TevStageConfig tev_stage2;
  221. INSERT_PADDING_WORDS(0x3);
  222. TevStageConfig tev_stage3;
  223. INSERT_PADDING_WORDS(0x3);
  224. enum class FogMode : u32 {
  225. None = 0,
  226. Fog = 5,
  227. Gas = 7,
  228. };
  229. union {
  230. BitField<0, 3, FogMode> fog_mode;
  231. BitField<16, 1, u32> fog_flip;
  232. union {
  233. // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in
  234. // these masks are set
  235. BitField<8, 4, u32> update_mask_rgb;
  236. BitField<12, 4, u32> update_mask_a;
  237. bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const {
  238. return (stage_index < 4) && (update_mask_rgb & (1 << stage_index));
  239. }
  240. bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const {
  241. return (stage_index < 4) && (update_mask_a & (1 << stage_index));
  242. }
  243. } tev_combiner_buffer_input;
  244. };
  245. union {
  246. u32 raw;
  247. BitField<0, 8, u32> r;
  248. BitField<8, 8, u32> g;
  249. BitField<16, 8, u32> b;
  250. } fog_color;
  251. INSERT_PADDING_WORDS(0x4);
  252. BitField<0, 16, u32> fog_lut_offset;
  253. INSERT_PADDING_WORDS(0x1);
  254. u32 fog_lut_data[8];
  255. TevStageConfig tev_stage4;
  256. INSERT_PADDING_WORDS(0x3);
  257. TevStageConfig tev_stage5;
  258. union {
  259. u32 raw;
  260. BitField<0, 8, u32> r;
  261. BitField<8, 8, u32> g;
  262. BitField<16, 8, u32> b;
  263. BitField<24, 8, u32> a;
  264. } tev_combiner_buffer_color;
  265. INSERT_PADDING_WORDS(0x2);
  266. const std::array<TevStageConfig, 6> GetTevStages() const {
  267. return {{tev_stage0, tev_stage1, tev_stage2, tev_stage3, tev_stage4, tev_stage5}};
  268. };
  269. };
  270. static_assert(sizeof(TexturingRegs) == 0x80 * sizeof(u32),
  271. "TexturingRegs struct has incorrect size");
  272. } // namespace Pica