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