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