regs_framebuffer.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. #include "common/logging/log.h"
  11. namespace Pica {
  12. struct FramebufferRegs {
  13. enum class LogicOp : u32 {
  14. Clear = 0,
  15. And = 1,
  16. AndReverse = 2,
  17. Copy = 3,
  18. Set = 4,
  19. CopyInverted = 5,
  20. NoOp = 6,
  21. Invert = 7,
  22. Nand = 8,
  23. Or = 9,
  24. Nor = 10,
  25. Xor = 11,
  26. Equiv = 12,
  27. AndInverted = 13,
  28. OrReverse = 14,
  29. OrInverted = 15,
  30. };
  31. enum class BlendEquation : u32 {
  32. Add = 0,
  33. Subtract = 1,
  34. ReverseSubtract = 2,
  35. Min = 3,
  36. Max = 4,
  37. };
  38. enum class BlendFactor : u32 {
  39. Zero = 0,
  40. One = 1,
  41. SourceColor = 2,
  42. OneMinusSourceColor = 3,
  43. DestColor = 4,
  44. OneMinusDestColor = 5,
  45. SourceAlpha = 6,
  46. OneMinusSourceAlpha = 7,
  47. DestAlpha = 8,
  48. OneMinusDestAlpha = 9,
  49. ConstantColor = 10,
  50. OneMinusConstantColor = 11,
  51. ConstantAlpha = 12,
  52. OneMinusConstantAlpha = 13,
  53. SourceAlphaSaturate = 14,
  54. };
  55. enum class CompareFunc : u32 {
  56. Never = 0,
  57. Always = 1,
  58. Equal = 2,
  59. NotEqual = 3,
  60. LessThan = 4,
  61. LessThanOrEqual = 5,
  62. GreaterThan = 6,
  63. GreaterThanOrEqual = 7,
  64. };
  65. enum class StencilAction : u32 {
  66. Keep = 0,
  67. Zero = 1,
  68. Replace = 2,
  69. Increment = 3,
  70. Decrement = 4,
  71. Invert = 5,
  72. IncrementWrap = 6,
  73. DecrementWrap = 7,
  74. };
  75. struct {
  76. union {
  77. // If false, logic blending is used
  78. BitField<8, 1, u32> alphablend_enable;
  79. };
  80. union {
  81. BitField<0, 3, BlendEquation> blend_equation_rgb;
  82. BitField<8, 3, BlendEquation> blend_equation_a;
  83. BitField<16, 4, BlendFactor> factor_source_rgb;
  84. BitField<20, 4, BlendFactor> factor_dest_rgb;
  85. BitField<24, 4, BlendFactor> factor_source_a;
  86. BitField<28, 4, BlendFactor> factor_dest_a;
  87. } alpha_blending;
  88. union {
  89. BitField<0, 4, LogicOp> logic_op;
  90. };
  91. union {
  92. u32 raw;
  93. BitField<0, 8, u32> r;
  94. BitField<8, 8, u32> g;
  95. BitField<16, 8, u32> b;
  96. BitField<24, 8, u32> a;
  97. } blend_const;
  98. union {
  99. BitField<0, 1, u32> enable;
  100. BitField<4, 3, CompareFunc> func;
  101. BitField<8, 8, u32> ref;
  102. } alpha_test;
  103. struct {
  104. union {
  105. // Raw value of this register
  106. u32 raw_func;
  107. // If true, enable stencil testing
  108. BitField<0, 1, u32> enable;
  109. // Comparison operation for stencil testing
  110. BitField<4, 3, CompareFunc> func;
  111. // Mask used to control writing to the stencil buffer
  112. BitField<8, 8, u32> write_mask;
  113. // Value to compare against for stencil testing
  114. BitField<16, 8, u32> reference_value;
  115. // Mask to apply on stencil test inputs
  116. BitField<24, 8, u32> input_mask;
  117. };
  118. union {
  119. // Raw value of this register
  120. u32 raw_op;
  121. // Action to perform when the stencil test fails
  122. BitField<0, 3, StencilAction> action_stencil_fail;
  123. // Action to perform when stencil testing passed but depth testing fails
  124. BitField<4, 3, StencilAction> action_depth_fail;
  125. // Action to perform when both stencil and depth testing pass
  126. BitField<8, 3, StencilAction> action_depth_pass;
  127. };
  128. } stencil_test;
  129. union {
  130. BitField<0, 1, u32> depth_test_enable;
  131. BitField<4, 3, CompareFunc> depth_test_func;
  132. BitField<8, 1, u32> red_enable;
  133. BitField<9, 1, u32> green_enable;
  134. BitField<10, 1, u32> blue_enable;
  135. BitField<11, 1, u32> alpha_enable;
  136. BitField<12, 1, u32> depth_write_enable;
  137. };
  138. INSERT_PADDING_WORDS(0x8);
  139. } output_merger;
  140. // Components are laid out in reverse byte order, most significant bits first.
  141. enum class ColorFormat : u32 {
  142. RGBA8 = 0,
  143. RGB8 = 1,
  144. RGB5A1 = 2,
  145. RGB565 = 3,
  146. RGBA4 = 4,
  147. };
  148. enum class DepthFormat : u32 {
  149. D16 = 0,
  150. D24 = 2,
  151. D24S8 = 3,
  152. };
  153. // Returns the number of bytes in the specified color format
  154. static unsigned BytesPerColorPixel(ColorFormat format) {
  155. switch (format) {
  156. case ColorFormat::RGBA8:
  157. return 4;
  158. case ColorFormat::RGB8:
  159. return 3;
  160. case ColorFormat::RGB5A1:
  161. case ColorFormat::RGB565:
  162. case ColorFormat::RGBA4:
  163. return 2;
  164. default:
  165. LOG_CRITICAL(HW_GPU, "Unknown color format %u", format);
  166. UNIMPLEMENTED();
  167. }
  168. }
  169. struct FramebufferConfig {
  170. INSERT_PADDING_WORDS(0x3);
  171. union {
  172. BitField<0, 4, u32> allow_color_write; // 0 = disable, else enable
  173. };
  174. INSERT_PADDING_WORDS(0x1);
  175. union {
  176. BitField<0, 2, u32> allow_depth_stencil_write; // 0 = disable, else enable
  177. };
  178. BitField<0, 2, DepthFormat> depth_format;
  179. BitField<16, 3, ColorFormat> color_format;
  180. INSERT_PADDING_WORDS(0x4);
  181. BitField<0, 28, u32> depth_buffer_address;
  182. BitField<0, 28, u32> color_buffer_address;
  183. union {
  184. // Apparently, the framebuffer width is stored as expected,
  185. // while the height is stored as the actual height minus one.
  186. // Hence, don't access these fields directly but use the accessors
  187. // GetWidth() and GetHeight() instead.
  188. BitField<0, 11, u32> width;
  189. BitField<12, 10, u32> height;
  190. };
  191. INSERT_PADDING_WORDS(0x1);
  192. inline PAddr GetColorBufferPhysicalAddress() const {
  193. return color_buffer_address * 8;
  194. }
  195. inline PAddr GetDepthBufferPhysicalAddress() const {
  196. return depth_buffer_address * 8;
  197. }
  198. inline u32 GetWidth() const {
  199. return width;
  200. }
  201. inline u32 GetHeight() const {
  202. return height + 1;
  203. }
  204. } framebuffer;
  205. // Returns the number of bytes in the specified depth format
  206. static u32 BytesPerDepthPixel(DepthFormat format) {
  207. switch (format) {
  208. case DepthFormat::D16:
  209. return 2;
  210. case DepthFormat::D24:
  211. return 3;
  212. case DepthFormat::D24S8:
  213. return 4;
  214. default:
  215. LOG_CRITICAL(HW_GPU, "Unknown depth format %u", format);
  216. UNIMPLEMENTED();
  217. }
  218. }
  219. // Returns the number of bits per depth component of the specified depth format
  220. static u32 DepthBitsPerPixel(DepthFormat format) {
  221. switch (format) {
  222. case DepthFormat::D16:
  223. return 16;
  224. case DepthFormat::D24:
  225. case DepthFormat::D24S8:
  226. return 24;
  227. default:
  228. LOG_CRITICAL(HW_GPU, "Unknown depth format %u", format);
  229. UNIMPLEMENTED();
  230. }
  231. }
  232. INSERT_PADDING_WORDS(0x20);
  233. };
  234. static_assert(sizeof(FramebufferRegs) == 0x40 * sizeof(u32),
  235. "FramebufferRegs struct has incorrect size");
  236. } // namespace Pica