00001
00002 #include "brw_context.h"
00003 #include "brw_eu.h"
00004 #include "brw_wm.h"
00005 #include "util/u_math.h"
00006 #include "util/u_memory.h"
00007 #include "pipe/p_shader_tokens.h"
00008 #include "tgsi/tgsi_parse.h"
00009
00010
00011
00012 static int get_scalar_dst_index(struct tgsi_full_instruction *inst)
00013 {
00014 struct tgsi_dst_register dst = inst->FullDstRegisters[0].DstRegister;
00015 int i;
00016 for (i = 0; i < 4; i++)
00017 if (dst.WriteMask & (1<<i))
00018 break;
00019 return i;
00020 }
00021
00022 static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
00023 {
00024 c->tmp_index++;
00025 c->reg_index = MAX2(c->reg_index, c->tmp_index);
00026 return brw_vec8_grf(c->tmp_start + c->tmp_index, 0);
00027 }
00028
00029 static void release_tmps(struct brw_wm_compile *c)
00030 {
00031 c->tmp_index = 0;
00032 }
00033
00034
00035 static struct brw_reg
00036 get_reg(struct brw_wm_compile *c, int file, int index, int component )
00037 {
00038 switch (file) {
00039 case TGSI_FILE_NULL:
00040 return brw_null_reg();
00041
00042 case TGSI_FILE_SAMPLER:
00043
00044
00045 assert (0);
00046 return brw_null_reg();
00047
00048 case TGSI_FILE_IMMEDIATE:
00049
00050
00051 assert(0);
00052 return brw_null_reg();
00053
00054
00055 case TGSI_FILE_CONSTANT:
00056 case TGSI_FILE_INPUT:
00057 case TGSI_FILE_OUTPUT:
00058 case TGSI_FILE_TEMPORARY:
00059 case TGSI_FILE_ADDRESS:
00060 return c->wm_regs[file][index][component];
00061
00062 default:
00063 assert(0);
00064 return brw_null_reg();
00065 }
00066 }
00067
00068
00069 static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
00070 struct tgsi_full_instruction *inst,
00071 int component)
00072 {
00073 return get_reg(c,
00074 inst->FullDstRegisters[0].DstRegister.File,
00075 inst->FullDstRegisters[0].DstRegister.Index,
00076 component);
00077 }
00078
00079 static int get_swz( struct tgsi_src_register src, int index )
00080 {
00081 switch (index & 3) {
00082 case 0: return src.SwizzleX;
00083 case 1: return src.SwizzleY;
00084 case 2: return src.SwizzleZ;
00085 case 3: return src.SwizzleW;
00086 default: return 0;
00087 }
00088 }
00089
00090 static int get_ext_swz( struct tgsi_src_register_ext_swz src, int index )
00091 {
00092 switch (index & 3) {
00093 case 0: return src.ExtSwizzleX;
00094 case 1: return src.ExtSwizzleY;
00095 case 2: return src.ExtSwizzleZ;
00096 case 3: return src.ExtSwizzleW;
00097 default: return 0;
00098 }
00099 }
00100
00101 static struct brw_reg get_src_reg(struct brw_wm_compile *c,
00102 struct tgsi_full_src_register *src,
00103 int index)
00104 {
00105 struct brw_reg reg;
00106 int component = index;
00107 int neg = 0;
00108 int abs = 0;
00109
00110 if (src->SrcRegister.Negate)
00111 neg = 1;
00112
00113 component = get_swz(src->SrcRegister, component);
00114
00115
00116
00117 switch (component & 3) {
00118 case 0: neg ^= src->SrcRegisterExtSwz.NegateX; break;
00119 case 1: neg ^= src->SrcRegisterExtSwz.NegateY; break;
00120 case 2: neg ^= src->SrcRegisterExtSwz.NegateZ; break;
00121 case 3: neg ^= src->SrcRegisterExtSwz.NegateW; break;
00122 }
00123
00124
00125
00126 component = get_ext_swz(src->SrcRegisterExtSwz, component);
00127
00128
00129
00130 assert(src->SrcRegister.Indirect == 0);
00131
00132
00133
00134 assert(src->SrcRegister.Dimension == 0);
00135
00136
00137
00138 assert(src->SrcRegisterExtMod.Complement == 0);
00139 assert(src->SrcRegisterExtMod.Bias == 0);
00140 assert(src->SrcRegisterExtMod.Scale2X == 0);
00141
00142 if (src->SrcRegisterExtMod.Absolute)
00143 abs = 1;
00144
00145
00146
00147
00148 assert(src->SrcRegisterExtMod.Negate == 0);
00149
00150 switch( component ) {
00151 case TGSI_EXTSWIZZLE_X:
00152 case TGSI_EXTSWIZZLE_Y:
00153 case TGSI_EXTSWIZZLE_Z:
00154 case TGSI_EXTSWIZZLE_W:
00155 reg = get_reg(c,
00156 src->SrcRegister.File,
00157 src->SrcRegister.Index,
00158 component );
00159
00160 if (neg)
00161 reg = negate(reg);
00162
00163 if (abs)
00164 reg = brw_abs(reg);
00165
00166 break;
00167
00168
00169
00170
00171
00172
00173 case TGSI_EXTSWIZZLE_ZERO:
00174 reg = brw_imm_f(0);
00175 break;
00176
00177 case TGSI_EXTSWIZZLE_ONE:
00178 if (neg && !abs)
00179 reg = brw_imm_f(-1.0);
00180 else
00181 reg = brw_imm_f(1.0);
00182 break;
00183
00184 default:
00185 assert(0);
00186 break;
00187 }
00188
00189
00190 return reg;
00191 }
00192
00193 static void emit_abs( struct brw_wm_compile *c,
00194 struct tgsi_full_instruction *inst)
00195 {
00196 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00197
00198 int i;
00199 struct brw_compile *p = &c->func;
00200 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
00201 for (i = 0; i < 4; i++) {
00202 if (mask & (1<<i)) {
00203 struct brw_reg src, dst;
00204 dst = get_dst_reg(c, inst, i);
00205 src = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00206 brw_MOV(p, dst, brw_abs(src));
00207 }
00208 }
00209 brw_set_saturate(p, 0);
00210 }
00211
00212
00213 static void emit_xpd(struct brw_wm_compile *c,
00214 struct tgsi_full_instruction *inst)
00215 {
00216 int i;
00217 struct brw_compile *p = &c->func;
00218 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00219 for (i = 0; i < 4; i++) {
00220 unsigned i2 = (i+2)%3;
00221 unsigned i1 = (i+1)%3;
00222 if (mask & (1<<i)) {
00223 struct brw_reg src0, src1, dst;
00224 dst = get_dst_reg(c, inst, i);
00225 src0 = negate(get_src_reg(c, &inst->FullSrcRegisters[0], i2));
00226 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i1);
00227 brw_MUL(p, brw_null_reg(), src0, src1);
00228 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i1);
00229 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i2);
00230 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
00231 brw_MAC(p, dst, src0, src1);
00232 brw_set_saturate(p, 0);
00233 }
00234 }
00235 brw_set_saturate(p, 0);
00236 }
00237
00238 static void emit_dp3(struct brw_wm_compile *c,
00239 struct tgsi_full_instruction *inst)
00240 {
00241 struct brw_reg src0[3], src1[3], dst;
00242 int i;
00243 struct brw_compile *p = &c->func;
00244 for (i = 0; i < 3; i++) {
00245 src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00246 src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00247 }
00248
00249 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
00250 brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
00251 brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
00252 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00253 brw_MAC(p, dst, src0[2], src1[2]);
00254 brw_set_saturate(p, 0);
00255 }
00256
00257 static void emit_dp4(struct brw_wm_compile *c,
00258 struct tgsi_full_instruction *inst)
00259 {
00260 struct brw_reg src0[4], src1[4], dst;
00261 int i;
00262 struct brw_compile *p = &c->func;
00263 for (i = 0; i < 4; i++) {
00264 src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00265 src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00266 }
00267 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
00268 brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
00269 brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
00270 brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
00271 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00272 brw_MAC(p, dst, src0[3], src1[3]);
00273 brw_set_saturate(p, 0);
00274 }
00275
00276 static void emit_dph(struct brw_wm_compile *c,
00277 struct tgsi_full_instruction *inst)
00278 {
00279 struct brw_reg src0[4], src1[4], dst;
00280 int i;
00281 struct brw_compile *p = &c->func;
00282 for (i = 0; i < 4; i++) {
00283 src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00284 src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00285 }
00286 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
00287 brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
00288 brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
00289 brw_MAC(p, dst, src0[2], src1[2]);
00290 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00291 brw_ADD(p, dst, src0[3], src1[3]);
00292 brw_set_saturate(p, 0);
00293 }
00294
00295 static void emit_math1(struct brw_wm_compile *c,
00296 struct tgsi_full_instruction *inst, unsigned func)
00297 {
00298 struct brw_compile *p = &c->func;
00299 struct brw_reg src0, dst;
00300
00301 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
00302 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
00303 brw_MOV(p, brw_message_reg(2), src0);
00304 brw_math(p,
00305 dst,
00306 func,
00307 ((inst->Instruction.Saturate != TGSI_SAT_NONE)
00308 ? BRW_MATH_SATURATE_SATURATE
00309 : BRW_MATH_SATURATE_NONE),
00310 2,
00311 brw_null_reg(),
00312 BRW_MATH_DATA_VECTOR,
00313 BRW_MATH_PRECISION_FULL);
00314 }
00315
00316
00317 static void emit_alu2(struct brw_wm_compile *c,
00318 struct tgsi_full_instruction *inst,
00319 unsigned opcode)
00320 {
00321 struct brw_compile *p = &c->func;
00322 struct brw_reg src0, src1, dst;
00323 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00324 int i;
00325 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00326 for (i = 0 ; i < 4; i++) {
00327 if (mask & (1<<i)) {
00328 dst = get_dst_reg(c, inst, i);
00329 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00330 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00331 brw_alu2(p, opcode, dst, src0, src1);
00332 }
00333 }
00334 brw_set_saturate(p, 0);
00335 }
00336
00337
00338 static void emit_alu1(struct brw_wm_compile *c,
00339 struct tgsi_full_instruction *inst,
00340 unsigned opcode)
00341 {
00342 struct brw_compile *p = &c->func;
00343 struct brw_reg src0, dst;
00344 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00345 int i;
00346 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00347 for (i = 0 ; i < 4; i++) {
00348 if (mask & (1<<i)) {
00349 dst = get_dst_reg(c, inst, i);
00350 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00351 brw_alu1(p, opcode, dst, src0);
00352 }
00353 }
00354 if (inst->Instruction.Saturate != TGSI_SAT_NONE)
00355 brw_set_saturate(p, 0);
00356 }
00357
00358
00359 static void emit_max(struct brw_wm_compile *c,
00360 struct tgsi_full_instruction *inst)
00361 {
00362 struct brw_compile *p = &c->func;
00363 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00364 struct brw_reg src0, src1, dst;
00365 int i;
00366 brw_push_insn_state(p);
00367 for (i = 0; i < 4; i++) {
00368 if (mask & (1<<i)) {
00369 dst = get_dst_reg(c, inst, i);
00370 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00371 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00372 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00373 brw_MOV(p, dst, src0);
00374 brw_set_saturate(p, 0);
00375
00376 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src0, src1);
00377 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00378 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
00379 brw_MOV(p, dst, src1);
00380 brw_set_saturate(p, 0);
00381 brw_set_predicate_control_flag_value(p, 0xff);
00382 }
00383 }
00384 brw_pop_insn_state(p);
00385 }
00386
00387 static void emit_min(struct brw_wm_compile *c,
00388 struct tgsi_full_instruction *inst)
00389 {
00390 struct brw_compile *p = &c->func;
00391 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00392 struct brw_reg src0, src1, dst;
00393 int i;
00394 brw_push_insn_state(p);
00395 for (i = 0; i < 4; i++) {
00396 if (mask & (1<<i)) {
00397 dst = get_dst_reg(c, inst, i);
00398 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00399 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00400 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00401 brw_MOV(p, dst, src0);
00402 brw_set_saturate(p, 0);
00403
00404 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0);
00405 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00406 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
00407 brw_MOV(p, dst, src1);
00408 brw_set_saturate(p, 0);
00409 brw_set_predicate_control_flag_value(p, 0xff);
00410 }
00411 }
00412 brw_pop_insn_state(p);
00413 }
00414
00415 static void emit_pow(struct brw_wm_compile *c,
00416 struct tgsi_full_instruction *inst)
00417 {
00418 struct brw_compile *p = &c->func;
00419 struct brw_reg dst, src0, src1;
00420 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
00421 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
00422 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], 0);
00423
00424 brw_MOV(p, brw_message_reg(2), src0);
00425 brw_MOV(p, brw_message_reg(3), src1);
00426
00427 brw_math(p,
00428 dst,
00429 BRW_MATH_FUNCTION_POW,
00430 (inst->Instruction.Saturate != TGSI_SAT_NONE
00431 ? BRW_MATH_SATURATE_SATURATE
00432 : BRW_MATH_SATURATE_NONE),
00433 2,
00434 brw_null_reg(),
00435 BRW_MATH_DATA_VECTOR,
00436 BRW_MATH_PRECISION_FULL);
00437 }
00438
00439 static void emit_lrp(struct brw_wm_compile *c,
00440 struct tgsi_full_instruction *inst)
00441 {
00442 struct brw_compile *p = &c->func;
00443 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00444 struct brw_reg dst, tmp1, tmp2, src0, src1, src2;
00445 int i;
00446 for (i = 0; i < 4; i++) {
00447 if (mask & (1<<i)) {
00448 dst = get_dst_reg(c, inst, i);
00449 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00450
00451 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00452
00453 if (src1.nr == dst.nr) {
00454 tmp1 = alloc_tmp(c);
00455 brw_MOV(p, tmp1, src1);
00456 } else
00457 tmp1 = src1;
00458
00459 src2 = get_src_reg(c, &inst->FullSrcRegisters[2], i);
00460 if (src2.nr == dst.nr) {
00461 tmp2 = alloc_tmp(c);
00462 brw_MOV(p, tmp2, src2);
00463 } else
00464 tmp2 = src2;
00465
00466 brw_ADD(p, dst, negate(src0), brw_imm_f(1.0));
00467 brw_MUL(p, brw_null_reg(), dst, tmp2);
00468 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00469 brw_MAC(p, dst, src0, tmp1);
00470 brw_set_saturate(p, 0);
00471 }
00472 release_tmps(c);
00473 }
00474 }
00475
00476 static void emit_kil(struct brw_wm_compile *c)
00477 {
00478 struct brw_compile *p = &c->func;
00479 struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
00480 brw_push_insn_state(p);
00481 brw_set_mask_control(p, BRW_MASK_DISABLE);
00482 brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1));
00483 brw_AND(p, depth, c->emit_mask_reg, depth);
00484 brw_pop_insn_state(p);
00485 }
00486
00487 static void emit_mad(struct brw_wm_compile *c,
00488 struct tgsi_full_instruction *inst)
00489 {
00490 struct brw_compile *p = &c->func;
00491 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00492 struct brw_reg dst, src0, src1, src2;
00493 int i;
00494
00495 for (i = 0; i < 4; i++) {
00496 if (mask & (1<<i)) {
00497 dst = get_dst_reg(c, inst, i);
00498 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00499 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00500 src2 = get_src_reg(c, &inst->FullSrcRegisters[2], i);
00501 brw_MUL(p, dst, src0, src1);
00502
00503 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
00504 brw_ADD(p, dst, dst, src2);
00505 brw_set_saturate(p, 0);
00506 }
00507 }
00508 }
00509
00510 static void emit_sop(struct brw_wm_compile *c,
00511 struct tgsi_full_instruction *inst, unsigned cond)
00512 {
00513 struct brw_compile *p = &c->func;
00514 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00515 struct brw_reg dst, src0, src1;
00516 int i;
00517
00518 brw_push_insn_state(p);
00519 for (i = 0; i < 4; i++) {
00520 if (mask & (1<<i)) {
00521 dst = get_dst_reg(c, inst, i);
00522 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00523 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
00524 brw_CMP(p, brw_null_reg(), cond, src0, src1);
00525 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00526 brw_MOV(p, dst, brw_imm_f(0.0));
00527 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
00528 brw_MOV(p, dst, brw_imm_f(1.0));
00529 }
00530 }
00531 brw_pop_insn_state(p);
00532 }
00533
00534
00535 static void emit_ddx(struct brw_wm_compile *c,
00536 struct tgsi_full_instruction *inst)
00537 {
00538 struct brw_compile *p = &c->func;
00539 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00540 struct brw_reg interp[4];
00541 struct brw_reg dst;
00542 struct brw_reg src0, w;
00543 unsigned nr, i;
00544 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
00545 w = get_src_reg(c, &inst->FullSrcRegisters[1], 3);
00546 nr = src0.nr;
00547 interp[0] = brw_vec1_grf(nr, 0);
00548 interp[1] = brw_vec1_grf(nr, 4);
00549 interp[2] = brw_vec1_grf(nr+1, 0);
00550 interp[3] = brw_vec1_grf(nr+1, 4);
00551 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
00552 for(i = 0; i < 4; i++ ) {
00553 if (mask & (1<<i)) {
00554 dst = get_dst_reg(c, inst, i);
00555 brw_MOV(p, dst, interp[i]);
00556 brw_MUL(p, dst, dst, w);
00557 }
00558 }
00559 brw_set_saturate(p, 0);
00560 }
00561
00562 static void emit_ddy(struct brw_wm_compile *c,
00563 struct tgsi_full_instruction *inst)
00564 {
00565 struct brw_compile *p = &c->func;
00566 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
00567 struct brw_reg interp[4];
00568 struct brw_reg dst;
00569 struct brw_reg src0, w;
00570 unsigned nr, i;
00571
00572 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
00573 nr = src0.nr;
00574 w = get_src_reg(c, &inst->FullSrcRegisters[1], 3);
00575 interp[0] = brw_vec1_grf(nr, 0);
00576 interp[1] = brw_vec1_grf(nr, 4);
00577 interp[2] = brw_vec1_grf(nr+1, 0);
00578 interp[3] = brw_vec1_grf(nr+1, 4);
00579 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
00580 for(i = 0; i < 4; i++ ) {
00581 if (mask & (1<<i)) {
00582 dst = get_dst_reg(c, inst, i);
00583 brw_MOV(p, dst, suboffset(interp[i], 1));
00584 brw_MUL(p, dst, dst, w);
00585 }
00586 }
00587 brw_set_saturate(p, 0);
00588 }
00589
00590
00591
00592
00593 static void emit_txb(struct brw_wm_compile *c,
00594 struct tgsi_full_instruction *inst)
00595 {
00596 #if 0
00597 struct brw_compile *p = &c->func;
00598 struct brw_reg payload_reg = c->payload_depth[0];
00599 struct brw_reg dst[4], src[4];
00600 unsigned i;
00601 for (i = 0; i < 4; i++)
00602 dst[i] = get_dst_reg(c, inst, i);
00603 for (i = 0; i < 4; i++)
00604 src[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00605
00606 #if 0
00607 switch (inst->TexSrcTarget) {
00608 case TEXTURE_1D_INDEX:
00609 brw_MOV(p, brw_message_reg(2), src[0]);
00610 brw_MOV(p, brw_message_reg(3), brw_imm_f(0));
00611 brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
00612 break;
00613 case TEXTURE_2D_INDEX:
00614 case TEXTURE_RECT_INDEX:
00615 brw_MOV(p, brw_message_reg(2), src[0]);
00616 brw_MOV(p, brw_message_reg(3), src[1]);
00617 brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
00618 break;
00619 default:
00620 brw_MOV(p, brw_message_reg(2), src[0]);
00621 brw_MOV(p, brw_message_reg(3), src[1]);
00622 brw_MOV(p, brw_message_reg(4), src[2]);
00623 break;
00624 }
00625 #else
00626 brw_MOV(p, brw_message_reg(2), src[0]);
00627 brw_MOV(p, brw_message_reg(3), src[1]);
00628 brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
00629 #endif
00630
00631 brw_MOV(p, brw_message_reg(5), src[3]);
00632 brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
00633 brw_SAMPLE(p,
00634 retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
00635 1,
00636 retype(payload_reg, BRW_REGISTER_TYPE_UW),
00637 inst->TexSrcUnit + 1,
00638 inst->TexSrcUnit,
00639 inst->FullDstRegisters[0].DstRegister.WriteMask,
00640 BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
00641 4,
00642 4,
00643 0);
00644 #endif
00645 }
00646
00647 static void emit_tex(struct brw_wm_compile *c,
00648 struct tgsi_full_instruction *inst)
00649 {
00650 #if 0
00651 struct brw_compile *p = &c->func;
00652 struct brw_reg payload_reg = c->payload_depth[0];
00653 struct brw_reg dst[4], src[4];
00654 unsigned msg_len;
00655 unsigned i, nr;
00656 unsigned emit;
00657 boolean shadow = (c->key.shadowtex_mask & (1<<inst->TexSrcUnit)) ? 1 : 0;
00658
00659 for (i = 0; i < 4; i++)
00660 dst[i] = get_dst_reg(c, inst, i);
00661 for (i = 0; i < 4; i++)
00662 src[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
00663
00664 #if 0
00665 switch (inst->TexSrcTarget) {
00666 case TEXTURE_1D_INDEX:
00667 emit = WRITEMASK_X;
00668 nr = 1;
00669 break;
00670 case TEXTURE_2D_INDEX:
00671 case TEXTURE_RECT_INDEX:
00672 emit = WRITEMASK_XY;
00673 nr = 2;
00674 break;
00675 default:
00676 emit = WRITEMASK_XYZ;
00677 nr = 3;
00678 break;
00679 }
00680 #else
00681 emit = WRITEMASK_XY;
00682 nr = 2;
00683 #endif
00684
00685 msg_len = 1;
00686
00687 for (i = 0; i < nr; i++) {
00688 static const unsigned swz[4] = {0,1,2,2};
00689 if (emit & (1<<i))
00690 brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
00691 else
00692 brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
00693 msg_len += 1;
00694 }
00695
00696 if (shadow) {
00697 brw_MOV(p, brw_message_reg(5), brw_imm_f(0));
00698 brw_MOV(p, brw_message_reg(6), src[2]);
00699 }
00700
00701 brw_SAMPLE(p,
00702 retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
00703 1,
00704 retype(payload_reg, BRW_REGISTER_TYPE_UW),
00705 inst->TexSrcUnit + 1,
00706 inst->TexSrcUnit,
00707 inst->FullDstRegisters[0].DstRegister.WriteMask,
00708 BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
00709 4,
00710 shadow ? 6 : 4,
00711 0);
00712
00713 if (shadow)
00714 brw_MOV(p, dst[3], brw_imm_f(1.0));
00715 #endif
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725 static void emit_fb_write(struct brw_wm_compile *c,
00726 struct tgsi_full_instruction *inst)
00727 {
00728 struct brw_compile *p = &c->func;
00729 int nr = 2;
00730 int channel;
00731 int base_reg = 0;
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 if (c->key.aa_dest_stencil_reg)
00743 nr += 1;
00744
00745 {
00746 brw_push_insn_state(p);
00747 for (channel = 0; channel < 4; channel++) {
00748 struct brw_reg src0 = c->wm_regs[TGSI_FILE_OUTPUT][0][channel];
00749
00750
00751
00752 brw_MOV(p, brw_message_reg(nr + channel), src0);
00753 }
00754
00755 nr += 8;
00756 brw_pop_insn_state(p);
00757 }
00758
00759
00760
00761
00762
00763 {
00764 brw_push_insn_state(p);
00765 brw_set_mask_control(p, BRW_MASK_DISABLE);
00766 brw_MOV(p,
00767 brw_message_reg(base_reg + 1),
00768 brw_vec8_grf(1, 0));
00769 brw_pop_insn_state(p);
00770 }
00771
00772
00773 brw_fb_WRITE(p,
00774 retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
00775 base_reg,
00776 retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
00777 0,
00778 nr,
00779 0,
00780 1);
00781
00782 }
00783
00784
00785 static void brw_wm_emit_instruction( struct brw_wm_compile *c,
00786 struct tgsi_full_instruction *inst )
00787 {
00788 struct brw_compile *p = &c->func;
00789
00790 #if 0
00791 if (inst->CondUpdate)
00792 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
00793 else
00794 brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
00795 #else
00796 brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
00797 #endif
00798
00799 switch (inst->Instruction.Opcode) {
00800 case TGSI_OPCODE_ABS:
00801 emit_abs(c, inst);
00802 break;
00803 case TGSI_OPCODE_ADD:
00804 emit_alu2(c, inst, BRW_OPCODE_ADD);
00805 break;
00806 case TGSI_OPCODE_SUB:
00807 assert(0);
00808
00809 break;
00810 case TGSI_OPCODE_FRC:
00811 emit_alu1(c, inst, BRW_OPCODE_FRC);
00812 break;
00813 case TGSI_OPCODE_FLR:
00814 assert(0);
00815
00816 break;
00817 case TGSI_OPCODE_LRP:
00818 emit_lrp(c, inst);
00819 break;
00820 case TGSI_OPCODE_INT:
00821 emit_alu1(c, inst, BRW_OPCODE_RNDD);
00822 break;
00823 case TGSI_OPCODE_MOV:
00824 emit_alu1(c, inst, BRW_OPCODE_MOV);
00825 break;
00826 case TGSI_OPCODE_DP3:
00827 emit_dp3(c, inst);
00828 break;
00829 case TGSI_OPCODE_DP4:
00830 emit_dp4(c, inst);
00831 break;
00832 case TGSI_OPCODE_XPD:
00833 emit_xpd(c, inst);
00834 break;
00835 case TGSI_OPCODE_DPH:
00836 emit_dph(c, inst);
00837 break;
00838 case TGSI_OPCODE_RCP:
00839 emit_math1(c, inst, BRW_MATH_FUNCTION_INV);
00840 break;
00841 case TGSI_OPCODE_RSQ:
00842 emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ);
00843 break;
00844 case TGSI_OPCODE_SIN:
00845 emit_math1(c, inst, BRW_MATH_FUNCTION_SIN);
00846 break;
00847 case TGSI_OPCODE_COS:
00848 emit_math1(c, inst, BRW_MATH_FUNCTION_COS);
00849 break;
00850 case TGSI_OPCODE_EX2:
00851 emit_math1(c, inst, BRW_MATH_FUNCTION_EXP);
00852 break;
00853 case TGSI_OPCODE_LG2:
00854 emit_math1(c, inst, BRW_MATH_FUNCTION_LOG);
00855 break;
00856 case TGSI_OPCODE_MAX:
00857 emit_max(c, inst);
00858 break;
00859 case TGSI_OPCODE_MIN:
00860 emit_min(c, inst);
00861 break;
00862 case TGSI_OPCODE_DDX:
00863 emit_ddx(c, inst);
00864 break;
00865 case TGSI_OPCODE_DDY:
00866 emit_ddy(c, inst);
00867 break;
00868 case TGSI_OPCODE_SLT:
00869 emit_sop(c, inst, BRW_CONDITIONAL_L);
00870 break;
00871 case TGSI_OPCODE_SLE:
00872 emit_sop(c, inst, BRW_CONDITIONAL_LE);
00873 break;
00874 case TGSI_OPCODE_SGT:
00875 emit_sop(c, inst, BRW_CONDITIONAL_G);
00876 break;
00877 case TGSI_OPCODE_SGE:
00878 emit_sop(c, inst, BRW_CONDITIONAL_GE);
00879 break;
00880 case TGSI_OPCODE_SEQ:
00881 emit_sop(c, inst, BRW_CONDITIONAL_EQ);
00882 break;
00883 case TGSI_OPCODE_SNE:
00884 emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
00885 break;
00886 case TGSI_OPCODE_MUL:
00887 emit_alu2(c, inst, BRW_OPCODE_MUL);
00888 break;
00889 case TGSI_OPCODE_POW:
00890 emit_pow(c, inst);
00891 break;
00892 case TGSI_OPCODE_MAD:
00893 emit_mad(c, inst);
00894 break;
00895 case TGSI_OPCODE_TEX:
00896 emit_tex(c, inst);
00897 break;
00898 case TGSI_OPCODE_TXB:
00899 emit_txb(c, inst);
00900 break;
00901 case TGSI_OPCODE_TEXKILL:
00902 emit_kil(c);
00903 break;
00904 case TGSI_OPCODE_IF:
00905 assert(c->if_insn < MAX_IFSN);
00906 c->if_inst[c->if_insn++] = brw_IF(p, BRW_EXECUTE_8);
00907 break;
00908 case TGSI_OPCODE_ELSE:
00909 c->if_inst[c->if_insn-1] = brw_ELSE(p, c->if_inst[c->if_insn-1]);
00910 break;
00911 case TGSI_OPCODE_ENDIF:
00912 assert(c->if_insn > 0);
00913 brw_ENDIF(p, c->if_inst[--c->if_insn]);
00914 break;
00915 case TGSI_OPCODE_BGNSUB:
00916 case TGSI_OPCODE_ENDSUB:
00917 break;
00918 case TGSI_OPCODE_CAL:
00919 brw_push_insn_state(p);
00920 brw_set_mask_control(p, BRW_MASK_DISABLE);
00921 brw_set_access_mode(p, BRW_ALIGN_1);
00922 brw_ADD(p, deref_1ud(c->stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
00923 brw_set_access_mode(p, BRW_ALIGN_16);
00924 brw_ADD(p,
00925 get_addr_reg(c->stack_index),
00926 get_addr_reg(c->stack_index), brw_imm_d(4));
00927
00928
00929 assert(0);
00930 brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
00931 brw_pop_insn_state(p);
00932 break;
00933
00934 case TGSI_OPCODE_RET:
00935 #if 0
00936 brw_push_insn_state(p);
00937 brw_set_mask_control(p, BRW_MASK_DISABLE);
00938 brw_ADD(p,
00939 get_addr_reg(c->stack_index),
00940 get_addr_reg(c->stack_index), brw_imm_d(-4));
00941 brw_set_access_mode(p, BRW_ALIGN_1);
00942 brw_MOV(p, brw_ip_reg(), deref_1ud(c->stack_index, 0));
00943 brw_set_access_mode(p, BRW_ALIGN_16);
00944 brw_pop_insn_state(p);
00945 #else
00946 emit_fb_write(c, inst);
00947 #endif
00948
00949 break;
00950 case TGSI_OPCODE_LOOP:
00951 c->loop_inst[c->loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
00952 break;
00953 case TGSI_OPCODE_BRK:
00954 brw_BREAK(p);
00955 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00956 break;
00957 case TGSI_OPCODE_CONT:
00958 brw_CONT(p);
00959 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00960 break;
00961 case TGSI_OPCODE_ENDLOOP:
00962 c->loop_insn--;
00963 c->inst0 = c->inst1 = brw_WHILE(p, c->loop_inst[c->loop_insn]);
00964
00965
00966 while (c->inst0 > c->loop_inst[c->loop_insn]) {
00967 c->inst0--;
00968 if (c->inst0->header.opcode == BRW_OPCODE_BREAK) {
00969 c->inst0->bits3.if_else.jump_count = c->inst1 - c->inst0 + 1;
00970 c->inst0->bits3.if_else.pop_count = 0;
00971 } else if (c->inst0->header.opcode == BRW_OPCODE_CONTINUE) {
00972 c->inst0->bits3.if_else.jump_count = c->inst1 - c->inst0;
00973 c->inst0->bits3.if_else.pop_count = 0;
00974 }
00975 }
00976 break;
00977 case TGSI_OPCODE_END:
00978 emit_fb_write(c, inst);
00979 break;
00980
00981 default:
00982 debug_printf("unsupported IR in fragment shader %d\n",
00983 inst->Instruction.Opcode);
00984 }
00985 #if 0
00986 if (inst->CondUpdate)
00987 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
00988 else
00989 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
00990 #endif
00991 }
00992
00993
00994
00995
00996
00997
00998 void brw_wm_glsl_emit(struct brw_wm_compile *c)
00999 {
01000 struct tgsi_parse_context parse;
01001 struct brw_compile *p = &c->func;
01002
01003 brw_init_compile(&c->func);
01004 brw_set_compression_control(p, BRW_COMPRESSION_NONE);
01005
01006 c->reg_index = 0;
01007 c->if_insn = 0;
01008 c->loop_insn = 0;
01009 c->stack_index = brw_indirect(0,0);
01010
01011
01012
01013 brw_wm_emit_decls( c );
01014
01015
01016
01017
01018 brw_MOV(p, get_addr_reg(c->stack_index), brw_address(c->stack));
01019
01020 tgsi_parse_init( &parse, c->fp->program.tokens );
01021
01022 while( !tgsi_parse_end_of_tokens( &parse ) )
01023 {
01024 tgsi_parse_token( &parse );
01025
01026 switch( parse.FullToken.Token.Type ) {
01027 case TGSI_TOKEN_TYPE_DECLARATION:
01028
01029 break;
01030
01031 case TGSI_TOKEN_TYPE_IMMEDIATE:
01032
01033 assert(0);
01034 break;
01035
01036 case TGSI_TOKEN_TYPE_INSTRUCTION:
01037 brw_wm_emit_instruction(c, &parse.FullToken.FullInstruction);
01038 break;
01039
01040 default:
01041 assert( 0 );
01042 }
01043 }
01044
01045 tgsi_parse_free (&parse);
01046
01047
01048
01049 #if 0
01050 {
01051 unsigned nr_insns = c->fp->program.Base.NumInstructions;
01052 unsigned insn, target_insn;
01053 struct tgsi_full_instruction *inst1, *inst2;
01054 struct brw_instruction *brw_inst1, *brw_inst2;
01055 int offset;
01056 for (insn = 0; insn < nr_insns; insn++) {
01057 inst1 = &c->fp->program.Base.Instructions[insn];
01058 brw_inst1 = inst1->Data;
01059 switch (inst1->Opcode) {
01060 case TGSI_OPCODE_CAL:
01061 target_insn = inst1->BranchTarget;
01062 inst2 = &c->fp->program.Base.Instructions[target_insn];
01063 brw_inst2 = inst2->Data;
01064 offset = brw_inst2 - brw_inst1;
01065 brw_set_src1(brw_inst1, brw_imm_d(offset*16));
01066 break;
01067 default:
01068 break;
01069 }
01070 }
01071 }
01072 #endif
01073
01074 c->prog_data.total_grf = c->reg_index;
01075 c->prog_data.total_scratch = 0;
01076 }