| 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 | |