gallium: move pipe_copy_rect(), pipe_fill_rect() protos into new u_rect.h header
[mesa.git] / src / gallium / drivers / i965simple / brw_wm_glsl.c
1
2 #include "brw_context.h"
3 #include "brw_eu.h"
4 #include "brw_wm.h"
5 #include "pipe/p_util.h"
6 #include "pipe/p_shader_tokens.h"
7 #include "tgsi/tgsi_parse.h"
8
9
10
11 static int get_scalar_dst_index(struct tgsi_full_instruction *inst)
12 {
13 struct tgsi_dst_register dst = inst->FullDstRegisters[0].DstRegister;
14 int i;
15 for (i = 0; i < 4; i++)
16 if (dst.WriteMask & (1<<i))
17 break;
18 return i;
19 }
20
21 static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
22 {
23 c->tmp_index++;
24 c->reg_index = MAX2(c->reg_index, c->tmp_index);
25 return brw_vec8_grf(c->tmp_start + c->tmp_index, 0);
26 }
27
28 static void release_tmps(struct brw_wm_compile *c)
29 {
30 c->tmp_index = 0;
31 }
32
33
34 static struct brw_reg
35 get_reg(struct brw_wm_compile *c, int file, int index, int component )
36 {
37 switch (file) {
38 case TGSI_FILE_NULL:
39 return brw_null_reg();
40
41 case TGSI_FILE_SAMPLER:
42 /* Should never get here:
43 */
44 assert (0);
45 return brw_null_reg();
46
47 case TGSI_FILE_IMMEDIATE:
48 /* These need a different path:
49 */
50 assert(0);
51 return brw_null_reg();
52
53
54 case TGSI_FILE_CONSTANT:
55 case TGSI_FILE_INPUT:
56 case TGSI_FILE_OUTPUT:
57 case TGSI_FILE_TEMPORARY:
58 case TGSI_FILE_ADDRESS:
59 return c->wm_regs[file][index][component];
60
61 default:
62 assert(0);
63 return brw_null_reg();
64 }
65 }
66
67
68 static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
69 struct tgsi_full_instruction *inst,
70 int component)
71 {
72 return get_reg(c,
73 inst->FullDstRegisters[0].DstRegister.File,
74 inst->FullDstRegisters[0].DstRegister.Index,
75 component);
76 }
77
78 static int get_swz( struct tgsi_src_register src, int index )
79 {
80 switch (index & 3) {
81 case 0: return src.SwizzleX;
82 case 1: return src.SwizzleY;
83 case 2: return src.SwizzleZ;
84 case 3: return src.SwizzleW;
85 default: return 0;
86 }
87 }
88
89 static int get_ext_swz( struct tgsi_src_register_ext_swz src, int index )
90 {
91 switch (index & 3) {
92 case 0: return src.ExtSwizzleX;
93 case 1: return src.ExtSwizzleY;
94 case 2: return src.ExtSwizzleZ;
95 case 3: return src.ExtSwizzleW;
96 default: return 0;
97 }
98 }
99
100 static struct brw_reg get_src_reg(struct brw_wm_compile *c,
101 struct tgsi_full_src_register *src,
102 int index)
103 {
104 struct brw_reg reg;
105 int component = index;
106 int neg = 0;
107 int abs = 0;
108
109 if (src->SrcRegister.Negate)
110 neg = 1;
111
112 component = get_swz(src->SrcRegister, component);
113
114 /* Yes, there are multiple negates:
115 */
116 switch (component & 3) {
117 case 0: neg ^= src->SrcRegisterExtSwz.NegateX; break;
118 case 1: neg ^= src->SrcRegisterExtSwz.NegateY; break;
119 case 2: neg ^= src->SrcRegisterExtSwz.NegateZ; break;
120 case 3: neg ^= src->SrcRegisterExtSwz.NegateW; break;
121 }
122
123 /* And multiple swizzles, fun isn't it:
124 */
125 component = get_ext_swz(src->SrcRegisterExtSwz, component);
126
127 /* Not handling indirect lookups yet:
128 */
129 assert(src->SrcRegister.Indirect == 0);
130
131 /* Don't know what dimension means:
132 */
133 assert(src->SrcRegister.Dimension == 0);
134
135 /* Will never handle any of this stuff:
136 */
137 assert(src->SrcRegisterExtMod.Complement == 0);
138 assert(src->SrcRegisterExtMod.Bias == 0);
139 assert(src->SrcRegisterExtMod.Scale2X == 0);
140
141 if (src->SrcRegisterExtMod.Absolute)
142 abs = 1;
143
144 /* Another negate! This is a post-absolute negate, which we
145 * can't do. Need to clean the crap out of tgsi somehow.
146 */
147 assert(src->SrcRegisterExtMod.Negate == 0);
148
149 switch( component ) {
150 case TGSI_EXTSWIZZLE_X:
151 case TGSI_EXTSWIZZLE_Y:
152 case TGSI_EXTSWIZZLE_Z:
153 case TGSI_EXTSWIZZLE_W:
154 reg = get_reg(c,
155 src->SrcRegister.File,
156 src->SrcRegister.Index,
157 component );
158
159 if (neg)
160 reg = negate(reg);
161
162 if (abs)
163 reg = brw_abs(reg);
164
165 break;
166
167 /* XXX: this won't really work in the general case, but we know
168 * that the extended swizzle is only allowed in the SWZ
169 * instruction (right??), in which case using an immediate
170 * directly will work.
171 */
172 case TGSI_EXTSWIZZLE_ZERO:
173 reg = brw_imm_f(0);
174 break;
175
176 case TGSI_EXTSWIZZLE_ONE:
177 if (neg && !abs)
178 reg = brw_imm_f(-1.0);
179 else
180 reg = brw_imm_f(1.0);
181 break;
182
183 default:
184 assert(0);
185 break;
186 }
187
188
189 return reg;
190 }
191
192 static void emit_abs( struct brw_wm_compile *c,
193 struct tgsi_full_instruction *inst)
194 {
195 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
196
197 int i;
198 struct brw_compile *p = &c->func;
199 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
200 for (i = 0; i < 4; i++) {
201 if (mask & (1<<i)) {
202 struct brw_reg src, dst;
203 dst = get_dst_reg(c, inst, i);
204 src = get_src_reg(c, &inst->FullSrcRegisters[0], i);
205 brw_MOV(p, dst, brw_abs(src)); /* NOTE */
206 }
207 }
208 brw_set_saturate(p, 0);
209 }
210
211
212 static void emit_xpd(struct brw_wm_compile *c,
213 struct tgsi_full_instruction *inst)
214 {
215 int i;
216 struct brw_compile *p = &c->func;
217 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
218 for (i = 0; i < 4; i++) {
219 unsigned i2 = (i+2)%3;
220 unsigned i1 = (i+1)%3;
221 if (mask & (1<<i)) {
222 struct brw_reg src0, src1, dst;
223 dst = get_dst_reg(c, inst, i);
224 src0 = negate(get_src_reg(c, &inst->FullSrcRegisters[0], i2));
225 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i1);
226 brw_MUL(p, brw_null_reg(), src0, src1);
227 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i1);
228 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i2);
229 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
230 brw_MAC(p, dst, src0, src1);
231 brw_set_saturate(p, 0);
232 }
233 }
234 brw_set_saturate(p, 0);
235 }
236
237 static void emit_dp3(struct brw_wm_compile *c,
238 struct tgsi_full_instruction *inst)
239 {
240 struct brw_reg src0[3], src1[3], dst;
241 int i;
242 struct brw_compile *p = &c->func;
243 for (i = 0; i < 3; i++) {
244 src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
245 src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i);
246 }
247
248 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
249 brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
250 brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
251 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
252 brw_MAC(p, dst, src0[2], src1[2]);
253 brw_set_saturate(p, 0);
254 }
255
256 static void emit_dp4(struct brw_wm_compile *c,
257 struct tgsi_full_instruction *inst)
258 {
259 struct brw_reg src0[4], src1[4], dst;
260 int i;
261 struct brw_compile *p = &c->func;
262 for (i = 0; i < 4; i++) {
263 src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
264 src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i);
265 }
266 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
267 brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
268 brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
269 brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
270 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
271 brw_MAC(p, dst, src0[3], src1[3]);
272 brw_set_saturate(p, 0);
273 }
274
275 static void emit_dph(struct brw_wm_compile *c,
276 struct tgsi_full_instruction *inst)
277 {
278 struct brw_reg src0[4], src1[4], dst;
279 int i;
280 struct brw_compile *p = &c->func;
281 for (i = 0; i < 4; i++) {
282 src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
283 src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i);
284 }
285 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
286 brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
287 brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
288 brw_MAC(p, dst, src0[2], src1[2]);
289 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
290 brw_ADD(p, dst, src0[3], src1[3]);
291 brw_set_saturate(p, 0);
292 }
293
294 static void emit_math1(struct brw_wm_compile *c,
295 struct tgsi_full_instruction *inst, unsigned func)
296 {
297 struct brw_compile *p = &c->func;
298 struct brw_reg src0, dst;
299
300 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
301 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
302 brw_MOV(p, brw_message_reg(2), src0);
303 brw_math(p,
304 dst,
305 func,
306 ((inst->Instruction.Saturate != TGSI_SAT_NONE)
307 ? BRW_MATH_SATURATE_SATURATE
308 : BRW_MATH_SATURATE_NONE),
309 2,
310 brw_null_reg(),
311 BRW_MATH_DATA_VECTOR,
312 BRW_MATH_PRECISION_FULL);
313 }
314
315
316 static void emit_alu2(struct brw_wm_compile *c,
317 struct tgsi_full_instruction *inst,
318 unsigned opcode)
319 {
320 struct brw_compile *p = &c->func;
321 struct brw_reg src0, src1, dst;
322 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
323 int i;
324 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
325 for (i = 0 ; i < 4; i++) {
326 if (mask & (1<<i)) {
327 dst = get_dst_reg(c, inst, i);
328 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
329 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
330 brw_alu2(p, opcode, dst, src0, src1);
331 }
332 }
333 brw_set_saturate(p, 0);
334 }
335
336
337 static void emit_alu1(struct brw_wm_compile *c,
338 struct tgsi_full_instruction *inst,
339 unsigned opcode)
340 {
341 struct brw_compile *p = &c->func;
342 struct brw_reg src0, dst;
343 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
344 int i;
345 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
346 for (i = 0 ; i < 4; i++) {
347 if (mask & (1<<i)) {
348 dst = get_dst_reg(c, inst, i);
349 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
350 brw_alu1(p, opcode, dst, src0);
351 }
352 }
353 if (inst->Instruction.Saturate != TGSI_SAT_NONE)
354 brw_set_saturate(p, 0);
355 }
356
357
358 static void emit_max(struct brw_wm_compile *c,
359 struct tgsi_full_instruction *inst)
360 {
361 struct brw_compile *p = &c->func;
362 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
363 struct brw_reg src0, src1, dst;
364 int i;
365 brw_push_insn_state(p);
366 for (i = 0; i < 4; i++) {
367 if (mask & (1<<i)) {
368 dst = get_dst_reg(c, inst, i);
369 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
370 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
371 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
372 brw_MOV(p, dst, src0);
373 brw_set_saturate(p, 0);
374
375 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src0, src1);
376 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
377 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
378 brw_MOV(p, dst, src1);
379 brw_set_saturate(p, 0);
380 brw_set_predicate_control_flag_value(p, 0xff);
381 }
382 }
383 brw_pop_insn_state(p);
384 }
385
386 static void emit_min(struct brw_wm_compile *c,
387 struct tgsi_full_instruction *inst)
388 {
389 struct brw_compile *p = &c->func;
390 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
391 struct brw_reg src0, src1, dst;
392 int i;
393 brw_push_insn_state(p);
394 for (i = 0; i < 4; i++) {
395 if (mask & (1<<i)) {
396 dst = get_dst_reg(c, inst, i);
397 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
398 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
399 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
400 brw_MOV(p, dst, src0);
401 brw_set_saturate(p, 0);
402
403 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0);
404 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
405 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
406 brw_MOV(p, dst, src1);
407 brw_set_saturate(p, 0);
408 brw_set_predicate_control_flag_value(p, 0xff);
409 }
410 }
411 brw_pop_insn_state(p);
412 }
413
414 static void emit_pow(struct brw_wm_compile *c,
415 struct tgsi_full_instruction *inst)
416 {
417 struct brw_compile *p = &c->func;
418 struct brw_reg dst, src0, src1;
419 dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
420 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
421 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], 0);
422
423 brw_MOV(p, brw_message_reg(2), src0);
424 brw_MOV(p, brw_message_reg(3), src1);
425
426 brw_math(p,
427 dst,
428 BRW_MATH_FUNCTION_POW,
429 (inst->Instruction.Saturate != TGSI_SAT_NONE
430 ? BRW_MATH_SATURATE_SATURATE
431 : BRW_MATH_SATURATE_NONE),
432 2,
433 brw_null_reg(),
434 BRW_MATH_DATA_VECTOR,
435 BRW_MATH_PRECISION_FULL);
436 }
437
438 static void emit_lrp(struct brw_wm_compile *c,
439 struct tgsi_full_instruction *inst)
440 {
441 struct brw_compile *p = &c->func;
442 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
443 struct brw_reg dst, tmp1, tmp2, src0, src1, src2;
444 int i;
445 for (i = 0; i < 4; i++) {
446 if (mask & (1<<i)) {
447 dst = get_dst_reg(c, inst, i);
448 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
449
450 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
451
452 if (src1.nr == dst.nr) {
453 tmp1 = alloc_tmp(c);
454 brw_MOV(p, tmp1, src1);
455 } else
456 tmp1 = src1;
457
458 src2 = get_src_reg(c, &inst->FullSrcRegisters[2], i);
459 if (src2.nr == dst.nr) {
460 tmp2 = alloc_tmp(c);
461 brw_MOV(p, tmp2, src2);
462 } else
463 tmp2 = src2;
464
465 brw_ADD(p, dst, negate(src0), brw_imm_f(1.0));
466 brw_MUL(p, brw_null_reg(), dst, tmp2);
467 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
468 brw_MAC(p, dst, src0, tmp1);
469 brw_set_saturate(p, 0);
470 }
471 release_tmps(c);
472 }
473 }
474
475 static void emit_kil(struct brw_wm_compile *c)
476 {
477 struct brw_compile *p = &c->func;
478 struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
479 brw_push_insn_state(p);
480 brw_set_mask_control(p, BRW_MASK_DISABLE);
481 brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
482 brw_AND(p, depth, c->emit_mask_reg, depth);
483 brw_pop_insn_state(p);
484 }
485
486 static void emit_mad(struct brw_wm_compile *c,
487 struct tgsi_full_instruction *inst)
488 {
489 struct brw_compile *p = &c->func;
490 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
491 struct brw_reg dst, src0, src1, src2;
492 int i;
493
494 for (i = 0; i < 4; i++) {
495 if (mask & (1<<i)) {
496 dst = get_dst_reg(c, inst, i);
497 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
498 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
499 src2 = get_src_reg(c, &inst->FullSrcRegisters[2], i);
500 brw_MUL(p, dst, src0, src1);
501
502 brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0);
503 brw_ADD(p, dst, dst, src2);
504 brw_set_saturate(p, 0);
505 }
506 }
507 }
508
509 static void emit_sop(struct brw_wm_compile *c,
510 struct tgsi_full_instruction *inst, unsigned cond)
511 {
512 struct brw_compile *p = &c->func;
513 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
514 struct brw_reg dst, src0, src1;
515 int i;
516
517 brw_push_insn_state(p);
518 for (i = 0; i < 4; i++) {
519 if (mask & (1<<i)) {
520 dst = get_dst_reg(c, inst, i);
521 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i);
522 src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i);
523 brw_CMP(p, brw_null_reg(), cond, src0, src1);
524 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
525 brw_MOV(p, dst, brw_imm_f(0.0));
526 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
527 brw_MOV(p, dst, brw_imm_f(1.0));
528 }
529 }
530 brw_pop_insn_state(p);
531 }
532
533
534 static void emit_ddx(struct brw_wm_compile *c,
535 struct tgsi_full_instruction *inst)
536 {
537 struct brw_compile *p = &c->func;
538 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
539 struct brw_reg interp[4];
540 struct brw_reg dst;
541 struct brw_reg src0, w;
542 unsigned nr, i;
543 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
544 w = get_src_reg(c, &inst->FullSrcRegisters[1], 3);
545 nr = src0.nr;
546 interp[0] = brw_vec1_grf(nr, 0);
547 interp[1] = brw_vec1_grf(nr, 4);
548 interp[2] = brw_vec1_grf(nr+1, 0);
549 interp[3] = brw_vec1_grf(nr+1, 4);
550 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
551 for(i = 0; i < 4; i++ ) {
552 if (mask & (1<<i)) {
553 dst = get_dst_reg(c, inst, i);
554 brw_MOV(p, dst, interp[i]);
555 brw_MUL(p, dst, dst, w);
556 }
557 }
558 brw_set_saturate(p, 0);
559 }
560
561 static void emit_ddy(struct brw_wm_compile *c,
562 struct tgsi_full_instruction *inst)
563 {
564 struct brw_compile *p = &c->func;
565 unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
566 struct brw_reg interp[4];
567 struct brw_reg dst;
568 struct brw_reg src0, w;
569 unsigned nr, i;
570
571 src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0);
572 nr = src0.nr;
573 w = get_src_reg(c, &inst->FullSrcRegisters[1], 3);
574 interp[0] = brw_vec1_grf(nr, 0);
575 interp[1] = brw_vec1_grf(nr, 4);
576 interp[2] = brw_vec1_grf(nr+1, 0);
577 interp[3] = brw_vec1_grf(nr+1, 4);
578 brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE);
579 for(i = 0; i < 4; i++ ) {
580 if (mask & (1<<i)) {
581 dst = get_dst_reg(c, inst, i);
582 brw_MOV(p, dst, suboffset(interp[i], 1));
583 brw_MUL(p, dst, dst, w);
584 }
585 }
586 brw_set_saturate(p, 0);
587 }
588
589 /* TODO
590 BIAS on SIMD8 not workind yet...
591 */
592 static void emit_txb(struct brw_wm_compile *c,
593 struct tgsi_full_instruction *inst)
594 {
595 #if 0
596 struct brw_compile *p = &c->func;
597 struct brw_reg payload_reg = c->payload_depth[0];
598 struct brw_reg dst[4], src[4];
599 unsigned i;
600 for (i = 0; i < 4; i++)
601 dst[i] = get_dst_reg(c, inst, i);
602 for (i = 0; i < 4; i++)
603 src[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
604
605 #if 0
606 switch (inst->TexSrcTarget) {
607 case TEXTURE_1D_INDEX:
608 brw_MOV(p, brw_message_reg(2), src[0]);
609 brw_MOV(p, brw_message_reg(3), brw_imm_f(0));
610 brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
611 break;
612 case TEXTURE_2D_INDEX:
613 case TEXTURE_RECT_INDEX:
614 brw_MOV(p, brw_message_reg(2), src[0]);
615 brw_MOV(p, brw_message_reg(3), src[1]);
616 brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
617 break;
618 default:
619 brw_MOV(p, brw_message_reg(2), src[0]);
620 brw_MOV(p, brw_message_reg(3), src[1]);
621 brw_MOV(p, brw_message_reg(4), src[2]);
622 break;
623 }
624 #else
625 brw_MOV(p, brw_message_reg(2), src[0]);
626 brw_MOV(p, brw_message_reg(3), src[1]);
627 brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
628 #endif
629
630 brw_MOV(p, brw_message_reg(5), src[3]);
631 brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
632 brw_SAMPLE(p,
633 retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
634 1,
635 retype(payload_reg, BRW_REGISTER_TYPE_UW),
636 inst->TexSrcUnit + 1, /* surface */
637 inst->TexSrcUnit, /* sampler */
638 inst->FullDstRegisters[0].DstRegister.WriteMask,
639 BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
640 4,
641 4,
642 0);
643 #endif
644 }
645
646 static void emit_tex(struct brw_wm_compile *c,
647 struct tgsi_full_instruction *inst)
648 {
649 #if 0
650 struct brw_compile *p = &c->func;
651 struct brw_reg payload_reg = c->payload_depth[0];
652 struct brw_reg dst[4], src[4];
653 unsigned msg_len;
654 unsigned i, nr;
655 unsigned emit;
656 boolean shadow = (c->key.shadowtex_mask & (1<<inst->TexSrcUnit)) ? 1 : 0;
657
658 for (i = 0; i < 4; i++)
659 dst[i] = get_dst_reg(c, inst, i);
660 for (i = 0; i < 4; i++)
661 src[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i);
662
663 #if 0
664 switch (inst->TexSrcTarget) {
665 case TEXTURE_1D_INDEX:
666 emit = WRITEMASK_X;
667 nr = 1;
668 break;
669 case TEXTURE_2D_INDEX:
670 case TEXTURE_RECT_INDEX:
671 emit = WRITEMASK_XY;
672 nr = 2;
673 break;
674 default:
675 emit = WRITEMASK_XYZ;
676 nr = 3;
677 break;
678 }
679 #else
680 emit = WRITEMASK_XY;
681 nr = 2;
682 #endif
683
684 msg_len = 1;
685
686 for (i = 0; i < nr; i++) {
687 static const unsigned swz[4] = {0,1,2,2};
688 if (emit & (1<<i))
689 brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
690 else
691 brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
692 msg_len += 1;
693 }
694
695 if (shadow) {
696 brw_MOV(p, brw_message_reg(5), brw_imm_f(0));
697 brw_MOV(p, brw_message_reg(6), src[2]);
698 }
699
700 brw_SAMPLE(p,
701 retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
702 1,
703 retype(payload_reg, BRW_REGISTER_TYPE_UW),
704 inst->TexSrcUnit + 1, /* surface */
705 inst->TexSrcUnit, /* sampler */
706 inst->FullDstRegisters[0].DstRegister.WriteMask,
707 BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
708 4,
709 shadow ? 6 : 4,
710 0);
711
712 if (shadow)
713 brw_MOV(p, dst[3], brw_imm_f(1.0));
714 #endif
715 }
716
717
718
719
720
721
722
723
724 static void emit_fb_write(struct brw_wm_compile *c,
725 struct tgsi_full_instruction *inst)
726 {
727 struct brw_compile *p = &c->func;
728 int nr = 2;
729 int channel;
730 int base_reg = 0;
731
732 // src0 = output color
733 // src1 = payload_depth[0]
734 // src2 = output depth
735 // dst = ???
736
737
738
739 /* Reserve a space for AA - may not be needed:
740 */
741 if (c->key.aa_dest_stencil_reg)
742 nr += 1;
743
744 {
745 brw_push_insn_state(p);
746 for (channel = 0; channel < 4; channel++) {
747 struct brw_reg src0 = c->wm_regs[TGSI_FILE_OUTPUT][0][channel];
748
749 /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */
750 /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */
751 brw_MOV(p, brw_message_reg(nr + channel), src0);
752 }
753 /* skip over the regs populated above: */
754 nr += 8;
755 brw_pop_insn_state(p);
756 }
757
758
759 /* Pass through control information:
760 */
761 /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */
762 {
763 brw_push_insn_state(p);
764 brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
765 brw_MOV(p,
766 brw_message_reg(base_reg + 1),
767 brw_vec8_grf(1, 0));
768 brw_pop_insn_state(p);
769 }
770
771 /* Send framebuffer write message: */
772 brw_fb_WRITE(p,
773 retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
774 base_reg,
775 retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
776 0, /* render surface always 0 */
777 nr,
778 0,
779 1);
780
781 }
782
783
784 static void brw_wm_emit_instruction( struct brw_wm_compile *c,
785 struct tgsi_full_instruction *inst )
786 {
787 struct brw_compile *p = &c->func;
788
789 #if 0
790 if (inst->CondUpdate)
791 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
792 else
793 brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
794 #else
795 brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
796 #endif
797
798 switch (inst->Instruction.Opcode) {
799 case TGSI_OPCODE_ABS:
800 emit_abs(c, inst);
801 break;
802 case TGSI_OPCODE_ADD:
803 emit_alu2(c, inst, BRW_OPCODE_ADD);
804 break;
805 case TGSI_OPCODE_SUB:
806 assert(0);
807 // emit_alu2(c, inst, BRW_OPCODE_SUB);
808 break;
809 case TGSI_OPCODE_FRC:
810 emit_alu1(c, inst, BRW_OPCODE_FRC);
811 break;
812 case TGSI_OPCODE_FLR:
813 assert(0);
814 // emit_alu1(c, inst, BRW_OPCODE_FLR);
815 break;
816 case TGSI_OPCODE_LRP:
817 emit_lrp(c, inst);
818 break;
819 case TGSI_OPCODE_INT:
820 emit_alu1(c, inst, BRW_OPCODE_RNDD);
821 break;
822 case TGSI_OPCODE_MOV:
823 emit_alu1(c, inst, BRW_OPCODE_MOV);
824 break;
825 case TGSI_OPCODE_DP3:
826 emit_dp3(c, inst);
827 break;
828 case TGSI_OPCODE_DP4:
829 emit_dp4(c, inst);
830 break;
831 case TGSI_OPCODE_XPD:
832 emit_xpd(c, inst);
833 break;
834 case TGSI_OPCODE_DPH:
835 emit_dph(c, inst);
836 break;
837 case TGSI_OPCODE_RCP:
838 emit_math1(c, inst, BRW_MATH_FUNCTION_INV);
839 break;
840 case TGSI_OPCODE_RSQ:
841 emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ);
842 break;
843 case TGSI_OPCODE_SIN:
844 emit_math1(c, inst, BRW_MATH_FUNCTION_SIN);
845 break;
846 case TGSI_OPCODE_COS:
847 emit_math1(c, inst, BRW_MATH_FUNCTION_COS);
848 break;
849 case TGSI_OPCODE_EX2:
850 emit_math1(c, inst, BRW_MATH_FUNCTION_EXP);
851 break;
852 case TGSI_OPCODE_LG2:
853 emit_math1(c, inst, BRW_MATH_FUNCTION_LOG);
854 break;
855 case TGSI_OPCODE_MAX:
856 emit_max(c, inst);
857 break;
858 case TGSI_OPCODE_MIN:
859 emit_min(c, inst);
860 break;
861 case TGSI_OPCODE_DDX:
862 emit_ddx(c, inst);
863 break;
864 case TGSI_OPCODE_DDY:
865 emit_ddy(c, inst);
866 break;
867 case TGSI_OPCODE_SLT:
868 emit_sop(c, inst, BRW_CONDITIONAL_L);
869 break;
870 case TGSI_OPCODE_SLE:
871 emit_sop(c, inst, BRW_CONDITIONAL_LE);
872 break;
873 case TGSI_OPCODE_SGT:
874 emit_sop(c, inst, BRW_CONDITIONAL_G);
875 break;
876 case TGSI_OPCODE_SGE:
877 emit_sop(c, inst, BRW_CONDITIONAL_GE);
878 break;
879 case TGSI_OPCODE_SEQ:
880 emit_sop(c, inst, BRW_CONDITIONAL_EQ);
881 break;
882 case TGSI_OPCODE_SNE:
883 emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
884 break;
885 case TGSI_OPCODE_MUL:
886 emit_alu2(c, inst, BRW_OPCODE_MUL);
887 break;
888 case TGSI_OPCODE_POW:
889 emit_pow(c, inst);
890 break;
891 case TGSI_OPCODE_MAD:
892 emit_mad(c, inst);
893 break;
894 case TGSI_OPCODE_TEX:
895 emit_tex(c, inst);
896 break;
897 case TGSI_OPCODE_TXB:
898 emit_txb(c, inst);
899 break;
900 case TGSI_OPCODE_TEXKILL:
901 emit_kil(c);
902 break;
903 case TGSI_OPCODE_IF:
904 assert(c->if_insn < MAX_IFSN);
905 c->if_inst[c->if_insn++] = brw_IF(p, BRW_EXECUTE_8);
906 break;
907 case TGSI_OPCODE_ELSE:
908 c->if_inst[c->if_insn-1] = brw_ELSE(p, c->if_inst[c->if_insn-1]);
909 break;
910 case TGSI_OPCODE_ENDIF:
911 assert(c->if_insn > 0);
912 brw_ENDIF(p, c->if_inst[--c->if_insn]);
913 break;
914 case TGSI_OPCODE_BGNSUB:
915 case TGSI_OPCODE_ENDSUB:
916 break;
917 case TGSI_OPCODE_CAL:
918 brw_push_insn_state(p);
919 brw_set_mask_control(p, BRW_MASK_DISABLE);
920 brw_set_access_mode(p, BRW_ALIGN_1);
921 brw_ADD(p, deref_1ud(c->stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
922 brw_set_access_mode(p, BRW_ALIGN_16);
923 brw_ADD(p,
924 get_addr_reg(c->stack_index),
925 get_addr_reg(c->stack_index), brw_imm_d(4));
926 // orig_inst = inst->Data;
927 // orig_inst->Data = &p->store[p->nr_insn];
928 assert(0);
929 brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
930 brw_pop_insn_state(p);
931 break;
932
933 case TGSI_OPCODE_RET:
934 #if 0
935 brw_push_insn_state(p);
936 brw_set_mask_control(p, BRW_MASK_DISABLE);
937 brw_ADD(p,
938 get_addr_reg(c->stack_index),
939 get_addr_reg(c->stack_index), brw_imm_d(-4));
940 brw_set_access_mode(p, BRW_ALIGN_1);
941 brw_MOV(p, brw_ip_reg(), deref_1ud(c->stack_index, 0));
942 brw_set_access_mode(p, BRW_ALIGN_16);
943 brw_pop_insn_state(p);
944 #else
945 emit_fb_write(c, inst);
946 #endif
947
948 break;
949 case TGSI_OPCODE_LOOP:
950 c->loop_inst[c->loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
951 break;
952 case TGSI_OPCODE_BRK:
953 brw_BREAK(p);
954 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
955 break;
956 case TGSI_OPCODE_CONT:
957 brw_CONT(p);
958 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
959 break;
960 case TGSI_OPCODE_ENDLOOP:
961 c->loop_insn--;
962 c->inst0 = c->inst1 = brw_WHILE(p, c->loop_inst[c->loop_insn]);
963 /* patch all the BREAK instructions from
964 last BEGINLOOP */
965 while (c->inst0 > c->loop_inst[c->loop_insn]) {
966 c->inst0--;
967 if (c->inst0->header.opcode == BRW_OPCODE_BREAK) {
968 c->inst0->bits3.if_else.jump_count = c->inst1 - c->inst0 + 1;
969 c->inst0->bits3.if_else.pop_count = 0;
970 } else if (c->inst0->header.opcode == BRW_OPCODE_CONTINUE) {
971 c->inst0->bits3.if_else.jump_count = c->inst1 - c->inst0;
972 c->inst0->bits3.if_else.pop_count = 0;
973 }
974 }
975 break;
976 case TGSI_OPCODE_END:
977 emit_fb_write(c, inst);
978 break;
979
980 default:
981 debug_printf("unsupported IR in fragment shader %d\n",
982 inst->Instruction.Opcode);
983 }
984 #if 0
985 if (inst->CondUpdate)
986 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
987 else
988 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
989 #endif
990 }
991
992
993
994
995
996
997 void brw_wm_glsl_emit(struct brw_wm_compile *c)
998 {
999 struct tgsi_parse_context parse;
1000 struct brw_compile *p = &c->func;
1001
1002 brw_init_compile(&c->func);
1003 brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1004
1005 c->reg_index = 0;
1006 c->if_insn = 0;
1007 c->loop_insn = 0;
1008 c->stack_index = brw_indirect(0,0);
1009
1010 /* Do static register allocation and parameter interpolation:
1011 */
1012 brw_wm_emit_decls( c );
1013
1014 /* Emit the actual program. All done with very direct translation,
1015 * hopefully we can improve on this shortly...
1016 */
1017 brw_MOV(p, get_addr_reg(c->stack_index), brw_address(c->stack));
1018
1019 tgsi_parse_init( &parse, c->fp->program.tokens );
1020
1021 while( !tgsi_parse_end_of_tokens( &parse ) )
1022 {
1023 tgsi_parse_token( &parse );
1024
1025 switch( parse.FullToken.Token.Type ) {
1026 case TGSI_TOKEN_TYPE_DECLARATION:
1027 /* already done */
1028 break;
1029
1030 case TGSI_TOKEN_TYPE_IMMEDIATE:
1031 /* not handled yet */
1032 assert(0);
1033 break;
1034
1035 case TGSI_TOKEN_TYPE_INSTRUCTION:
1036 brw_wm_emit_instruction(c, &parse.FullToken.FullInstruction);
1037 break;
1038
1039 default:
1040 assert( 0 );
1041 }
1042 }
1043
1044 tgsi_parse_free (&parse);
1045
1046 /* Fix up call targets:
1047 */
1048 #if 0
1049 {
1050 unsigned nr_insns = c->fp->program.Base.NumInstructions;
1051 unsigned insn, target_insn;
1052 struct tgsi_full_instruction *inst1, *inst2;
1053 struct brw_instruction *brw_inst1, *brw_inst2;
1054 int offset;
1055 for (insn = 0; insn < nr_insns; insn++) {
1056 inst1 = &c->fp->program.Base.Instructions[insn];
1057 brw_inst1 = inst1->Data;
1058 switch (inst1->Opcode) {
1059 case TGSI_OPCODE_CAL:
1060 target_insn = inst1->BranchTarget;
1061 inst2 = &c->fp->program.Base.Instructions[target_insn];
1062 brw_inst2 = inst2->Data;
1063 offset = brw_inst2 - brw_inst1;
1064 brw_set_src1(brw_inst1, brw_imm_d(offset*16));
1065 break;
1066 default:
1067 break;
1068 }
1069 }
1070 }
1071 #endif
1072
1073 c->prog_data.total_grf = c->reg_index;
1074 c->prog_data.total_scratch = 0;
1075 }