1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #pragma once
6 
7 #include "Common/BitSet.h"
8 #include "Common/CommonTypes.h"
9 
10 // Vertex array numbers
11 enum
12 {
13   ARRAY_POSITION = 0,
14   ARRAY_NORMAL = 1,
15   ARRAY_COLOR = 2,
16   ARRAY_COLOR2 = 3,
17   ARRAY_TEXCOORD0 = 4,
18 };
19 
20 // Vertex components
21 enum
22 {
23   NOT_PRESENT = 0,
24   DIRECT = 1,
25   INDEX8 = 2,
26   INDEX16 = 3,
27 
28   MASK_INDEXED = 2,
29 };
30 
31 enum
32 {
33   FORMAT_UBYTE = 0,  // 2 Cmp
34   FORMAT_BYTE = 1,   // 3 Cmp
35   FORMAT_USHORT = 2,
36   FORMAT_SHORT = 3,
37   FORMAT_FLOAT = 4,
38 };
39 
40 enum
41 {
42   FORMAT_16B_565 = 0,  // NA
43   FORMAT_24B_888 = 1,
44   FORMAT_32B_888x = 2,
45   FORMAT_16B_4444 = 3,
46   FORMAT_24B_6666 = 4,
47   FORMAT_32B_8888 = 5,
48 };
49 
50 #pragma pack(4)
51 union TVtxDesc
52 {
53   u64 Hex;
54   struct
55   {
56     // 0: not present
57     // 1: present
58     u64 PosMatIdx : 1;
59     u64 Tex0MatIdx : 1;
60     u64 Tex1MatIdx : 1;
61     u64 Tex2MatIdx : 1;
62     u64 Tex3MatIdx : 1;
63     u64 Tex4MatIdx : 1;
64     u64 Tex5MatIdx : 1;
65     u64 Tex6MatIdx : 1;
66     u64 Tex7MatIdx : 1;
67 
68     // 00: not present
69     // 01: direct
70     // 10: 8 bit index
71     // 11: 16 bit index
72     u64 Position : 2;
73     u64 Normal : 2;
74     u64 Color0 : 2;
75     u64 Color1 : 2;
76     u64 Tex0Coord : 2;
77     u64 Tex1Coord : 2;
78     u64 Tex2Coord : 2;
79     u64 Tex3Coord : 2;
80     u64 Tex4Coord : 2;
81     u64 Tex5Coord : 2;
82     u64 Tex6Coord : 2;
83     u64 Tex7Coord : 2;
84     u64 : 31;
85   };
86 
87   struct
88   {
89     u32 Hex0, Hex1;
90   };
91 
92   // Easily index into the Position..Tex7Coord fields.
GetVertexArrayStatus(int idx)93   u32 GetVertexArrayStatus(int idx) { return (Hex >> (9 + idx * 2)) & 0x3; }
94 };
95 
96 union UVAT_group0
97 {
98   u32 Hex;
99   struct
100   {
101     // 0:8
102     u32 PosElements : 1;
103     u32 PosFormat : 3;
104     u32 PosFrac : 5;
105     // 9:12
106     u32 NormalElements : 1;
107     u32 NormalFormat : 3;
108     // 13:16
109     u32 Color0Elements : 1;
110     u32 Color0Comp : 3;
111     // 17:20
112     u32 Color1Elements : 1;
113     u32 Color1Comp : 3;
114     // 21:29
115     u32 Tex0CoordElements : 1;
116     u32 Tex0CoordFormat : 3;
117     u32 Tex0Frac : 5;
118     // 30:31
119     u32 ByteDequant : 1;
120     u32 NormalIndex3 : 1;
121   };
122 };
123 
124 union UVAT_group1
125 {
126   u32 Hex;
127   struct
128   {
129     // 0:8
130     u32 Tex1CoordElements : 1;
131     u32 Tex1CoordFormat : 3;
132     u32 Tex1Frac : 5;
133     // 9:17
134     u32 Tex2CoordElements : 1;
135     u32 Tex2CoordFormat : 3;
136     u32 Tex2Frac : 5;
137     // 18:26
138     u32 Tex3CoordElements : 1;
139     u32 Tex3CoordFormat : 3;
140     u32 Tex3Frac : 5;
141     // 27:30
142     u32 Tex4CoordElements : 1;
143     u32 Tex4CoordFormat : 3;
144     //
145     u32 : 1;
146   };
147 };
148 
149 union UVAT_group2
150 {
151   u32 Hex;
152   struct
153   {
154     // 0:4
155     u32 Tex4Frac : 5;
156     // 5:13
157     u32 Tex5CoordElements : 1;
158     u32 Tex5CoordFormat : 3;
159     u32 Tex5Frac : 5;
160     // 14:22
161     u32 Tex6CoordElements : 1;
162     u32 Tex6CoordFormat : 3;
163     u32 Tex6Frac : 5;
164     // 23:31
165     u32 Tex7CoordElements : 1;
166     u32 Tex7CoordFormat : 3;
167     u32 Tex7Frac : 5;
168   };
169 };
170 
171 struct ColorAttr
172 {
173   u8 Elements;
174   u8 Comp;
175 };
176 
177 struct TexAttr
178 {
179   u8 Elements;
180   u8 Format;
181   u8 Frac;
182 };
183 
184 struct TVtxAttr
185 {
186   u8 PosElements;
187   u8 PosFormat;
188   u8 PosFrac;
189   u8 NormalElements;
190   u8 NormalFormat;
191   ColorAttr color[2];
192   TexAttr texCoord[8];
193   bool ByteDequant;
194   u8 NormalIndex3;
195 };
196 
197 // Matrix indices
198 union TMatrixIndexA
199 {
200   struct
201   {
202     u32 PosNormalMtxIdx : 6;
203     u32 Tex0MtxIdx : 6;
204     u32 Tex1MtxIdx : 6;
205     u32 Tex2MtxIdx : 6;
206     u32 Tex3MtxIdx : 6;
207   };
208   struct
209   {
210     u32 Hex : 30;
211     u32 unused : 2;
212   };
213 };
214 
215 union TMatrixIndexB
216 {
217   struct
218   {
219     u32 Tex4MtxIdx : 6;
220     u32 Tex5MtxIdx : 6;
221     u32 Tex6MtxIdx : 6;
222     u32 Tex7MtxIdx : 6;
223   };
224   struct
225   {
226     u32 Hex : 24;
227     u32 unused : 8;
228   };
229 };
230 
231 #pragma pack()
232 
233 struct VAT
234 {
235   UVAT_group0 g0;
236   UVAT_group1 g1;
237   UVAT_group2 g2;
238 };
239 
240 class VertexLoaderBase;
241 
242 // STATE_TO_SAVE
243 struct CPState final
244 {
245   u32 array_bases[16];
246   u32 array_strides[16];
247   TMatrixIndexA matrix_index_a;
248   TMatrixIndexB matrix_index_b;
249   TVtxDesc vtx_desc;
250   // Most games only use the first VtxAttr and simply reconfigure it all the time as needed.
251   VAT vtx_attr[8];
252 
253   // Attributes that actually belong to VertexLoaderManager:
254   BitSet32 attr_dirty;
255   bool bases_dirty;
256   VertexLoaderBase* vertex_loaders[8];
257   int last_id;
258 };
259 
260 class PointerWrap;
261 
262 extern CPState g_main_cp_state;
263 extern CPState g_preprocess_cp_state;
264 
265 // Might move this into its own file later.
266 void LoadCPReg(u32 SubCmd, u32 Value, bool is_preprocess = false);
267 
268 // Fills memory with data from CP regs
269 void FillCPMemoryArray(u32* memory);
270 
271 void DoCPState(PointerWrap& p);
272 
273 void CopyPreprocessCPStateFromMain();
274