1 /* Copyright (c) 2020 Themaister
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining
4 * a copy of this software and associated documentation files (the
5 * "Software"), to deal in the Software without restriction, including
6 * without limitation the rights to use, copy, modify, merge, publish,
7 * distribute, sublicense, and/or sell copies of the Software, and to
8 * permit persons to whom the Software is furnished to do so, subject to
9 * the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be
12 * included in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 #pragma once
24
25 namespace Vulkan
26 {
27 class Program;
28 class Shader;
29 }
30
31 namespace RDP
32 {
33 template <typename Program, typename Shader> struct Shaders;
34 using ShaderBank = Shaders<Vulkan::Program *, Vulkan::Shader *>;
35
36 // list of command IDs
37 enum class Op
38 {
39 Nop = 0,
40
41 MetaSignalTimeline = 1,
42 MetaFlush = 2,
43 MetaIdle = 3,
44 MetaSetQuirks = 4,
45
46 FillTriangle = 0x08,
47 FillZBufferTriangle = 0x09,
48 TextureTriangle = 0x0a,
49 TextureZBufferTriangle = 0x0b,
50 ShadeTriangle = 0x0c,
51 ShadeZBufferTriangle = 0x0d,
52 ShadeTextureTriangle = 0x0e,
53 ShadeTextureZBufferTriangle = 0x0f,
54 TextureRectangle = 0x24,
55 TextureRectangleFlip = 0x25,
56 SyncLoad = 0x26,
57 SyncPipe = 0x27,
58 SyncTile = 0x28,
59 SyncFull = 0x29,
60 SetKeyGB = 0x2a,
61 SetKeyR = 0x2b,
62 SetConvert = 0x2c,
63 SetScissor = 0x2d,
64 SetPrimDepth = 0x2e,
65 SetOtherModes = 0x2f,
66 LoadTLut = 0x30,
67 SetTileSize = 0x32,
68 LoadBlock = 0x33,
69 LoadTile = 0x34,
70 SetTile = 0x35,
71 FillRectangle = 0x36,
72 SetFillColor = 0x37,
73 SetFogColor = 0x38,
74 SetBlendColor = 0x39,
75 SetPrimColor = 0x3a,
76 SetEnvColor = 0x3b,
77 SetCombine = 0x3c,
78 SetTextureImage = 0x3d,
79 SetMaskImage = 0x3e,
80 SetColorImage = 0x3f
81 };
82
83 enum class RGBMul : uint8_t
84 {
85 Combined = 0,
86 Texel0 = 1,
87 Texel1 = 2,
88 Primitive = 3,
89 Shade = 4,
90 Env = 5,
91 KeyScale = 6,
92 CombinedAlpha = 7,
93 Texel0Alpha = 8,
94 Texel1Alpha = 9,
95 PrimitiveAlpha = 10,
96 ShadeAlpha = 11,
97 EnvAlpha = 12,
98 LODFrac = 13,
99 PrimLODFrac = 14,
100 ConvertK5 = 15,
101 Zero = 16
102 };
103
104 enum class RGBMulAdd : uint8_t
105 {
106 Combined = 0,
107 Texel0 = 1,
108 Texel1 = 2,
109 Primitive = 3,
110 Shade = 4,
111 Env = 5,
112 One = 6,
113 Noise = 7,
114 Zero = 8
115 };
116
117 enum class RGBMulSub : uint8_t
118 {
119 Combined = 0,
120 Texel0 = 1,
121 Texel1 = 2,
122 Primitive = 3,
123 Shade = 4,
124 Env = 5,
125 KeyCenter = 6,
126 ConvertK4 = 7,
127 Zero = 8
128 };
129
130 enum class RGBAdd : uint8_t
131 {
132 Combined = 0,
133 Texel0 = 1,
134 Texel1 = 2,
135 Primitive = 3,
136 Shade = 4,
137 Env = 5,
138 One = 6,
139 Zero = 7
140 };
141
142 enum class AlphaAddSub : uint8_t
143 {
144 CombinedAlpha = 0,
145 Texel0Alpha = 1,
146 Texel1Alpha = 2,
147 PrimitiveAlpha = 3,
148 ShadeAlpha = 4,
149 EnvAlpha = 5,
150 One = 6,
151 Zero = 7
152 };
153
154 enum class AlphaMul : uint8_t
155 {
156 LODFrac = 0,
157 Texel0Alpha = 1,
158 Texel1Alpha = 2,
159 PrimitiveAlpha = 3,
160 ShadeAlpha = 4,
161 EnvAlpha = 5,
162 PrimLODFrac = 6,
163 Zero = 7
164 };
165
166 enum class TextureSize : uint8_t
167 {
168 Bpp4 = 0,
169 Bpp8 = 1,
170 Bpp16 = 2,
171 Bpp32 = 3
172 };
173
174 enum class TextureFormat : uint8_t
175 {
176 RGBA = 0,
177 YUV = 1,
178 CI = 2,
179 IA = 3,
180 I = 4
181 };
182
183 enum class RGBDitherMode : uint8_t
184 {
185 Magic = 0,
186 Bayer = 1,
187 Noise = 2,
188 Off = 3
189 };
190
191 enum class AlphaDitherMode : uint8_t
192 {
193 Pattern = 0,
194 InvPattern = 1,
195 Noise = 2,
196 Off = 3
197 };
198
199 enum class CycleType : uint8_t
200 {
201 Cycle1 = 0,
202 Cycle2 = 1,
203 Copy = 2,
204 Fill = 3
205 };
206
207 enum class BlendMode1A : uint8_t
208 {
209 PixelColor = 0,
210 MemoryColor = 1,
211 BlendColor = 2,
212 FogColor = 3
213 };
214
215 enum class BlendMode1B : uint8_t
216 {
217 PixelAlpha = 0,
218 FogAlpha = 1,
219 ShadeAlpha = 2,
220 Zero = 3
221 };
222
223 enum class BlendMode2A : uint8_t
224 {
225 PixelColor = 0,
226 MemoryColor = 1,
227 BlendColor = 2,
228 FogColor = 3
229 };
230
231 enum class BlendMode2B : uint8_t
232 {
233 InvPixelAlpha = 0,
234 MemoryAlpha = 1,
235 One = 2,
236 Zero = 3
237 };
238
239 enum class CoverageMode : uint8_t
240 {
241 Clamp = 0,
242 Wrap = 1,
243 Zap = 2,
244 Save = 3
245 };
246
247 enum class ZMode : uint8_t
248 {
249 Opaque = 0,
250 Interpenetrating = 1,
251 Transparent = 2,
252 Decal = 3
253 };
254
255 enum TileInfoFlagBits
256 {
257 TILE_INFO_CLAMP_S_BIT = 1 << 0,
258 TILE_INFO_MIRROR_S_BIT = 1 << 1,
259 TILE_INFO_CLAMP_T_BIT = 1 << 2,
260 TILE_INFO_MIRROR_T_BIT = 1 << 3
261 };
262 using TileInfoFlags = uint8_t;
263
264 struct TileSize
265 {
266 uint32_t slo = 0;
267 uint32_t shi = 0;
268 uint32_t tlo = 0;
269 uint32_t thi = 0;
270 };
271
272 struct TileMeta
273 {
274 uint32_t offset = 0;
275 uint32_t stride = 0;
276 TextureFormat fmt = TextureFormat::RGBA;
277 TextureSize size = TextureSize::Bpp16;
278 uint8_t palette = 0;
279 uint8_t mask_s = 0;
280 uint8_t shift_s = 0;
281 uint8_t mask_t = 0;
282 uint8_t shift_t = 0;
283 TileInfoFlags flags = 0;
284 };
285
286 struct TileInfo
287 {
288 TileSize size;
289 TileMeta meta;
290 };
291
292 struct CombinerInputsRGB
293 {
294 RGBMulAdd muladd;
295 RGBMulSub mulsub;
296 RGBMul mul;
297 RGBAdd add;
298 };
299
300 struct CombinerInputsAlpha
301 {
302 AlphaAddSub muladd;
303 AlphaAddSub mulsub;
304 AlphaMul mul;
305 AlphaAddSub add;
306 };
307
308 struct CombinerInputs
309 {
310 CombinerInputsRGB rgb;
311 CombinerInputsAlpha alpha;
312 };
313
314 struct BlendModes
315 {
316 BlendMode1A blend_1a;
317 BlendMode1B blend_1b;
318 BlendMode2A blend_2a;
319 BlendMode2B blend_2b;
320 };
321
322 static_assert(sizeof(TileInfo) == 32, "TileInfo must be 32 bytes.");
323
324 enum class VIRegister
325 {
326 Control = 0,
327 Origin,
328 Width,
329 Intr,
330 VCurrentLine,
331 Timing,
332 VSync,
333 HSync,
334 Leap,
335 HStart,
336 VStart,
337 VBurst,
338 XScale,
339 YScale,
340 Count
341 };
342
343 enum VIControlFlagBits
344 {
345 VI_CONTROL_TYPE_BLANK_BIT = 0 << 0,
346 VI_CONTROL_TYPE_RESERVED_BIT = 1 << 0,
347 VI_CONTROL_TYPE_RGBA5551_BIT = 2 << 0,
348 VI_CONTROL_TYPE_RGBA8888_BIT = 3 << 0,
349 VI_CONTROL_TYPE_MASK = 3 << 0,
350 VI_CONTROL_GAMMA_DITHER_ENABLE_BIT = 1 << 2,
351 VI_CONTROL_GAMMA_ENABLE_BIT = 1 << 3,
352 VI_CONTROL_DIVOT_ENABLE_BIT = 1 << 4,
353 VI_CONTROL_SERRATE_BIT = 1 << 6,
354 VI_CONTROL_AA_MODE_RESAMP_EXTRA_ALWAYS_BIT = 0 << 8,
355 VI_CONTROL_AA_MODE_RESAMP_EXTRA_BIT = 1 << 8,
356 VI_CONTROL_AA_MODE_RESAMP_ONLY_BIT = 2 << 8,
357 VI_CONTROL_AA_MODE_RESAMP_REPLICATE_BIT = 3 << 8,
358 VI_CONTROL_AA_MODE_MASK = 3 << 8,
359 VI_CONTROL_DITHER_FILTER_ENABLE_BIT = 1 << 16,
360 VI_CONTROL_META_AA_BIT = 1 << 17,
361 VI_CONTROL_META_SCALE_BIT = 1 << 18
362 };
363 using VIControlFlags = uint32_t;
364
make_vi_start_register(uint32_t start_value,uint32_t end_value)365 static inline uint32_t make_vi_start_register(uint32_t start_value, uint32_t end_value)
366 {
367 return ((start_value & 0x3ff) << 16) | (end_value & 0x3ff);
368 }
369
make_vi_scale_register(uint32_t scale_factor,uint32_t bias)370 static inline uint32_t make_vi_scale_register(uint32_t scale_factor, uint32_t bias)
371 {
372 return ((bias & 0xfff) << 16) | (scale_factor & 0xfff);
373 }
374
375 constexpr uint32_t VI_V_SYNC_NTSC = 525;
376 constexpr uint32_t VI_V_SYNC_PAL = 625;
377 constexpr uint32_t VI_H_OFFSET_NTSC = 108;
378 constexpr uint32_t VI_H_OFFSET_PAL = 128;
379 constexpr uint32_t VI_V_OFFSET_NTSC = 34;
380 constexpr uint32_t VI_V_OFFSET_PAL = 44;
381 constexpr uint32_t VI_V_RES_NTSC = 480;
382 constexpr uint32_t VI_V_RES_PAL = 576;
383 constexpr int VI_SCANOUT_WIDTH = 640;
384
make_default_v_start()385 static inline uint32_t make_default_v_start()
386 {
387 return make_vi_start_register(VI_V_OFFSET_NTSC, VI_V_OFFSET_NTSC + 224 * 2);
388 }
389
make_default_h_start()390 static inline uint32_t make_default_h_start()
391 {
392 return make_vi_start_register(VI_H_OFFSET_NTSC, VI_H_OFFSET_NTSC + VI_SCANOUT_WIDTH);
393 }
394
395 template <int bits>
sext(int32_t v)396 static int32_t sext(int32_t v)
397 {
398 struct { int32_t dummy : bits; } d;
399 d.dummy = v;
400 return d.dummy;
401 }
402 }