34cf4058 |
1 | |
2 | #ifndef SHADERCOMBINER_H |
3 | #define SHADERCOMBINER_H |
4 | |
5 | #define PRINT_SHADER |
6 | #define UNIFORM_CHECK |
7 | |
8 | #define SC_FOGENABLED 0x1 |
9 | #define SC_ALPHAENABLED 0x2 |
10 | #define SC_ALPHAGREATER 0x4 |
11 | #define SC_2CYCLE 0x8 |
12 | |
13 | #define SC_POSITION 1 |
14 | #define SC_COLOR 2 |
15 | #define SC_TEXCOORD0 3 |
16 | #define SC_TEXCOORD1 4 |
17 | |
18 | #ifdef UNIFORM_CHECK |
19 | #define SC_SetUniform1i(A, B) \ |
20 | if (scProgramCurrent->uniforms.A.val != B) \ |
21 | {scProgramCurrent->uniforms.A.val = B; glUniform1i(scProgramCurrent->uniforms.A.loc, B);} |
22 | |
23 | #define SC_SetUniform1f(A, B) \ |
24 | if (scProgramCurrent->uniforms.A.val != B) \ |
25 | {scProgramCurrent->uniforms.A.val = B; glUniform1f(scProgramCurrent->uniforms.A.loc, B);} |
26 | |
27 | #define SC_SetUniform4fv(A, B) \ |
28 | if ((scProgramCurrent->uniforms.A.val[0] != (B)[0]) || (scProgramCurrent->uniforms.A.val[1] != (B)[1]) || \ |
29 | (scProgramCurrent->uniforms.A.val[2] != (B)[2]) || (scProgramCurrent->uniforms.A.val[3] != (B)[3])) \ |
30 | {memcpy(scProgramCurrent->uniforms.A.val, B, 16); glUniform4fv(scProgramCurrent->uniforms.A.loc, 1, B);} |
31 | |
32 | #define SC_SetUniform2f(A, B, C) \ |
33 | if ((scProgramCurrent->uniforms.A.val[0] != B) || (scProgramCurrent->uniforms.A.val[1] != C)) \ |
34 | {scProgramCurrent->uniforms.A.val[0] = B; scProgramCurrent->uniforms.A.val[1] = C; glUniform2f(scProgramCurrent->uniforms.A.loc, B, C);} |
35 | |
36 | #define SC_ForceUniform1i(A, B) \ |
37 | {scProgramCurrent->uniforms.A.val = B; glUniform1i(scProgramCurrent->uniforms.A.loc, B);} |
38 | |
39 | #define SC_ForceUniform1f(A, B) \ |
40 | {scProgramCurrent->uniforms.A.val = B; glUniform1f(scProgramCurrent->uniforms.A.loc, B);} |
41 | |
42 | #define SC_ForceUniform4fv(A, B) \ |
43 | {memcpy(scProgramCurrent->uniforms.A.val, B, 16); glUniform4fv(scProgramCurrent->uniforms.A.loc, 1, B);} |
44 | |
45 | #define SC_ForceUniform2f(A, B, C) \ |
46 | {scProgramCurrent->uniforms.A.val[0] = B; scProgramCurrent->uniforms.A.val[1] = C; glUniform2f(scProgramCurrent->uniforms.A.loc, B, C);} |
47 | |
48 | #else |
49 | #define SC_SetUniform1i(A, B) glUniform1i(scProgramCurrent->uniforms.A.loc, B) |
50 | #define SC_SetUniform1f(A, B) glUniform1f(scProgramCurrent->uniforms.A.loc, B) |
51 | #define SC_SetUniform4fv(A, B) glUniform4fv(scProgramCurrent->uniforms.A.loc, 1, B) |
52 | #define SC_SetUniform2f(A, B, C) glUniform2f(scProgramCurrent->uniforms.A.loc, B, C) |
53 | #define SC_ForceUniform1i(A, B) glUniform1i(scProgramCurrent->uniforms.A.loc, B) |
54 | #define SC_ForceUniform1f(A, B) glUniform1f(scProgramCurrent->uniforms.A.loc, B) |
55 | #define SC_ForceUniform4fv(A, B) glUniform4fv(scProgramCurrent->uniforms.A.loc, 1, B) |
56 | #define SC_ForceUniform2f(A, B, C) glUniform2f(scProgramCurrent->uniforms.A.loc, B, C) |
57 | #endif |
58 | |
59 | /* Color combiner constants: */ |
60 | #define G_CCMUX_COMBINED 0 |
61 | #define G_CCMUX_TEXEL0 1 |
62 | #define G_CCMUX_TEXEL1 2 |
63 | #define G_CCMUX_PRIMITIVE 3 |
64 | #define G_CCMUX_SHADE 4 |
65 | #define G_CCMUX_ENVIRONMENT 5 |
66 | #define G_CCMUX_CENTER 6 |
67 | #define G_CCMUX_SCALE 6 |
68 | #define G_CCMUX_COMBINED_ALPHA 7 |
69 | #define G_CCMUX_TEXEL0_ALPHA 8 |
70 | #define G_CCMUX_TEXEL1_ALPHA 9 |
71 | #define G_CCMUX_PRIMITIVE_ALPHA 10 |
72 | #define G_CCMUX_SHADE_ALPHA 11 |
73 | #define G_CCMUX_ENV_ALPHA 12 |
74 | #define G_CCMUX_LOD_FRACTION 13 |
75 | #define G_CCMUX_PRIM_LOD_FRAC 14 |
76 | #define G_CCMUX_NOISE 7 |
77 | #define G_CCMUX_K4 7 |
78 | #define G_CCMUX_K5 15 |
79 | #define G_CCMUX_1 6 |
80 | #define G_CCMUX_0 31 |
81 | |
82 | /* Alpha combiner constants: */ |
83 | #define G_ACMUX_COMBINED 0 |
84 | #define G_ACMUX_TEXEL0 1 |
85 | #define G_ACMUX_TEXEL1 2 |
86 | #define G_ACMUX_PRIMITIVE 3 |
87 | #define G_ACMUX_SHADE 4 |
88 | #define G_ACMUX_ENVIRONMENT 5 |
89 | #define G_ACMUX_LOD_FRACTION 0 |
90 | #define G_ACMUX_PRIM_LOD_FRAC 6 |
91 | #define G_ACMUX_1 6 |
92 | #define G_ACMUX_0 7 |
93 | |
94 | #define EncodeCombineMode( a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \ |
95 | a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1 ) \ |
96 | (u64)(((u64)(_SHIFTL( G_CCMUX_##a0, 20, 4 ) | _SHIFTL( G_CCMUX_##c0, 15, 5 ) | \ |
97 | _SHIFTL( G_ACMUX_##Aa0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ac0, 9, 3 ) | \ |
98 | _SHIFTL( G_CCMUX_##a1, 5, 4 ) | _SHIFTL( G_CCMUX_##c1, 0, 5 )) << 32) | \ |
99 | (u64)(_SHIFTL( G_CCMUX_##b0, 28, 4 ) | _SHIFTL( G_CCMUX_##d0, 15, 3 ) | \ |
100 | _SHIFTL( G_ACMUX_##Ab0, 12, 3 ) | _SHIFTL( G_ACMUX_##Ad0, 9, 3 ) | \ |
101 | _SHIFTL( G_CCMUX_##b1, 24, 4 ) | _SHIFTL( G_ACMUX_##Aa1, 21, 3 ) | \ |
102 | _SHIFTL( G_ACMUX_##Ac1, 18, 3 ) | _SHIFTL( G_CCMUX_##d1, 6, 3 ) | \ |
103 | _SHIFTL( G_ACMUX_##Ab1, 3, 3 ) | _SHIFTL( G_ACMUX_##Ad1, 0, 3 ))) |
104 | |
105 | #define G_CC_PRIMITIVE 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE |
106 | #define G_CC_SHADE 0, 0, 0, SHADE, 0, 0, 0, SHADE |
107 | #define G_CC_MODULATEI TEXEL0, 0, SHADE, 0, 0, 0, 0, SHADE |
108 | #define G_CC_MODULATEIA TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0 |
109 | #define G_CC_MODULATEIDECALA TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0 |
110 | #define G_CC_MODULATERGB G_CC_MODULATEI |
111 | #define G_CC_MODULATERGBA G_CC_MODULATEIA |
112 | #define G_CC_MODULATERGBDECALA G_CC_MODULATEIDECALA |
113 | #define G_CC_MODULATEI_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE |
114 | #define G_CC_MODULATEIA_PRIM TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0 |
115 | #define G_CC_MODULATEIDECALA_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0 |
116 | #define G_CC_MODULATERGB_PRIM G_CC_MODULATEI_PRIM |
117 | #define G_CC_MODULATERGBA_PRIM G_CC_MODULATEIA_PRIM |
118 | #define G_CC_MODULATERGBDECALA_PRIM G_CC_MODULATEIDECALA_PRIM |
119 | #define G_CC_DECALRGB 0, 0, 0, TEXEL0, 0, 0, 0, SHADE |
120 | #define G_CC_DECALRGBA 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0 |
121 | #define G_CC_BLENDI ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE |
122 | #define G_CC_BLENDIA ENVIRONMENT, SHADE, TEXEL0, SHADE, TEXEL0, 0, SHADE, 0 |
123 | #define G_CC_BLENDIDECALA ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0 |
124 | #define G_CC_BLENDRGBA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, SHADE |
125 | #define G_CC_BLENDRGBDECALA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, TEXEL0 |
126 | #define G_CC_ADDRGB 1, 0, TEXEL0, SHADE, 0, 0, 0, SHADE |
127 | #define G_CC_ADDRGBDECALA 1, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0 |
128 | #define G_CC_REFLECTRGB ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, SHADE |
129 | #define G_CC_REFLECTRGBDECALA ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0 |
130 | #define G_CC_HILITERGB PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE |
131 | #define G_CC_HILITERGBA PRIMITIVE, SHADE, TEXEL0, SHADE, PRIMITIVE, SHADE, TEXEL0, SHADE |
132 | #define G_CC_HILITERGBDECALA PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0 |
133 | #define G_CC_SHADEDECALA 0, 0, 0, SHADE, 0, 0, 0, TEXEL0 |
134 | #define G_CC_BLENDPE PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, SHADE, 0 |
135 | #define G_CC_BLENDPEDECALA PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, TEXEL0 |
136 | #define _G_CC_BLENDPE ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, SHADE, 0 |
137 | #define _G_CC_BLENDPEDECALA ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, 0, 0, 0, TEXEL0 |
138 | #define _G_CC_TWOCOLORTEX PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE |
139 | #define _G_CC_SPARSEST PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0 |
140 | #define G_CC_TEMPLERP TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0 |
141 | #define G_CC_TRILERP TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0 |
142 | #define G_CC_INTERFERENCE TEXEL0, 0, TEXEL1, 0, TEXEL0, 0, TEXEL1, 0 |
143 | #define G_CC_1CYUV2RGB TEXEL0, K4, K5, TEXEL0, 0, 0, 0, SHADE |
144 | #define G_CC_YUV2RGB TEXEL1, K4, K5, TEXEL1, 0, 0, 0, 0 |
145 | #define G_CC_PASS2 0, 0, 0, COMBINED, 0, 0, 0, COMBINED |
146 | #define G_CC_MODULATEI2 COMBINED, 0, SHADE, 0, 0, 0, 0, SHADE |
147 | #define G_CC_MODULATEIA2 COMBINED, 0, SHADE, 0, COMBINED, 0, SHADE, 0 |
148 | #define G_CC_MODULATERGB2 G_CC_MODULATEI2 |
149 | #define G_CC_MODULATERGBA2 G_CC_MODULATEIA2 |
150 | #define G_CC_MODULATEI_PRIM2 COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE |
151 | #define G_CC_MODULATEIA_PRIM2 COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0 |
152 | #define G_CC_MODULATERGB_PRIM2 G_CC_MODULATEI_PRIM2 |
153 | #define G_CC_MODULATERGBA_PRIM2 G_CC_MODULATEIA_PRIM2 |
154 | #define G_CC_DECALRGB2 0, 0, 0, COMBINED, 0, 0, 0, SHADE |
155 | #define G_CC_BLENDI2 ENVIRONMENT, SHADE, COMBINED, SHADE, 0, 0, 0, SHADE |
156 | #define G_CC_BLENDIA2 ENVIRONMENT, SHADE, COMBINED, SHADE, COMBINED, 0, SHADE, 0 |
157 | #define G_CC_CHROMA_KEY2 TEXEL0, CENTER, SCALE, 0, 0, 0, 0, 0 |
158 | #define G_CC_HILITERGB2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, SHADE |
159 | #define G_CC_HILITERGBA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, ENVIRONMENT, COMBINED, TEXEL0, COMBINED |
160 | #define G_CC_HILITERGBDECALA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, TEXEL0 |
161 | #define G_CC_HILITERGBPASSA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, COMBINED |
162 | |
163 | // Internal generalized combiner inputs |
164 | #define COMBINED 0 |
165 | #define TEXEL0 1 |
166 | #define TEXEL1 2 |
167 | #define PRIMITIVE 3 |
168 | #define SHADE 4 |
169 | #define ENVIRONMENT 5 |
170 | #define CENTER 6 |
171 | #define SCALE 7 |
172 | #define COMBINED_ALPHA 8 |
173 | #define TEXEL0_ALPHA 9 |
174 | #define TEXEL1_ALPHA 10 |
175 | #define PRIMITIVE_ALPHA 11 |
176 | #define SHADE_ALPHA 12 |
177 | #define ENV_ALPHA 13 |
178 | #define LOD_FRACTION 14 |
179 | #define PRIM_LOD_FRAC 15 |
180 | #define NOISE 16 |
181 | #define K4 17 |
182 | #define K5 18 |
183 | #define ONE 19 |
184 | #define ZERO 20 |
185 | #define UNKNOWN 21 |
186 | |
187 | |
188 | struct UniformLocation |
189 | { |
190 | struct {GLint loc; int val;} uTex0, uTex1, uNoise; |
191 | struct {GLint loc; int val;} uEnableFog; |
192 | struct {GLint loc; float val;} uFogMultiplier, uFogOffset, uAlphaRef, uPrimLODFrac, uRenderState, uK4, uK5; |
193 | struct {GLint loc; float val[4];} uEnvColor, uPrimColor, uFogColor; |
194 | struct {GLint loc; float val[2];} uTexScale, uTexOffset[2], uCacheShiftScale[2], |
195 | uCacheScale[2], uCacheOffset[2]; |
196 | }; |
197 | |
198 | struct ShaderProgram |
199 | { |
200 | GLint program; |
201 | GLint fragment; |
202 | GLint vertex; |
203 | int usesT0; //uses texcoord0 attrib |
204 | int usesT1; //uses texcoord1 attrib |
205 | int usesCol; //uses color attrib |
206 | int usesNoise; //requires noise texture |
207 | |
208 | UniformLocation uniforms; |
209 | gDPCombine combine; |
210 | u32 flags; |
211 | ShaderProgram *left, *right; |
212 | u32 lastUsed; |
213 | }; |
214 | |
215 | |
216 | //dmux flags: |
217 | #define SC_IGNORE_RGB0 (1<<0) |
218 | #define SC_IGNORE_ALPHA0 (1<<1) |
219 | #define SC_IGNORE_RGB1 (1<<2) |
220 | #define SC_IGNORE_ALPHA1 (1<<3) |
221 | |
222 | class DecodedMux |
223 | { |
224 | public: |
225 | DecodedMux(u64 mux, bool cycle2); |
226 | |
227 | void hack(); |
228 | bool find(int index, int src); |
229 | bool swap(int cycle, int src0, int src1); |
230 | bool replace(int cycle, int src, int dest); |
231 | |
232 | gDPCombine combine; |
233 | int decode[4][4]; |
234 | int flags; |
235 | }; |
236 | |
237 | extern int CCEncodeA[]; |
238 | extern int CCEncodeB[]; |
239 | extern int CCEncodeC[]; |
240 | extern int CCEncodeD[]; |
241 | extern int ACEncodeA[]; |
242 | extern int ACEncodeB[]; |
243 | extern int ACEncodeC[]; |
244 | extern int ACEncodeD[]; |
245 | |
246 | extern ShaderProgram *scProgramRoot; |
247 | extern ShaderProgram *scProgramCurrent; |
248 | extern int scProgramChanged; |
249 | extern int scProgramCount; |
250 | |
251 | extern void ShaderCombiner_Init(); |
252 | extern void ShaderCombiner_Destroy(); |
253 | extern void ShaderCombiner_DeleteProgram(ShaderProgram *prog); |
254 | extern void ShaderCombiner_Set(u64 mux, int flags=-1); |
255 | extern ShaderProgram *ShaderCombiner_Compile(DecodedMux *dmux, int flags); |
256 | |
257 | #endif |
258 | |