00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "i915_reg.h"
00029 #include "i915_context.h"
00030 #include "i915_fpc.h"
00031 #include "util/u_math.h"
00032
00033
00034 #define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
00035 #define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
00036 #define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
00037 #define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
00038 #define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
00039 #define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
00040 #define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
00041 #define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
00042
00043
00044
00045 #define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
00046 #define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
00047 (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
00048
00049
00050
00051
00052
00053 #define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
00054 #define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
00055 #define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
00056 #define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
00057 #define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
00058 #define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
00059
00060 #define UREG_MASK 0xffffff00
00061 #define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
00062 (REG_NR_MASK << UREG_NR_SHIFT))
00063
00064
00065 uint
00066 i915_get_temp(struct i915_fp_compile *p)
00067 {
00068 int bit = ffs(~p->temp_flag);
00069 if (!bit) {
00070 i915_program_error(p, "i915_get_temp: out of temporaries\n");
00071 return 0;
00072 }
00073
00074 p->temp_flag |= 1 << (bit - 1);
00075 return bit - 1;
00076 }
00077
00078
00079 static void
00080 i915_release_temp(struct i915_fp_compile *p, int reg)
00081 {
00082 p->temp_flag &= ~(1 << reg);
00083 }
00084
00085
00090 uint
00091 i915_get_utemp(struct i915_fp_compile * p)
00092 {
00093 int bit = ffs(~p->utemp_flag);
00094 if (!bit) {
00095 i915_program_error(p, "i915_get_utemp: out of temporaries\n");
00096 return 0;
00097 }
00098
00099 p->utemp_flag |= 1 << (bit - 1);
00100 return UREG(REG_TYPE_U, (bit - 1));
00101 }
00102
00103 void
00104 i915_release_utemps(struct i915_fp_compile *p)
00105 {
00106 p->utemp_flag = ~0x7;
00107 }
00108
00109
00110 uint
00111 i915_emit_decl(struct i915_fp_compile *p,
00112 uint type, uint nr, uint d0_flags)
00113 {
00114 uint reg = UREG(type, nr);
00115
00116 if (type == REG_TYPE_T) {
00117 if (p->decl_t & (1 << nr))
00118 return reg;
00119
00120 p->decl_t |= (1 << nr);
00121 }
00122 else if (type == REG_TYPE_S) {
00123 if (p->decl_s & (1 << nr))
00124 return reg;
00125
00126 p->decl_s |= (1 << nr);
00127 }
00128 else
00129 return reg;
00130
00131 *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
00132 *(p->decl++) = D1_MBZ;
00133 *(p->decl++) = D2_MBZ;
00134
00135 p->nr_decl_insn++;
00136 return reg;
00137 }
00138
00139 uint
00140 i915_emit_arith(struct i915_fp_compile * p,
00141 uint op,
00142 uint dest,
00143 uint mask,
00144 uint saturate, uint src0, uint src1, uint src2)
00145 {
00146 uint c[3];
00147 uint nr_const = 0;
00148
00149 assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
00150 dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
00151 assert(dest);
00152
00153 if (GET_UREG_TYPE(src0) == REG_TYPE_CONST)
00154 c[nr_const++] = 0;
00155 if (GET_UREG_TYPE(src1) == REG_TYPE_CONST)
00156 c[nr_const++] = 1;
00157 if (GET_UREG_TYPE(src2) == REG_TYPE_CONST)
00158 c[nr_const++] = 2;
00159
00160
00161
00162
00163
00164
00165 if (nr_const > 1) {
00166 uint s[3], first, i, old_utemp_flag;
00167
00168 s[0] = src0;
00169 s[1] = src1;
00170 s[2] = src2;
00171 old_utemp_flag = p->utemp_flag;
00172
00173 first = GET_UREG_NR(s[c[0]]);
00174 for (i = 1; i < nr_const; i++) {
00175 if (GET_UREG_NR(s[c[i]]) != first) {
00176 uint tmp = i915_get_utemp(p);
00177
00178 i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
00179 s[c[i]], 0, 0);
00180 s[c[i]] = tmp;
00181 }
00182 }
00183
00184 src0 = s[0];
00185 src1 = s[1];
00186 src2 = s[2];
00187 p->utemp_flag = old_utemp_flag;
00188 }
00189
00190 *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
00191 *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
00192 *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
00193
00194 p->nr_alu_insn++;
00195 return dest;
00196 }
00197
00198
00207 uint i915_emit_texld( struct i915_fp_compile *p,
00208 uint dest,
00209 uint destmask,
00210 uint sampler,
00211 uint coord,
00212 uint opcode )
00213 {
00214 const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
00215 int temp = -1;
00216
00217 if (coord != k) {
00218
00219
00220
00221 uint tempReg;
00222
00223 temp = i915_get_temp(p);
00224 tempReg = UREG(REG_TYPE_R, temp);
00225
00226 i915_emit_arith( p, A0_MOV,
00227 tempReg, A0_DEST_CHANNEL_ALL,
00228 0,
00229 coord, 0, 0 );
00230
00231
00232 coord = tempReg;
00233 }
00234
00235
00236
00237 if (destmask != A0_DEST_CHANNEL_ALL) {
00238
00239 uint tmp = i915_get_utemp(p);
00240 i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode );
00241 i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
00242
00243 }
00244 else {
00245 assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
00246 assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
00247
00248
00249 if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
00250 p->nr_tex_indirect++;
00251 }
00252
00253 *(p->csr++) = (opcode |
00254 T0_DEST( dest ) |
00255 T0_SAMPLER( sampler ));
00256
00257 *(p->csr++) = T1_ADDRESS_REG( coord );
00258 *(p->csr++) = T2_MBZ;
00259
00260 p->nr_tex_insn++;
00261 }
00262
00263 if (temp >= 0)
00264 i915_release_temp(p, temp);
00265
00266 return dest;
00267 }
00268
00269
00270 uint
00271 i915_emit_const1f(struct i915_fp_compile * p, float c0)
00272 {
00273 struct i915_fragment_shader *ifs = p->shader;
00274 unsigned reg, idx;
00275
00276 if (c0 == 0.0)
00277 return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
00278 if (c0 == 1.0)
00279 return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
00280
00281 for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
00282 if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
00283 continue;
00284 for (idx = 0; idx < 4; idx++) {
00285 if (!(ifs->constant_flags[reg] & (1 << idx)) ||
00286 ifs->constants[reg][idx] == c0) {
00287 ifs->constants[reg][idx] = c0;
00288 ifs->constant_flags[reg] |= 1 << idx;
00289 if (reg + 1 > ifs->num_constants)
00290 ifs->num_constants = reg + 1;
00291 return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
00292 }
00293 }
00294 }
00295
00296 i915_program_error(p, "i915_emit_const1f: out of constants\n");
00297 return 0;
00298 }
00299
00300 uint
00301 i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
00302 {
00303 struct i915_fragment_shader *ifs = p->shader;
00304 unsigned reg, idx;
00305
00306 if (c0 == 0.0)
00307 return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
00308 if (c0 == 1.0)
00309 return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
00310
00311 if (c1 == 0.0)
00312 return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
00313 if (c1 == 1.0)
00314 return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
00315
00316 for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
00317 if (ifs->constant_flags[reg] == 0xf ||
00318 ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
00319 continue;
00320 for (idx = 0; idx < 3; idx++) {
00321 if (!(ifs->constant_flags[reg] & (3 << idx))) {
00322 ifs->constants[reg][idx + 0] = c0;
00323 ifs->constants[reg][idx + 1] = c1;
00324 ifs->constant_flags[reg] |= 3 << idx;
00325 if (reg + 1 > ifs->num_constants)
00326 ifs->num_constants = reg + 1;
00327 return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE);
00328 }
00329 }
00330 }
00331
00332 i915_program_error(p, "i915_emit_const2f: out of constants\n");
00333 return 0;
00334 }
00335
00336
00337
00338 uint
00339 i915_emit_const4f(struct i915_fp_compile * p,
00340 float c0, float c1, float c2, float c3)
00341 {
00342 struct i915_fragment_shader *ifs = p->shader;
00343 unsigned reg;
00344
00345 for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
00346 if (ifs->constant_flags[reg] == 0xf &&
00347 ifs->constants[reg][0] == c0 &&
00348 ifs->constants[reg][1] == c1 &&
00349 ifs->constants[reg][2] == c2 &&
00350 ifs->constants[reg][3] == c3) {
00351 return UREG(REG_TYPE_CONST, reg);
00352 }
00353 else if (ifs->constant_flags[reg] == 0) {
00354
00355 ifs->constants[reg][0] = c0;
00356 ifs->constants[reg][1] = c1;
00357 ifs->constants[reg][2] = c2;
00358 ifs->constants[reg][3] = c3;
00359 ifs->constant_flags[reg] = 0xf;
00360 if (reg + 1 > ifs->num_constants)
00361 ifs->num_constants = reg + 1;
00362 return UREG(REG_TYPE_CONST, reg);
00363 }
00364 }
00365
00366 i915_program_error(p, "i915_emit_const4f: out of constants\n");
00367 return 0;
00368 }
00369
00370
00371 uint
00372 i915_emit_const4fv(struct i915_fp_compile * p, const float * c)
00373 {
00374 return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
00375 }