2 #include "brw_context.h"
5 #include "pipe/p_util.h"
6 #include "pipe/p_shader_tokens.h"
7 #include "tgsi/tgsi_parse.h"
11 static int get_scalar_dst_index(struct tgsi_full_instruction
*inst
)
13 struct tgsi_dst_register dst
= inst
->FullDstRegisters
[0].DstRegister
;
15 for (i
= 0; i
< 4; i
++)
16 if (dst
.WriteMask
& (1<<i
))
21 static struct brw_reg
alloc_tmp(struct brw_wm_compile
*c
)
24 c
->reg_index
= MAX2(c
->reg_index
, c
->tmp_index
);
25 return brw_vec8_grf(c
->tmp_start
+ c
->tmp_index
, 0);
28 static void release_tmps(struct brw_wm_compile
*c
)
35 get_reg(struct brw_wm_compile
*c
, int file
, int index
, int component
)
39 return brw_null_reg();
41 case TGSI_FILE_SAMPLER
:
42 /* Should never get here:
45 return brw_null_reg();
47 case TGSI_FILE_IMMEDIATE
:
48 /* These need a different path:
51 return brw_null_reg();
54 case TGSI_FILE_CONSTANT
:
56 case TGSI_FILE_OUTPUT
:
57 case TGSI_FILE_TEMPORARY
:
58 case TGSI_FILE_ADDRESS
:
59 return c
->wm_regs
[file
][index
][component
];
63 return brw_null_reg();
68 static struct brw_reg
get_dst_reg(struct brw_wm_compile
*c
,
69 struct tgsi_full_instruction
*inst
,
73 inst
->FullDstRegisters
[0].DstRegister
.File
,
74 inst
->FullDstRegisters
[0].DstRegister
.Index
,
78 static int get_swz( struct tgsi_src_register src
, int index
)
81 case 0: return src
.SwizzleX
;
82 case 1: return src
.SwizzleY
;
83 case 2: return src
.SwizzleZ
;
84 case 3: return src
.SwizzleW
;
89 static int get_ext_swz( struct tgsi_src_register_ext_swz src
, int index
)
92 case 0: return src
.ExtSwizzleX
;
93 case 1: return src
.ExtSwizzleY
;
94 case 2: return src
.ExtSwizzleZ
;
95 case 3: return src
.ExtSwizzleW
;
100 static struct brw_reg
get_src_reg(struct brw_wm_compile
*c
,
101 struct tgsi_full_src_register
*src
,
105 int component
= index
;
109 if (src
->SrcRegister
.Negate
)
112 component
= get_swz(src
->SrcRegister
, component
);
114 /* Yes, there are multiple negates:
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;
123 /* And multiple swizzles, fun isn't it:
125 component
= get_ext_swz(src
->SrcRegisterExtSwz
, component
);
127 /* Not handling indirect lookups yet:
129 assert(src
->SrcRegister
.Indirect
== 0);
131 /* Don't know what dimension means:
133 assert(src
->SrcRegister
.Dimension
== 0);
135 /* Will never handle any of this stuff:
137 assert(src
->SrcRegisterExtMod
.Complement
== 0);
138 assert(src
->SrcRegisterExtMod
.Bias
== 0);
139 assert(src
->SrcRegisterExtMod
.Scale2X
== 0);
141 if (src
->SrcRegisterExtMod
.Absolute
)
144 /* Another negate! This is a post-absolute negate, which we
145 * can't do. Need to clean the crap out of tgsi somehow.
147 assert(src
->SrcRegisterExtMod
.Negate
== 0);
149 switch( component
) {
150 case TGSI_EXTSWIZZLE_X
:
151 case TGSI_EXTSWIZZLE_Y
:
152 case TGSI_EXTSWIZZLE_Z
:
153 case TGSI_EXTSWIZZLE_W
:
155 src
->SrcRegister
.File
,
156 src
->SrcRegister
.Index
,
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.
172 case TGSI_EXTSWIZZLE_ZERO
:
176 case TGSI_EXTSWIZZLE_ONE
:
178 reg
= brw_imm_f(-1.0);
180 reg
= brw_imm_f(1.0);
192 static void emit_abs( struct brw_wm_compile
*c
,
193 struct tgsi_full_instruction
*inst
)
195 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
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
++) {
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 */
208 brw_set_saturate(p
, 0);
212 static void emit_xpd(struct brw_wm_compile
*c
,
213 struct tgsi_full_instruction
*inst
)
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;
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);
234 brw_set_saturate(p
, 0);
237 static void emit_dp3(struct brw_wm_compile
*c
,
238 struct tgsi_full_instruction
*inst
)
240 struct brw_reg src0
[3], src1
[3], dst
;
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
);
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);
256 static void emit_dp4(struct brw_wm_compile
*c
,
257 struct tgsi_full_instruction
*inst
)
259 struct brw_reg src0
[4], src1
[4], dst
;
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
);
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);
275 static void emit_dph(struct brw_wm_compile
*c
,
276 struct tgsi_full_instruction
*inst
)
278 struct brw_reg src0
[4], src1
[4], dst
;
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
);
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);
294 static void emit_math1(struct brw_wm_compile
*c
,
295 struct tgsi_full_instruction
*inst
, unsigned func
)
297 struct brw_compile
*p
= &c
->func
;
298 struct brw_reg src0
, dst
;
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
);
306 ((inst
->Instruction
.Saturate
!= TGSI_SAT_NONE
)
307 ? BRW_MATH_SATURATE_SATURATE
308 : BRW_MATH_SATURATE_NONE
),
311 BRW_MATH_DATA_VECTOR
,
312 BRW_MATH_PRECISION_FULL
);
316 static void emit_alu2(struct brw_wm_compile
*c
,
317 struct tgsi_full_instruction
*inst
,
320 struct brw_compile
*p
= &c
->func
;
321 struct brw_reg src0
, src1
, dst
;
322 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
324 brw_set_saturate(p
, (inst
->Instruction
.Saturate
!= TGSI_SAT_NONE
) ? 1 : 0);
325 for (i
= 0 ; i
< 4; 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
);
333 brw_set_saturate(p
, 0);
337 static void emit_alu1(struct brw_wm_compile
*c
,
338 struct tgsi_full_instruction
*inst
,
341 struct brw_compile
*p
= &c
->func
;
342 struct brw_reg src0
, dst
;
343 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
345 brw_set_saturate(p
, (inst
->Instruction
.Saturate
!= TGSI_SAT_NONE
) ? 1 : 0);
346 for (i
= 0 ; i
< 4; 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
);
353 if (inst
->Instruction
.Saturate
!= TGSI_SAT_NONE
)
354 brw_set_saturate(p
, 0);
358 static void emit_max(struct brw_wm_compile
*c
,
359 struct tgsi_full_instruction
*inst
)
361 struct brw_compile
*p
= &c
->func
;
362 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
363 struct brw_reg src0
, src1
, dst
;
365 brw_push_insn_state(p
);
366 for (i
= 0; i
< 4; 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);
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);
383 brw_pop_insn_state(p
);
386 static void emit_min(struct brw_wm_compile
*c
,
387 struct tgsi_full_instruction
*inst
)
389 struct brw_compile
*p
= &c
->func
;
390 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
391 struct brw_reg src0
, src1
, dst
;
393 brw_push_insn_state(p
);
394 for (i
= 0; i
< 4; 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);
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);
411 brw_pop_insn_state(p
);
414 static void emit_pow(struct brw_wm_compile
*c
,
415 struct tgsi_full_instruction
*inst
)
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);
423 brw_MOV(p
, brw_message_reg(2), src0
);
424 brw_MOV(p
, brw_message_reg(3), src1
);
428 BRW_MATH_FUNCTION_POW
,
429 (inst
->Instruction
.Saturate
!= TGSI_SAT_NONE
430 ? BRW_MATH_SATURATE_SATURATE
431 : BRW_MATH_SATURATE_NONE
),
434 BRW_MATH_DATA_VECTOR
,
435 BRW_MATH_PRECISION_FULL
);
438 static void emit_lrp(struct brw_wm_compile
*c
,
439 struct tgsi_full_instruction
*inst
)
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
;
445 for (i
= 0; i
< 4; i
++) {
447 dst
= get_dst_reg(c
, inst
, i
);
448 src0
= get_src_reg(c
, &inst
->FullSrcRegisters
[0], i
);
450 src1
= get_src_reg(c
, &inst
->FullSrcRegisters
[1], i
);
452 if (src1
.nr
== dst
.nr
) {
454 brw_MOV(p
, tmp1
, src1
);
458 src2
= get_src_reg(c
, &inst
->FullSrcRegisters
[2], i
);
459 if (src2
.nr
== dst
.nr
) {
461 brw_MOV(p
, tmp2
, src2
);
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);
475 static void emit_kil(struct brw_wm_compile
*c
)
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
);
486 static void emit_mad(struct brw_wm_compile
*c
,
487 struct tgsi_full_instruction
*inst
)
489 struct brw_compile
*p
= &c
->func
;
490 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
491 struct brw_reg dst
, src0
, src1
, src2
;
494 for (i
= 0; i
< 4; 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
);
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);
509 static void emit_sop(struct brw_wm_compile
*c
,
510 struct tgsi_full_instruction
*inst
, unsigned cond
)
512 struct brw_compile
*p
= &c
->func
;
513 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
514 struct brw_reg dst
, src0
, src1
;
517 brw_push_insn_state(p
);
518 for (i
= 0; i
< 4; 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));
530 brw_pop_insn_state(p
);
534 static void emit_ddx(struct brw_wm_compile
*c
,
535 struct tgsi_full_instruction
*inst
)
537 struct brw_compile
*p
= &c
->func
;
538 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
539 struct brw_reg interp
[4];
541 struct brw_reg src0
, w
;
543 src0
= get_src_reg(c
, &inst
->FullSrcRegisters
[0], 0);
544 w
= get_src_reg(c
, &inst
->FullSrcRegisters
[1], 3);
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
++ ) {
553 dst
= get_dst_reg(c
, inst
, i
);
554 brw_MOV(p
, dst
, interp
[i
]);
555 brw_MUL(p
, dst
, dst
, w
);
558 brw_set_saturate(p
, 0);
561 static void emit_ddy(struct brw_wm_compile
*c
,
562 struct tgsi_full_instruction
*inst
)
564 struct brw_compile
*p
= &c
->func
;
565 unsigned mask
= inst
->FullDstRegisters
[0].DstRegister
.WriteMask
;
566 struct brw_reg interp
[4];
568 struct brw_reg src0
, w
;
571 src0
= get_src_reg(c
, &inst
->FullSrcRegisters
[0], 0);
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
++ ) {
581 dst
= get_dst_reg(c
, inst
, i
);
582 brw_MOV(p
, dst
, suboffset(interp
[i
], 1));
583 brw_MUL(p
, dst
, dst
, w
);
586 brw_set_saturate(p
, 0);
590 BIAS on SIMD8 not workind yet...
592 static void emit_txb(struct brw_wm_compile
*c
,
593 struct tgsi_full_instruction
*inst
)
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];
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
);
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));
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));
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]);
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));
630 brw_MOV(p
, brw_message_reg(5), src
[3]);
631 brw_MOV(p
, brw_message_reg(6), brw_imm_f(0));
633 retype(vec8(dst
[0]), BRW_REGISTER_TYPE_UW
),
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
,
646 static void emit_tex(struct brw_wm_compile
*c
,
647 struct tgsi_full_instruction
*inst
)
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];
656 boolean shadow
= (c
->key
.shadowtex_mask
& (1<<inst
->TexSrcUnit
)) ? 1 : 0;
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
);
664 switch (inst
->TexSrcTarget
) {
665 case TEXTURE_1D_INDEX
:
669 case TEXTURE_2D_INDEX
:
670 case TEXTURE_RECT_INDEX
:
675 emit
= WRITEMASK_XYZ
;
686 for (i
= 0; i
< nr
; i
++) {
687 static const unsigned swz
[4] = {0,1,2,2};
689 brw_MOV(p
, brw_message_reg(msg_len
+1), src
[swz
[i
]]);
691 brw_MOV(p
, brw_message_reg(msg_len
+1), brw_imm_f(0));
696 brw_MOV(p
, brw_message_reg(5), brw_imm_f(0));
697 brw_MOV(p
, brw_message_reg(6), src
[2]);
701 retype(vec8(dst
[0]), BRW_REGISTER_TYPE_UW
),
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
,
713 brw_MOV(p
, dst
[3], brw_imm_f(1.0));
724 static void emit_fb_write(struct brw_wm_compile
*c
,
725 struct tgsi_full_instruction
*inst
)
727 struct brw_compile
*p
= &c
->func
;
732 // src0 = output color
733 // src1 = payload_depth[0]
734 // src2 = output depth
739 /* Reserve a space for AA - may not be needed:
741 if (c
->key
.aa_dest_stencil_reg
)
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
];
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
);
753 /* skip over the regs populated above: */
755 brw_pop_insn_state(p
);
759 /* Pass through control information:
761 /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */
763 brw_push_insn_state(p
);
764 brw_set_mask_control(p
, BRW_MASK_DISABLE
); /* ? */
766 brw_message_reg(base_reg
+ 1),
768 brw_pop_insn_state(p
);
771 /* Send framebuffer write message: */
773 retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW
),
775 retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW
),
776 0, /* render surface always 0 */
784 static void brw_wm_emit_instruction( struct brw_wm_compile
*c
,
785 struct tgsi_full_instruction
*inst
)
787 struct brw_compile
*p
= &c
->func
;
790 if (inst
->CondUpdate
)
791 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
793 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NONE
);
795 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NONE
);
798 switch (inst
->Instruction
.Opcode
) {
799 case TGSI_OPCODE_ABS
:
802 case TGSI_OPCODE_ADD
:
803 emit_alu2(c
, inst
, BRW_OPCODE_ADD
);
805 case TGSI_OPCODE_SUB
:
807 // emit_alu2(c, inst, BRW_OPCODE_SUB);
809 case TGSI_OPCODE_FRC
:
810 emit_alu1(c
, inst
, BRW_OPCODE_FRC
);
812 case TGSI_OPCODE_FLR
:
814 // emit_alu1(c, inst, BRW_OPCODE_FLR);
816 case TGSI_OPCODE_LRP
:
819 case TGSI_OPCODE_INT
:
820 emit_alu1(c
, inst
, BRW_OPCODE_RNDD
);
822 case TGSI_OPCODE_MOV
:
823 emit_alu1(c
, inst
, BRW_OPCODE_MOV
);
825 case TGSI_OPCODE_DP3
:
828 case TGSI_OPCODE_DP4
:
831 case TGSI_OPCODE_XPD
:
834 case TGSI_OPCODE_DPH
:
837 case TGSI_OPCODE_RCP
:
838 emit_math1(c
, inst
, BRW_MATH_FUNCTION_INV
);
840 case TGSI_OPCODE_RSQ
:
841 emit_math1(c
, inst
, BRW_MATH_FUNCTION_RSQ
);
843 case TGSI_OPCODE_SIN
:
844 emit_math1(c
, inst
, BRW_MATH_FUNCTION_SIN
);
846 case TGSI_OPCODE_COS
:
847 emit_math1(c
, inst
, BRW_MATH_FUNCTION_COS
);
849 case TGSI_OPCODE_EX2
:
850 emit_math1(c
, inst
, BRW_MATH_FUNCTION_EXP
);
852 case TGSI_OPCODE_LG2
:
853 emit_math1(c
, inst
, BRW_MATH_FUNCTION_LOG
);
855 case TGSI_OPCODE_MAX
:
858 case TGSI_OPCODE_MIN
:
861 case TGSI_OPCODE_DDX
:
864 case TGSI_OPCODE_DDY
:
867 case TGSI_OPCODE_SLT
:
868 emit_sop(c
, inst
, BRW_CONDITIONAL_L
);
870 case TGSI_OPCODE_SLE
:
871 emit_sop(c
, inst
, BRW_CONDITIONAL_LE
);
873 case TGSI_OPCODE_SGT
:
874 emit_sop(c
, inst
, BRW_CONDITIONAL_G
);
876 case TGSI_OPCODE_SGE
:
877 emit_sop(c
, inst
, BRW_CONDITIONAL_GE
);
879 case TGSI_OPCODE_SEQ
:
880 emit_sop(c
, inst
, BRW_CONDITIONAL_EQ
);
882 case TGSI_OPCODE_SNE
:
883 emit_sop(c
, inst
, BRW_CONDITIONAL_NEQ
);
885 case TGSI_OPCODE_MUL
:
886 emit_alu2(c
, inst
, BRW_OPCODE_MUL
);
888 case TGSI_OPCODE_POW
:
891 case TGSI_OPCODE_MAD
:
894 case TGSI_OPCODE_TEX
:
897 case TGSI_OPCODE_TXB
:
900 case TGSI_OPCODE_TEXKILL
:
904 assert(c
->if_insn
< MAX_IFSN
);
905 c
->if_inst
[c
->if_insn
++] = brw_IF(p
, BRW_EXECUTE_8
);
907 case TGSI_OPCODE_ELSE
:
908 c
->if_inst
[c
->if_insn
-1] = brw_ELSE(p
, c
->if_inst
[c
->if_insn
-1]);
910 case TGSI_OPCODE_ENDIF
:
911 assert(c
->if_insn
> 0);
912 brw_ENDIF(p
, c
->if_inst
[--c
->if_insn
]);
914 case TGSI_OPCODE_BGNSUB
:
915 case TGSI_OPCODE_ENDSUB
:
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
);
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];
929 brw_ADD(p
, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
930 brw_pop_insn_state(p
);
933 case TGSI_OPCODE_RET
:
935 brw_push_insn_state(p
);
936 brw_set_mask_control(p
, BRW_MASK_DISABLE
);
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
);
945 emit_fb_write(c
, inst
);
949 case TGSI_OPCODE_LOOP
:
950 c
->loop_inst
[c
->loop_insn
++] = brw_DO(p
, BRW_EXECUTE_8
);
952 case TGSI_OPCODE_BRK
:
954 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
956 case TGSI_OPCODE_CONT
:
958 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
960 case TGSI_OPCODE_ENDLOOP
:
962 c
->inst0
= c
->inst1
= brw_WHILE(p
, c
->loop_inst
[c
->loop_insn
]);
963 /* patch all the BREAK instructions from
965 while (c
->inst0
> c
->loop_inst
[c
->loop_insn
]) {
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;
976 case TGSI_OPCODE_END
:
977 emit_fb_write(c
, inst
);
981 debug_printf("unsupported IR in fragment shader %d\n",
982 inst
->Instruction
.Opcode
);
985 if (inst
->CondUpdate
)
986 brw_set_predicate_control(p
, BRW_PREDICATE_NORMAL
);
988 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
997 void brw_wm_glsl_emit(struct brw_wm_compile
*c
)
999 struct tgsi_parse_context parse
;
1000 struct brw_compile
*p
= &c
->func
;
1002 brw_init_compile(&c
->func
);
1003 brw_set_compression_control(p
, BRW_COMPRESSION_NONE
);
1008 c
->stack_index
= brw_indirect(0,0);
1010 /* Do static register allocation and parameter interpolation:
1012 brw_wm_emit_decls( c
);
1014 /* Emit the actual program. All done with very direct translation,
1015 * hopefully we can improve on this shortly...
1017 brw_MOV(p
, get_addr_reg(c
->stack_index
), brw_address(c
->stack
));
1019 tgsi_parse_init( &parse
, c
->fp
->program
.tokens
);
1021 while( !tgsi_parse_end_of_tokens( &parse
) )
1023 tgsi_parse_token( &parse
);
1025 switch( parse
.FullToken
.Token
.Type
) {
1026 case TGSI_TOKEN_TYPE_DECLARATION
:
1030 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1031 /* not handled yet */
1035 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1036 brw_wm_emit_instruction(c
, &parse
.FullToken
.FullInstruction
);
1044 tgsi_parse_free (&parse
);
1046 /* Fix up call targets:
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
;
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));
1073 c
->prog_data
.total_grf
= c
->reg_index
;
1074 c
->prog_data
.total_scratch
= 0;