ir_to_mesa: Note which of our expr ops are unsupported 1.30 features.
[mesa.git] / src / mesa / shader / ir_to_mesa.cpp
1 /*
2 * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
3 * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
4 * Copyright © 2010 Intel Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file ir_to_mesa.cpp
28 *
29 * Translates the IR to ARB_fragment_program text if possible,
30 * printing the result
31 */
32
33 #include <stdio.h>
34 #include "ir.h"
35 #include "ir_visitor.h"
36 #include "ir_print_visitor.h"
37 #include "ir_expression_flattening.h"
38 #include "glsl_types.h"
39 #include "glsl_parser_extras.h"
40 #include "../glsl/program.h"
41 #include "ir_optimization.h"
42 #include "ast.h"
43
44 extern "C" {
45 #include "main/mtypes.h"
46 #include "shader/prog_instruction.h"
47 #include "shader/prog_print.h"
48 #include "shader/program.h"
49 #include "shader/prog_uniform.h"
50 #include "shader/prog_parameter.h"
51 #include "shader/shader_api.h"
52 }
53
54 /**
55 * This struct is a corresponding struct to Mesa prog_src_register, with
56 * wider fields.
57 */
58 typedef struct ir_to_mesa_src_reg {
59 int file; /**< PROGRAM_* from Mesa */
60 int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
61 GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
62 int negate; /**< NEGATE_XYZW mask from mesa */
63 bool reladdr; /**< Register index should be offset by address reg. */
64 } ir_to_mesa_src_reg;
65
66 typedef struct ir_to_mesa_dst_reg {
67 int file; /**< PROGRAM_* from Mesa */
68 int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
69 int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
70 GLuint cond_mask:4;
71 } ir_to_mesa_dst_reg;
72
73 extern ir_to_mesa_src_reg ir_to_mesa_undef;
74
75 class ir_to_mesa_instruction : public exec_node {
76 public:
77 enum prog_opcode op;
78 ir_to_mesa_dst_reg dst_reg;
79 ir_to_mesa_src_reg src_reg[3];
80 /** Pointer to the ir source this tree came from for debugging */
81 ir_instruction *ir;
82 GLboolean cond_update;
83 int sampler; /**< sampler index */
84 int tex_target; /**< One of TEXTURE_*_INDEX */
85 };
86
87 class temp_entry : public exec_node {
88 public:
89 temp_entry(ir_variable *var, int file, int index)
90 : file(file), index(index), var(var)
91 {
92 /* empty */
93 }
94
95 int file;
96 int index;
97 ir_variable *var; /* variable that maps to this, if any */
98 };
99
100 class ir_to_mesa_visitor : public ir_visitor {
101 public:
102 ir_to_mesa_visitor();
103
104 GLcontext *ctx;
105 struct gl_program *prog;
106
107 int next_temp;
108
109 temp_entry *find_variable_storage(ir_variable *var);
110
111 ir_to_mesa_src_reg get_temp(const glsl_type *type);
112
113 struct ir_to_mesa_src_reg src_reg_for_float(float val);
114
115 /**
116 * \name Visit methods
117 *
118 * As typical for the visitor pattern, there must be one \c visit method for
119 * each concrete subclass of \c ir_instruction. Virtual base classes within
120 * the hierarchy should not have \c visit methods.
121 */
122 /*@{*/
123 virtual void visit(ir_variable *);
124 virtual void visit(ir_loop *);
125 virtual void visit(ir_loop_jump *);
126 virtual void visit(ir_function_signature *);
127 virtual void visit(ir_function *);
128 virtual void visit(ir_expression *);
129 virtual void visit(ir_swizzle *);
130 virtual void visit(ir_dereference_variable *);
131 virtual void visit(ir_dereference_array *);
132 virtual void visit(ir_dereference_record *);
133 virtual void visit(ir_assignment *);
134 virtual void visit(ir_constant *);
135 virtual void visit(ir_call *);
136 virtual void visit(ir_return *);
137 virtual void visit(ir_discard *);
138 virtual void visit(ir_texture *);
139 virtual void visit(ir_if *);
140 /*@}*/
141
142 struct ir_to_mesa_src_reg result;
143
144 /** List of temp_entry */
145 exec_list variable_storage;
146
147 /** List of ir_to_mesa_instruction */
148 exec_list instructions;
149
150 ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
151 enum prog_opcode op,
152 ir_to_mesa_dst_reg dst,
153 ir_to_mesa_src_reg src0);
154
155 ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
156 enum prog_opcode op,
157 ir_to_mesa_dst_reg dst,
158 ir_to_mesa_src_reg src0,
159 ir_to_mesa_src_reg src1);
160
161 ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
162 enum prog_opcode op,
163 ir_to_mesa_dst_reg dst,
164 ir_to_mesa_src_reg src0,
165 ir_to_mesa_src_reg src1,
166 ir_to_mesa_src_reg src2);
167
168 void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
169 enum prog_opcode op,
170 ir_to_mesa_dst_reg dst,
171 ir_to_mesa_src_reg src0);
172
173 void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
174 enum prog_opcode op,
175 ir_to_mesa_dst_reg dst,
176 ir_to_mesa_src_reg src0,
177 ir_to_mesa_src_reg src1);
178
179 int *sampler_map;
180 int sampler_map_size;
181
182 void map_sampler(int location, int sampler);
183 int get_sampler_number(int location);
184
185 void *mem_ctx;
186 };
187
188 ir_to_mesa_src_reg ir_to_mesa_undef = {
189 PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
190 };
191
192 ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
193 PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
194 };
195
196 ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
197 PROGRAM_ADDRESS, 0, WRITEMASK_X
198 };
199
200 static int swizzle_for_size(int size)
201 {
202 int size_swizzles[4] = {
203 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
204 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
205 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
206 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
207 };
208
209 return size_swizzles[size - 1];
210 }
211
212 /* This list should match up with builtin_variables.h */
213 static const struct {
214 const char *name;
215 int file;
216 int index;
217 } builtin_var_to_mesa_reg[] = {
218 /* core_vs */
219 {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS},
220 {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ},
221
222 /* core_fs */
223 {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS},
224 {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE},
225 {"gl_FragColor", PROGRAM_OUTPUT, FRAG_ATTRIB_COL0},
226 {"gl_FragDepth", PROGRAM_OUTPUT, FRAG_RESULT_DEPTH},
227
228 /* 110_deprecated_fs */
229 {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
230 {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1},
231 {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC},
232 {"gl_TexCoord", PROGRAM_INPUT, FRAG_ATTRIB_TEX0}, /* array */
233
234 /* 110_deprecated_vs */
235 {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS},
236 {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL},
237 {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0},
238 {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1},
239 {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0},
240 {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1},
241 {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2},
242 {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3},
243 {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4},
244 {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5},
245 {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6},
246 {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7},
247 {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */
248 {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC},
249 /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
250 {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0},
251 {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0},
252 {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1},
253 {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1},
254 {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC},
255
256 /* 130_vs */
257 /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
258
259 {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */
260 };
261
262 ir_to_mesa_instruction *
263 ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
264 enum prog_opcode op,
265 ir_to_mesa_dst_reg dst,
266 ir_to_mesa_src_reg src0,
267 ir_to_mesa_src_reg src1,
268 ir_to_mesa_src_reg src2)
269 {
270 ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
271
272 inst->op = op;
273 inst->dst_reg = dst;
274 inst->src_reg[0] = src0;
275 inst->src_reg[1] = src1;
276 inst->src_reg[2] = src2;
277 inst->ir = ir;
278
279 this->instructions.push_tail(inst);
280
281 return inst;
282 }
283
284
285 ir_to_mesa_instruction *
286 ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
287 enum prog_opcode op,
288 ir_to_mesa_dst_reg dst,
289 ir_to_mesa_src_reg src0,
290 ir_to_mesa_src_reg src1)
291 {
292 return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
293 }
294
295 ir_to_mesa_instruction *
296 ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
297 enum prog_opcode op,
298 ir_to_mesa_dst_reg dst,
299 ir_to_mesa_src_reg src0)
300 {
301 return ir_to_mesa_emit_op3(ir, op, dst,
302 src0, ir_to_mesa_undef, ir_to_mesa_undef);
303 }
304
305 void
306 ir_to_mesa_visitor::map_sampler(int location, int sampler)
307 {
308 if (this->sampler_map_size <= location) {
309 this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map,
310 int, location + 1);
311 this->sampler_map_size = location + 1;
312 }
313
314 this->sampler_map[location] = sampler;
315 }
316
317 int
318 ir_to_mesa_visitor::get_sampler_number(int location)
319 {
320 assert(location < this->sampler_map_size);
321 return this->sampler_map[location];
322 }
323
324 inline ir_to_mesa_dst_reg
325 ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
326 {
327 ir_to_mesa_dst_reg dst_reg;
328
329 dst_reg.file = reg.file;
330 dst_reg.index = reg.index;
331 dst_reg.writemask = WRITEMASK_XYZW;
332 dst_reg.cond_mask = COND_TR;
333
334 return dst_reg;
335 }
336
337 /**
338 * Emits Mesa scalar opcodes to produce unique answers across channels.
339 *
340 * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X
341 * channel determines the result across all channels. So to do a vec4
342 * of this operation, we want to emit a scalar per source channel used
343 * to produce dest channels.
344 */
345 void
346 ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
347 enum prog_opcode op,
348 ir_to_mesa_dst_reg dst,
349 ir_to_mesa_src_reg orig_src0,
350 ir_to_mesa_src_reg orig_src1)
351 {
352 int i, j;
353 int done_mask = ~dst.writemask;
354
355 /* Mesa RCP is a scalar operation splatting results to all channels,
356 * like ARB_fp/vp. So emit as many RCPs as necessary to cover our
357 * dst channels.
358 */
359 for (i = 0; i < 4; i++) {
360 GLuint this_mask = (1 << i);
361 ir_to_mesa_instruction *inst;
362 ir_to_mesa_src_reg src0 = orig_src0;
363 ir_to_mesa_src_reg src1 = orig_src1;
364
365 if (done_mask & this_mask)
366 continue;
367
368 GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
369 GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
370 for (j = i + 1; j < 4; j++) {
371 if (!(done_mask & (1 << j)) &&
372 GET_SWZ(src0.swizzle, j) == src0_swiz &&
373 GET_SWZ(src1.swizzle, j) == src1_swiz) {
374 this_mask |= (1 << j);
375 }
376 }
377 src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
378 src0_swiz, src0_swiz);
379 src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
380 src1_swiz, src1_swiz);
381
382 inst = ir_to_mesa_emit_op2(ir, op,
383 dst,
384 src0,
385 src1);
386 inst->dst_reg.writemask = this_mask;
387 done_mask |= this_mask;
388 }
389 }
390
391 void
392 ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
393 enum prog_opcode op,
394 ir_to_mesa_dst_reg dst,
395 ir_to_mesa_src_reg src0)
396 {
397 ir_to_mesa_src_reg undef = ir_to_mesa_undef;
398
399 undef.swizzle = SWIZZLE_XXXX;
400
401 ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
402 }
403
404 struct ir_to_mesa_src_reg
405 ir_to_mesa_visitor::src_reg_for_float(float val)
406 {
407 ir_to_mesa_src_reg src_reg;
408
409 src_reg.file = PROGRAM_CONSTANT;
410 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
411 &val, 1, &src_reg.swizzle);
412
413 return src_reg;
414 }
415
416 static int
417 type_size(const struct glsl_type *type)
418 {
419 unsigned int i;
420 int size;
421
422 switch (type->base_type) {
423 case GLSL_TYPE_UINT:
424 case GLSL_TYPE_INT:
425 case GLSL_TYPE_FLOAT:
426 case GLSL_TYPE_BOOL:
427 if (type->is_matrix()) {
428 return 4; /* FINISHME: Not all matrices are 4x4. */
429 } else {
430 /* Regardless of size of vector, it gets a vec4. This is bad
431 * packing for things like floats, but otherwise arrays become a
432 * mess. Hopefully a later pass over the code can pack scalars
433 * down if appropriate.
434 */
435 return 1;
436 }
437 case GLSL_TYPE_ARRAY:
438 return type_size(type->fields.array) * type->length;
439 case GLSL_TYPE_STRUCT:
440 size = 0;
441 for (i = 0; i < type->length; i++) {
442 size += type_size(type->fields.structure[i].type);
443 }
444 return size;
445 default:
446 assert(0);
447 }
448 }
449
450 /**
451 * In the initial pass of codegen, we assign temporary numbers to
452 * intermediate results. (not SSA -- variable assignments will reuse
453 * storage). Actual register allocation for the Mesa VM occurs in a
454 * pass over the Mesa IR later.
455 */
456 ir_to_mesa_src_reg
457 ir_to_mesa_visitor::get_temp(const glsl_type *type)
458 {
459 ir_to_mesa_src_reg src_reg;
460 int swizzle[4];
461 int i;
462
463 assert(!type->is_array());
464
465 src_reg.file = PROGRAM_TEMPORARY;
466 src_reg.index = next_temp;
467 src_reg.reladdr = false;
468 next_temp += type_size(type);
469
470 for (i = 0; i < type->vector_elements; i++)
471 swizzle[i] = i;
472 for (; i < 4; i++)
473 swizzle[i] = type->vector_elements - 1;
474 src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
475 swizzle[2], swizzle[3]);
476 src_reg.negate = 0;
477
478 return src_reg;
479 }
480
481 temp_entry *
482 ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
483 {
484
485 temp_entry *entry;
486
487 foreach_iter(exec_list_iterator, iter, this->variable_storage) {
488 entry = (temp_entry *)iter.get();
489
490 if (entry->var == var)
491 return entry;
492 }
493
494 return NULL;
495 }
496
497 void
498 ir_to_mesa_visitor::visit(ir_variable *ir)
499 {
500 (void)ir;
501 }
502
503 void
504 ir_to_mesa_visitor::visit(ir_loop *ir)
505 {
506 assert(!ir->from);
507 assert(!ir->to);
508 assert(!ir->increment);
509 assert(!ir->counter);
510
511 ir_to_mesa_emit_op1(NULL, OPCODE_BGNLOOP,
512 ir_to_mesa_undef_dst, ir_to_mesa_undef);
513
514 visit_exec_list(&ir->body_instructions, this);
515
516 ir_to_mesa_emit_op1(NULL, OPCODE_ENDLOOP,
517 ir_to_mesa_undef_dst, ir_to_mesa_undef);
518 }
519
520 void
521 ir_to_mesa_visitor::visit(ir_loop_jump *ir)
522 {
523 switch (ir->mode) {
524 case ir_loop_jump::jump_break:
525 ir_to_mesa_emit_op1(NULL, OPCODE_BRK,
526 ir_to_mesa_undef_dst, ir_to_mesa_undef);
527 break;
528 case ir_loop_jump::jump_continue:
529 ir_to_mesa_emit_op1(NULL, OPCODE_CONT,
530 ir_to_mesa_undef_dst, ir_to_mesa_undef);
531 break;
532 }
533 }
534
535
536 void
537 ir_to_mesa_visitor::visit(ir_function_signature *ir)
538 {
539 assert(0);
540 (void)ir;
541 }
542
543 void
544 ir_to_mesa_visitor::visit(ir_function *ir)
545 {
546 /* Ignore function bodies other than main() -- we shouldn't see calls to
547 * them since they should all be inlined before we get to ir_to_mesa.
548 */
549 if (strcmp(ir->name, "main") == 0) {
550 const ir_function_signature *sig;
551 exec_list empty;
552
553 sig = ir->matching_signature(&empty);
554
555 assert(sig);
556
557 foreach_iter(exec_list_iterator, iter, sig->body) {
558 ir_instruction *ir = (ir_instruction *)iter.get();
559
560 ir->accept(this);
561 }
562 }
563 }
564
565 void
566 ir_to_mesa_visitor::visit(ir_expression *ir)
567 {
568 unsigned int operand;
569 struct ir_to_mesa_src_reg op[2];
570 struct ir_to_mesa_src_reg result_src;
571 struct ir_to_mesa_dst_reg result_dst;
572 const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
573 const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
574 const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
575
576 for (operand = 0; operand < ir->get_num_operands(); operand++) {
577 this->result.file = PROGRAM_UNDEFINED;
578 ir->operands[operand]->accept(this);
579 if (this->result.file == PROGRAM_UNDEFINED) {
580 ir_print_visitor v;
581 printf("Failed to get tree for expression operand:\n");
582 ir->operands[operand]->accept(&v);
583 exit(1);
584 }
585 op[operand] = this->result;
586
587 /* Only expression implemented for matrices yet */
588 assert(!ir->operands[operand]->type->is_matrix() ||
589 ir->operation == ir_binop_mul);
590 }
591
592 this->result.file = PROGRAM_UNDEFINED;
593
594 /* Storage for our result. Ideally for an assignment we'd be using
595 * the actual storage for the result here, instead.
596 */
597 result_src = get_temp(ir->type);
598 /* convenience for the emit functions below. */
599 result_dst = ir_to_mesa_dst_reg_from_src(result_src);
600 /* Limit writes to the channels that will be used by result_src later.
601 * This does limit this temp's use as a temporary for multi-instruction
602 * sequences.
603 */
604 result_dst.writemask = (1 << ir->type->vector_elements) - 1;
605
606 switch (ir->operation) {
607 case ir_unop_logic_not:
608 ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
609 op[0], src_reg_for_float(0.0));
610 break;
611 case ir_unop_neg:
612 op[0].negate = ~op[0].negate;
613 result_src = op[0];
614 break;
615 case ir_unop_abs:
616 ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
617 break;
618
619 case ir_unop_exp:
620 ir_to_mesa_emit_scalar_op1(ir, OPCODE_EXP, result_dst, op[0]);
621 break;
622 case ir_unop_exp2:
623 ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
624 break;
625 case ir_unop_log:
626 ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
627 break;
628 case ir_unop_log2:
629 ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
630 break;
631 case ir_unop_sin:
632 ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
633 break;
634 case ir_unop_cos:
635 ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
636 break;
637
638 case ir_unop_dFdx:
639 ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
640 break;
641 case ir_unop_dFdy:
642 ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
643 break;
644
645 case ir_binop_add:
646 ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
647 break;
648 case ir_binop_sub:
649 ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
650 break;
651 case ir_binop_mul:
652 if (ir->operands[0]->type->is_matrix() &&
653 !ir->operands[1]->type->is_matrix()) {
654 if (ir->operands[1]->type->is_scalar()) {
655 ir_to_mesa_dst_reg dst_column = result_dst;
656 ir_to_mesa_src_reg src_column = op[0];
657 for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
658 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
659 dst_column, src_column, op[1]);
660 dst_column.index++;
661 src_column.index++;
662 }
663 } else {
664 ir_to_mesa_src_reg src_column = op[0];
665 ir_to_mesa_src_reg src_chan = op[1];
666 assert(!ir->operands[1]->type->is_matrix() ||
667 !"FINISHME: matrix * matrix");
668 for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
669 src_chan.swizzle = MAKE_SWIZZLE4(i, i, i, i);
670 if (i == 0) {
671 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
672 result_dst, src_column, src_chan);
673 } else {
674 ir_to_mesa_emit_op3(ir, OPCODE_MAD,
675 result_dst, src_column, src_chan,
676 result_src);
677 }
678 src_column.index++;
679 }
680 }
681 } else {
682 assert(!ir->operands[0]->type->is_matrix());
683 assert(!ir->operands[1]->type->is_matrix());
684 ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
685 }
686 break;
687 case ir_binop_div:
688 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[1]);
689 ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], result_src);
690 break;
691
692 case ir_binop_less:
693 ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
694 break;
695 case ir_binop_greater:
696 ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
697 break;
698 case ir_binop_lequal:
699 ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
700 break;
701 case ir_binop_gequal:
702 ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
703 break;
704 case ir_binop_equal:
705 ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
706 break;
707 case ir_binop_logic_xor:
708 case ir_binop_nequal:
709 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
710 break;
711
712 case ir_binop_logic_or:
713 /* This could be a saturated add and skip the SNE. */
714 ir_to_mesa_emit_op2(ir, OPCODE_ADD,
715 result_dst,
716 op[0], op[1]);
717
718 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
719 result_dst,
720 result_src, src_reg_for_float(0.0));
721 break;
722
723 case ir_binop_logic_and:
724 /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
725 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
726 result_dst,
727 op[0], op[1]);
728 break;
729
730 case ir_binop_dot:
731 if (ir->operands[0]->type == vec4_type) {
732 assert(ir->operands[1]->type == vec4_type);
733 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
734 result_dst,
735 op[0], op[1]);
736 } else if (ir->operands[0]->type == vec3_type) {
737 assert(ir->operands[1]->type == vec3_type);
738 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
739 result_dst,
740 op[0], op[1]);
741 } else if (ir->operands[0]->type == vec2_type) {
742 assert(ir->operands[1]->type == vec2_type);
743 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
744 result_dst,
745 op[0], op[1]);
746 }
747 break;
748 case ir_unop_sqrt:
749 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
750 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
751 /* For incoming channels < 0, set the result to 0. */
752 ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
753 op[0], src_reg_for_float(0.0), result_src);
754 break;
755 case ir_unop_rsq:
756 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
757 break;
758 case ir_unop_i2f:
759 /* Mesa IR lacks types, ints are stored as truncated floats. */
760 result_src = op[0];
761 break;
762 case ir_unop_f2i:
763 ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
764 break;
765 case ir_unop_f2b:
766 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
767 result_src, src_reg_for_float(0.0));
768 break;
769 case ir_unop_trunc:
770 ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
771 break;
772 case ir_unop_ceil:
773 op[0].negate = ~op[0].negate;
774 ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
775 result_src.negate = ~result_src.negate;
776 break;
777 case ir_unop_floor:
778 ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
779 break;
780 case ir_binop_min:
781 ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
782 break;
783 case ir_binop_max:
784 ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
785 break;
786 case ir_binop_pow:
787 ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
788 break;
789
790 case ir_unop_bit_not:
791 case ir_unop_u2f:
792 case ir_binop_lshift:
793 case ir_binop_rshift:
794 case ir_binop_bit_and:
795 case ir_binop_bit_xor:
796 case ir_binop_bit_or:
797 assert(!"GLSL 1.30 features unsupported");
798 break;
799
800 default:
801 ir_print_visitor v;
802 printf("Failed to get tree for expression:\n");
803 ir->accept(&v);
804 exit(1);
805 break;
806 }
807
808 this->result = result_src;
809 }
810
811
812 void
813 ir_to_mesa_visitor::visit(ir_swizzle *ir)
814 {
815 ir_to_mesa_src_reg src_reg;
816 int i;
817 int swizzle[4];
818
819 /* Note that this is only swizzles in expressions, not those on the left
820 * hand side of an assignment, which do write masking. See ir_assignment
821 * for that.
822 */
823
824 ir->val->accept(this);
825 src_reg = this->result;
826 assert(src_reg.file != PROGRAM_UNDEFINED);
827
828 for (i = 0; i < 4; i++) {
829 if (i < ir->type->vector_elements) {
830 switch (i) {
831 case 0:
832 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
833 break;
834 case 1:
835 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
836 break;
837 case 2:
838 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
839 break;
840 case 3:
841 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
842 break;
843 }
844 } else {
845 /* If the type is smaller than a vec4, replicate the last
846 * channel out.
847 */
848 swizzle[i] = swizzle[ir->type->vector_elements - 1];
849 }
850 }
851
852 src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
853 swizzle[1],
854 swizzle[2],
855 swizzle[3]);
856
857 this->result = src_reg;
858 }
859
860 static temp_entry *
861 get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var)
862 {
863 /*
864 * NOTE: The ARB_vertex_program extension specified that matrices get
865 * loaded in registers in row-major order. With GLSL, we want column-
866 * major order. So, we need to transpose all matrices here...
867 */
868 static const struct {
869 const char *name;
870 int matrix;
871 int modifier;
872 } matrices[] = {
873 { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
874 { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
875 { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
876 { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
877
878 { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
879 { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
880 { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
881 { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
882
883 { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
884 { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
885 { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
886 { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
887
888 { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
889 { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
890 { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
891 { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
892
893 { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
894
895 };
896 unsigned int i;
897 temp_entry *entry;
898
899 /* C++ gets angry when we try to use an int as a gl_state_index, so we use
900 * ints for gl_state_index. Make sure they're compatible.
901 */
902 assert(sizeof(gl_state_index) == sizeof(int));
903
904 for (i = 0; i < Elements(matrices); i++) {
905 if (strcmp(var->name, matrices[i].name) == 0) {
906 int j;
907 int last_pos = -1, base_pos = -1;
908 int tokens[STATE_LENGTH];
909
910 tokens[0] = matrices[i].matrix;
911 tokens[1] = 0; /* array index! */
912 tokens[4] = matrices[i].modifier;
913
914 /* Add a ref for each column. It looks like the reason we do
915 * it this way is that _mesa_add_state_reference doesn't work
916 * for things that aren't vec4s, so the tokens[2]/tokens[3]
917 * range has to be equal.
918 */
919 for (j = 0; j < 4; j++) {
920 tokens[2] = j;
921 tokens[3] = j;
922 int pos = _mesa_add_state_reference(prog->Parameters,
923 (gl_state_index *)tokens);
924 assert(last_pos == -1 || last_pos == base_pos + j);
925 if (base_pos == -1)
926 base_pos = pos;
927 }
928
929 entry = new(mem_ctx) temp_entry(var,
930 PROGRAM_STATE_VAR,
931 base_pos);
932
933 return entry;
934 }
935 }
936
937 return NULL;
938 }
939
940 void
941 ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
942 {
943 ir_to_mesa_src_reg src_reg;
944 temp_entry *entry = find_variable_storage(ir->var);
945 unsigned int i, loc;
946 bool var_in;
947
948 if (!entry) {
949 switch (ir->var->mode) {
950 case ir_var_uniform:
951 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var);
952 if (entry)
953 break;
954
955 /* FINISHME: Fix up uniform name for arrays and things */
956 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
957 /* FINISHME: we whack the location of the var here, which
958 * is probably not expected. But we need to communicate
959 * mesa's sampler number to the tex instruction.
960 */
961 int sampler = _mesa_add_sampler(this->prog->Parameters,
962 ir->var->name,
963 ir->var->type->gl_type);
964 map_sampler(ir->var->location, sampler);
965
966 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_SAMPLER, sampler);
967 this->variable_storage.push_tail(entry);
968 break;
969 }
970
971 assert(ir->var->type->gl_type != 0 &&
972 ir->var->type->gl_type != GL_INVALID_ENUM);
973 loc = _mesa_add_uniform(this->prog->Parameters,
974 ir->var->name,
975 type_size(ir->var->type) * 4,
976 ir->var->type->gl_type,
977 NULL);
978
979 /* Always mark the uniform used at this point. If it isn't
980 * used, dead code elimination should have nuked the decl already.
981 */
982 this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
983
984 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_UNIFORM, loc);
985 this->variable_storage.push_tail(entry);
986 break;
987 case ir_var_in:
988 case ir_var_out:
989 case ir_var_inout:
990 var_in = (ir->var->mode == ir_var_in ||
991 ir->var->mode == ir_var_inout);
992
993 for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
994 bool in = builtin_var_to_mesa_reg[i].file == PROGRAM_INPUT;
995
996 if (strcmp(ir->var->name, builtin_var_to_mesa_reg[i].name) == 0 &&
997 !(var_in ^ in))
998 break;
999 }
1000 if (i != ARRAY_SIZE(builtin_var_to_mesa_reg)) {
1001 entry = new(mem_ctx) temp_entry(ir->var,
1002 builtin_var_to_mesa_reg[i].file,
1003 builtin_var_to_mesa_reg[i].index);
1004 break;
1005 }
1006
1007 /* If no builtin, then it's a user-generated varying
1008 * (FINISHME: or a function argument!)
1009 */
1010 /* The linker-assigned location is VERT_RESULT_* or FRAG_ATTRIB*
1011 */
1012 assert(ir->var->location != -1);
1013 if (var_in) {
1014 entry = new(mem_ctx) temp_entry(ir->var,
1015 PROGRAM_INPUT,
1016 ir->var->location);
1017
1018 if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1019 ir->var->location >= VERT_ATTRIB_GENERIC0) {
1020 _mesa_add_attribute(prog->Attributes,
1021 ir->var->name,
1022 type_size(ir->var->type) * 4,
1023 ir->var->type->gl_type,
1024 ir->var->location - VERT_ATTRIB_GENERIC0);
1025 }
1026 } else {
1027 entry = new(mem_ctx) temp_entry(ir->var,
1028 PROGRAM_OUTPUT,
1029 ir->var->location);
1030 }
1031
1032 break;
1033 case ir_var_auto:
1034 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
1035 this->next_temp);
1036 this->variable_storage.push_tail(entry);
1037
1038 next_temp += type_size(ir->var->type);
1039 break;
1040 }
1041
1042 if (!entry) {
1043 printf("Failed to make storage for %s\n", ir->var->name);
1044 exit(1);
1045 }
1046 }
1047
1048 src_reg.file = entry->file;
1049 src_reg.index = entry->index;
1050 /* If the type is smaller than a vec4, replicate the last channel out. */
1051 src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
1052 src_reg.reladdr = false;
1053 src_reg.negate = 0;
1054
1055 this->result = src_reg;
1056 }
1057
1058 void
1059 ir_to_mesa_visitor::visit(ir_dereference_array *ir)
1060 {
1061 ir_constant *index;
1062 ir_to_mesa_src_reg src_reg;
1063
1064 index = ir->array_index->constant_expression_value();
1065
1066 /* By the time we make it to this stage, matrices should be broken down
1067 * to vectors.
1068 */
1069 assert(!ir->type->is_matrix());
1070
1071 ir->array->accept(this);
1072 src_reg = this->result;
1073
1074 if (src_reg.file == PROGRAM_INPUT ||
1075 src_reg.file == PROGRAM_OUTPUT) {
1076 assert(index); /* FINISHME: Handle variable indexing of builtins. */
1077
1078 src_reg.index += index->value.i[0];
1079 } else {
1080 if (index) {
1081 src_reg.index += index->value.i[0];
1082 } else {
1083 ir_to_mesa_src_reg array_base = this->result;
1084 /* Variable index array dereference. It eats the "vec4" of the
1085 * base of the array and an index that offsets the Mesa register
1086 * index.
1087 */
1088 ir->array_index->accept(this);
1089
1090 /* FINISHME: This doesn't work when we're trying to do the LHS
1091 * of an assignment.
1092 */
1093 src_reg.reladdr = true;
1094 ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
1095 this->result);
1096
1097 this->result = get_temp(ir->type);
1098 ir_to_mesa_emit_op1(ir, OPCODE_MOV,
1099 ir_to_mesa_dst_reg_from_src(this->result),
1100 src_reg);
1101 }
1102 }
1103
1104 /* If the type is smaller than a vec4, replicate the last channel out. */
1105 src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
1106
1107 this->result = src_reg;
1108 }
1109
1110 void
1111 ir_to_mesa_visitor::visit(ir_dereference_record *ir)
1112 {
1113 unsigned int i;
1114 const glsl_type *struct_type = ir->record->type;
1115 int offset = 0;
1116
1117 ir->record->accept(this);
1118
1119 for (i = 0; i < struct_type->length; i++) {
1120 if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
1121 break;
1122 offset += type_size(struct_type->fields.structure[i].type);
1123 }
1124 this->result.index += offset;
1125 }
1126
1127 /**
1128 * We want to be careful in assignment setup to hit the actual storage
1129 * instead of potentially using a temporary like we might with the
1130 * ir_dereference handler.
1131 *
1132 * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
1133 * should only see potentially one variable array index of a vector,
1134 * and one swizzle, before getting to actual vec4 storage. So handle
1135 * those, then go use ir_dereference to handle the rest.
1136 */
1137 static struct ir_to_mesa_dst_reg
1138 get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
1139 {
1140 struct ir_to_mesa_dst_reg dst_reg;
1141 ir_dereference *deref;
1142 ir_swizzle *swiz;
1143
1144 /* Use the rvalue deref handler for the most part. We'll ignore
1145 * swizzles in it and write swizzles using writemask, though.
1146 */
1147 ir->accept(v);
1148 dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
1149
1150 if ((deref = ir->as_dereference())) {
1151 ir_dereference_array *deref_array = ir->as_dereference_array();
1152 assert(!deref_array || deref_array->array->type->is_array());
1153
1154 ir->accept(v);
1155 } else if ((swiz = ir->as_swizzle())) {
1156 dst_reg.writemask = 0;
1157 if (swiz->mask.num_components >= 1)
1158 dst_reg.writemask |= (1 << swiz->mask.x);
1159 if (swiz->mask.num_components >= 2)
1160 dst_reg.writemask |= (1 << swiz->mask.y);
1161 if (swiz->mask.num_components >= 3)
1162 dst_reg.writemask |= (1 << swiz->mask.z);
1163 if (swiz->mask.num_components >= 4)
1164 dst_reg.writemask |= (1 << swiz->mask.w);
1165 }
1166
1167 return dst_reg;
1168 }
1169
1170 void
1171 ir_to_mesa_visitor::visit(ir_assignment *ir)
1172 {
1173 struct ir_to_mesa_dst_reg l;
1174 struct ir_to_mesa_src_reg r;
1175
1176 assert(!ir->lhs->type->is_matrix());
1177 assert(!ir->lhs->type->is_array());
1178 assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
1179
1180 l = get_assignment_lhs(ir->lhs, this);
1181
1182 ir->rhs->accept(this);
1183 r = this->result;
1184 assert(l.file != PROGRAM_UNDEFINED);
1185 assert(r.file != PROGRAM_UNDEFINED);
1186
1187 if (ir->condition) {
1188 ir_constant *condition_constant;
1189
1190 condition_constant = ir->condition->constant_expression_value();
1191
1192 assert(condition_constant && condition_constant->value.b[0]);
1193 }
1194
1195 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
1196 }
1197
1198
1199 void
1200 ir_to_mesa_visitor::visit(ir_constant *ir)
1201 {
1202 ir_to_mesa_src_reg src_reg;
1203 GLfloat stack_vals[4];
1204 GLfloat *values = stack_vals;
1205 unsigned int i;
1206
1207 if (ir->type->is_matrix() || ir->type->is_array()) {
1208 assert(!"FINISHME: array/matrix constants");
1209 }
1210
1211 src_reg.file = PROGRAM_CONSTANT;
1212 switch (ir->type->base_type) {
1213 case GLSL_TYPE_FLOAT:
1214 values = &ir->value.f[0];
1215 break;
1216 case GLSL_TYPE_UINT:
1217 for (i = 0; i < ir->type->vector_elements; i++) {
1218 values[i] = ir->value.u[i];
1219 }
1220 break;
1221 case GLSL_TYPE_INT:
1222 for (i = 0; i < ir->type->vector_elements; i++) {
1223 values[i] = ir->value.i[i];
1224 }
1225 break;
1226 case GLSL_TYPE_BOOL:
1227 for (i = 0; i < ir->type->vector_elements; i++) {
1228 values[i] = ir->value.b[i];
1229 }
1230 break;
1231 default:
1232 assert(!"Non-float/uint/int/bool constant");
1233 }
1234
1235 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
1236 values, ir->type->vector_elements,
1237 &src_reg.swizzle);
1238 src_reg.reladdr = false;
1239 src_reg.negate = 0;
1240
1241 this->result = src_reg;
1242 }
1243
1244
1245 void
1246 ir_to_mesa_visitor::visit(ir_call *ir)
1247 {
1248 printf("Can't support call to %s\n", ir->callee_name());
1249 exit(1);
1250 }
1251
1252
1253 void
1254 ir_to_mesa_visitor::visit(ir_texture *ir)
1255 {
1256 ir_to_mesa_src_reg result_src, coord;
1257 ir_to_mesa_dst_reg result_dst, lod_info;
1258 ir_to_mesa_instruction *inst = NULL;
1259
1260 ir->coordinate->accept(this);
1261 coord = this->result;
1262
1263 /* Storage for our result. Ideally for an assignment we'd be using
1264 * the actual storage for the result here, instead.
1265 */
1266 result_src = get_temp(glsl_type::vec4_type);
1267 result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1268
1269 switch (ir->op) {
1270 case ir_tex:
1271 inst = ir_to_mesa_emit_op1(ir, OPCODE_TEX, result_dst, coord);
1272 break;
1273 case ir_txb:
1274 /* Mesa IR stores bias in the last channel of the coords. */
1275 lod_info = ir_to_mesa_dst_reg_from_src(coord);
1276 lod_info.writemask = WRITEMASK_W;
1277 ir->lod_info.bias->accept(this);
1278 ir_to_mesa_emit_op1(ir, OPCODE_MOV, lod_info, this->result);
1279
1280 inst = ir_to_mesa_emit_op1(ir, OPCODE_TXB, result_dst, coord);
1281 break;
1282 case ir_txl:
1283 /* Mesa IR stores lod in the last channel of the coords. */
1284 lod_info = ir_to_mesa_dst_reg_from_src(coord);
1285 lod_info.writemask = WRITEMASK_W;
1286 ir->lod_info.lod->accept(this);
1287 ir_to_mesa_emit_op1(ir, OPCODE_MOV, lod_info, this->result);
1288
1289 inst = ir_to_mesa_emit_op1(ir, OPCODE_TXL, result_dst, coord);
1290 break;
1291 case ir_txd:
1292 case ir_txf:
1293 assert(!"GLSL 1.30 features unsupported");
1294 break;
1295 }
1296
1297 ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
1298 assert(sampler); /* FINISHME: sampler arrays */
1299 /* generate the mapping, remove when we generate storage at
1300 * declaration time
1301 */
1302 sampler->accept(this);
1303
1304 inst->sampler = get_sampler_number(sampler->var->location);
1305
1306 switch (sampler->type->sampler_dimensionality) {
1307 case GLSL_SAMPLER_DIM_1D:
1308 inst->tex_target = TEXTURE_1D_INDEX;
1309 break;
1310 case GLSL_SAMPLER_DIM_2D:
1311 inst->tex_target = TEXTURE_2D_INDEX;
1312 break;
1313 case GLSL_SAMPLER_DIM_3D:
1314 inst->tex_target = TEXTURE_3D_INDEX;
1315 break;
1316 case GLSL_SAMPLER_DIM_CUBE:
1317 inst->tex_target = TEXTURE_CUBE_INDEX;
1318 break;
1319 default:
1320 assert(!"FINISHME: other texture targets");
1321 }
1322
1323 assert(!ir->projector); /* FINISHME */
1324 assert(!ir->shadow_comparitor); /* FINISHME */
1325
1326 this->result = result_src;
1327 }
1328
1329 void
1330 ir_to_mesa_visitor::visit(ir_return *ir)
1331 {
1332 assert(0);
1333
1334 ir->get_value()->accept(this);
1335 }
1336
1337 void
1338 ir_to_mesa_visitor::visit(ir_discard *ir)
1339 {
1340 assert(0);
1341
1342 ir->condition->accept(this);
1343 }
1344
1345 void
1346 ir_to_mesa_visitor::visit(ir_if *ir)
1347 {
1348 ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
1349 ir_to_mesa_instruction *prev_inst;
1350
1351 prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1352
1353 ir->condition->accept(this);
1354 assert(this->result.file != PROGRAM_UNDEFINED);
1355
1356 if (ctx->Shader.EmitCondCodes) {
1357 cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1358
1359 /* See if we actually generated any instruction for generating
1360 * the condition. If not, then cook up a move to a temp so we
1361 * have something to set cond_update on.
1362 */
1363 if (cond_inst == prev_inst) {
1364 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
1365 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
1366 ir_to_mesa_dst_reg_from_src(temp),
1367 result);
1368 }
1369 cond_inst->cond_update = GL_TRUE;
1370
1371 if_inst = ir_to_mesa_emit_op1(ir->condition,
1372 OPCODE_IF, ir_to_mesa_undef_dst,
1373 ir_to_mesa_undef);
1374 if_inst->dst_reg.cond_mask = COND_NE;
1375 } else {
1376 if_inst = ir_to_mesa_emit_op1(ir->condition,
1377 OPCODE_IF, ir_to_mesa_undef_dst,
1378 this->result);
1379 }
1380
1381 this->instructions.push_tail(if_inst);
1382
1383 visit_exec_list(&ir->then_instructions, this);
1384
1385 if (!ir->else_instructions.is_empty()) {
1386 else_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ELSE,
1387 ir_to_mesa_undef_dst,
1388 ir_to_mesa_undef);
1389 visit_exec_list(&ir->else_instructions, this);
1390 }
1391
1392 if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
1393 ir_to_mesa_undef_dst, ir_to_mesa_undef);
1394 }
1395
1396 ir_to_mesa_visitor::ir_to_mesa_visitor()
1397 {
1398 result.file = PROGRAM_UNDEFINED;
1399 next_temp = 1;
1400 sampler_map = NULL;
1401 sampler_map_size = 0;
1402 }
1403
1404 static struct prog_src_register
1405 mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
1406 {
1407 struct prog_src_register mesa_reg;
1408
1409 mesa_reg.File = reg.file;
1410 assert(reg.index < (1 << INST_INDEX_BITS) - 1);
1411 mesa_reg.Index = reg.index;
1412 mesa_reg.Swizzle = reg.swizzle;
1413 mesa_reg.RelAddr = reg.reladdr;
1414 mesa_reg.Negate = reg.negate;
1415 mesa_reg.Abs = 0;
1416
1417 return mesa_reg;
1418 }
1419
1420 static void
1421 set_branchtargets(struct prog_instruction *mesa_instructions,
1422 int num_instructions)
1423 {
1424 int if_count = 0, loop_count;
1425 int *if_stack, *loop_stack;
1426 int if_stack_pos = 0, loop_stack_pos = 0;
1427 int i, j;
1428
1429 for (i = 0; i < num_instructions; i++) {
1430 switch (mesa_instructions[i].Opcode) {
1431 case OPCODE_IF:
1432 if_count++;
1433 break;
1434 case OPCODE_BGNLOOP:
1435 loop_count++;
1436 break;
1437 case OPCODE_BRK:
1438 case OPCODE_CONT:
1439 mesa_instructions[i].BranchTarget = -1;
1440 break;
1441 default:
1442 break;
1443 }
1444 }
1445
1446 if_stack = (int *)calloc(if_count, sizeof(*if_stack));
1447 loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
1448
1449 for (i = 0; i < num_instructions; i++) {
1450 switch (mesa_instructions[i].Opcode) {
1451 case OPCODE_IF:
1452 if_stack[if_stack_pos] = i;
1453 if_stack_pos++;
1454 break;
1455 case OPCODE_ELSE:
1456 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1457 if_stack[if_stack_pos - 1] = i;
1458 break;
1459 case OPCODE_ENDIF:
1460 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1461 if_stack_pos--;
1462 break;
1463 case OPCODE_BGNLOOP:
1464 loop_stack[loop_stack_pos] = i;
1465 loop_stack_pos++;
1466 break;
1467 case OPCODE_ENDLOOP:
1468 loop_stack_pos--;
1469 /* Rewrite any breaks/conts at this nesting level (haven't
1470 * already had a BranchTarget assigned) to point to the end
1471 * of the loop.
1472 */
1473 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
1474 if (mesa_instructions[j].Opcode == OPCODE_BRK ||
1475 mesa_instructions[j].Opcode == OPCODE_CONT) {
1476 if (mesa_instructions[j].BranchTarget == -1) {
1477 mesa_instructions[j].BranchTarget = i;
1478 }
1479 }
1480 }
1481 /* The loop ends point at each other. */
1482 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
1483 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
1484 default:
1485 break;
1486 }
1487 }
1488
1489 free(if_stack);
1490 }
1491
1492 static void
1493 print_program(struct prog_instruction *mesa_instructions,
1494 ir_instruction **mesa_instruction_annotation,
1495 int num_instructions)
1496 {
1497 ir_instruction *last_ir = NULL;
1498 int i;
1499
1500 for (i = 0; i < num_instructions; i++) {
1501 struct prog_instruction *mesa_inst = mesa_instructions + i;
1502 ir_instruction *ir = mesa_instruction_annotation[i];
1503
1504 if (last_ir != ir && ir) {
1505 ir_print_visitor print;
1506 ir->accept(&print);
1507 printf("\n");
1508 last_ir = ir;
1509 }
1510
1511 _mesa_print_instruction(mesa_inst);
1512 }
1513 }
1514
1515 static void
1516 count_resources(struct gl_program *prog)
1517 {
1518 unsigned int i;
1519
1520 prog->InputsRead = 0;
1521 prog->OutputsWritten = 0;
1522 prog->SamplersUsed = 0;
1523
1524 for (i = 0; i < prog->NumInstructions; i++) {
1525 struct prog_instruction *inst = &prog->Instructions[i];
1526 unsigned int reg;
1527
1528 switch (inst->DstReg.File) {
1529 case PROGRAM_OUTPUT:
1530 prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
1531 break;
1532 case PROGRAM_INPUT:
1533 prog->InputsRead |= BITFIELD64_BIT(inst->DstReg.Index);
1534 break;
1535 default:
1536 break;
1537 }
1538
1539 for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
1540 switch (inst->SrcReg[reg].File) {
1541 case PROGRAM_OUTPUT:
1542 prog->OutputsWritten |= BITFIELD64_BIT(inst->SrcReg[reg].Index);
1543 break;
1544 case PROGRAM_INPUT:
1545 prog->InputsRead |= BITFIELD64_BIT(inst->SrcReg[reg].Index);
1546 break;
1547 default:
1548 break;
1549 }
1550 }
1551
1552 /* Instead of just using the uniform's value to map to a
1553 * sampler, Mesa first allocates a separate number for the
1554 * sampler (_mesa_add_sampler), then we reindex it down to a
1555 * small integer (sampler_map[], SamplersUsed), then that gets
1556 * mapped to the uniform's value, and we get an actual sampler.
1557 */
1558 if (_mesa_is_tex_instruction(inst->Opcode)) {
1559 prog->SamplerTargets[inst->TexSrcUnit] =
1560 (gl_texture_index)inst->TexSrcTarget;
1561 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
1562 if (inst->TexShadow) {
1563 prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
1564 }
1565 }
1566 }
1567
1568 _mesa_update_shader_textures_used(prog);
1569 }
1570
1571 /* Each stage has some uniforms in its Parameters list. The Uniforms
1572 * list for the linked shader program has a pointer to these uniforms
1573 * in each of the stage's Parameters list, so that their values can be
1574 * updated when a uniform is set.
1575 */
1576 static void
1577 link_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
1578 struct gl_program *prog)
1579 {
1580 unsigned int i;
1581
1582 for (i = 0; i < prog->Parameters->NumParameters; i++) {
1583 const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
1584
1585 if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
1586 struct gl_uniform *uniform =
1587 _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
1588 if (uniform)
1589 uniform->Initialized = p->Initialized;
1590 }
1591 }
1592 }
1593
1594 struct gl_program *
1595 get_mesa_program(GLcontext *ctx, void *mem_ctx, struct gl_shader *shader)
1596 {
1597 ir_to_mesa_visitor v;
1598 struct prog_instruction *mesa_instructions, *mesa_inst;
1599 ir_instruction **mesa_instruction_annotation;
1600 int i;
1601 struct gl_program *prog;
1602 GLenum target;
1603
1604 switch (shader->Type) {
1605 case GL_VERTEX_SHADER: target = GL_VERTEX_PROGRAM_ARB; break;
1606 case GL_FRAGMENT_SHADER: target = GL_FRAGMENT_PROGRAM_ARB; break;
1607 default: assert(!"should not be reached"); break;
1608 }
1609
1610 prog = ctx->Driver.NewProgram(ctx, target, 1);
1611 if (!prog)
1612 return NULL;
1613 prog->Parameters = _mesa_new_parameter_list();
1614 prog->Varying = _mesa_new_parameter_list();
1615 prog->Attributes = _mesa_new_parameter_list();
1616 v.ctx = ctx;
1617 v.prog = prog;
1618
1619 v.mem_ctx = talloc_new(NULL);
1620 visit_exec_list(shader->ir, &v);
1621 v.ir_to_mesa_emit_op1(NULL, OPCODE_END,
1622 ir_to_mesa_undef_dst, ir_to_mesa_undef);
1623
1624 prog->NumTemporaries = v.next_temp;
1625
1626 int num_instructions = 0;
1627 foreach_iter(exec_list_iterator, iter, v.instructions) {
1628 num_instructions++;
1629 }
1630
1631 mesa_instructions =
1632 (struct prog_instruction *)calloc(num_instructions,
1633 sizeof(*mesa_instructions));
1634 mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
1635 num_instructions);
1636
1637 mesa_inst = mesa_instructions;
1638 i = 0;
1639 foreach_iter(exec_list_iterator, iter, v.instructions) {
1640 ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
1641
1642 mesa_inst->Opcode = inst->op;
1643 mesa_inst->CondUpdate = inst->cond_update;
1644 mesa_inst->DstReg.File = inst->dst_reg.file;
1645 mesa_inst->DstReg.Index = inst->dst_reg.index;
1646 mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
1647 mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
1648 mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
1649 mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
1650 mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
1651 mesa_inst->TexSrcUnit = inst->sampler;
1652 mesa_inst->TexSrcTarget = inst->tex_target;
1653 mesa_instruction_annotation[i] = inst->ir;
1654
1655 mesa_inst++;
1656 i++;
1657 }
1658
1659 set_branchtargets(mesa_instructions, num_instructions);
1660 if (0) {
1661 print_program(mesa_instructions, mesa_instruction_annotation,
1662 num_instructions);
1663 }
1664
1665 prog->Instructions = mesa_instructions;
1666 prog->NumInstructions = num_instructions;
1667
1668 _mesa_reference_program(ctx, &shader->Program, prog);
1669
1670 return prog;
1671 }
1672
1673 extern "C" {
1674
1675 static void
1676 steal_memory(ir_instruction *ir, void *new_ctx)
1677 {
1678 talloc_steal(new_ctx, ir);
1679 }
1680
1681 void
1682 _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
1683 {
1684 struct _mesa_glsl_parse_state *state;
1685
1686 state = talloc_zero(shader, struct _mesa_glsl_parse_state);
1687 switch (shader->Type) {
1688 case GL_VERTEX_SHADER: state->target = vertex_shader; break;
1689 case GL_FRAGMENT_SHADER: state->target = fragment_shader; break;
1690 case GL_GEOMETRY_SHADER: state->target = geometry_shader; break;
1691 }
1692
1693 state->scanner = NULL;
1694 state->translation_unit.make_empty();
1695 state->symbols = new(shader) glsl_symbol_table;
1696 state->info_log = talloc_strdup(shader, "");
1697 state->error = false;
1698 state->temp_index = 0;
1699 state->loop_or_switch_nesting = NULL;
1700 state->ARB_texture_rectangle_enable = true;
1701
1702 state->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
1703
1704 const char *source = shader->Source;
1705 state->error = preprocess(state, &source, &state->info_log);
1706
1707 if (!state->error) {
1708 _mesa_glsl_lexer_ctor(state, source);
1709 _mesa_glsl_parse(state);
1710 _mesa_glsl_lexer_dtor(state);
1711 }
1712
1713 shader->ir = new(shader) exec_list;
1714 if (!state->error && !state->translation_unit.is_empty())
1715 _mesa_ast_to_hir(shader->ir, state);
1716
1717 /* Optimization passes */
1718 if (!state->error && !shader->ir->is_empty()) {
1719 bool progress;
1720 do {
1721 progress = false;
1722
1723 progress = do_function_inlining(shader->ir) || progress;
1724 progress = do_if_simplification(shader->ir) || progress;
1725 progress = do_copy_propagation(shader->ir) || progress;
1726 progress = do_dead_code_local(shader->ir) || progress;
1727 progress = do_dead_code_unlinked(state, shader->ir) || progress;
1728 progress = do_constant_variable_unlinked(shader->ir) || progress;
1729 progress = do_constant_folding(shader->ir) || progress;
1730 progress = do_vec_index_to_swizzle(shader->ir) || progress;
1731 progress = do_swizzle_swizzle(shader->ir) || progress;
1732 } while (progress);
1733 }
1734
1735 shader->symbols = state->symbols;
1736
1737 shader->CompileStatus = !state->error;
1738 shader->InfoLog = state->info_log;
1739
1740 /* Retain any live IR, but trash the rest. */
1741 foreach_list(node, shader->ir) {
1742 visit_tree((ir_instruction *) node, steal_memory, shader);
1743 }
1744
1745 talloc_free(state);
1746 }
1747
1748 void
1749 _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
1750 {
1751 unsigned int i;
1752
1753 _mesa_clear_shader_program_data(ctx, prog);
1754
1755 prog->LinkStatus = GL_TRUE;
1756
1757 for (i = 0; i < prog->NumShaders; i++) {
1758 if (!prog->Shaders[i]->CompileStatus) {
1759 prog->InfoLog =
1760 talloc_asprintf_append(prog->InfoLog,
1761 "linking with uncompiled shader");
1762 prog->LinkStatus = GL_FALSE;
1763 }
1764 }
1765
1766 prog->Varying = _mesa_new_parameter_list();
1767 _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
1768 _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
1769
1770 if (prog->LinkStatus) {
1771 link_shaders(prog);
1772
1773 /* We don't use the linker's uniforms list, and cook up our own at
1774 * generate time.
1775 */
1776 free(prog->Uniforms);
1777 prog->Uniforms = _mesa_new_uniform_list();
1778 }
1779
1780 prog->LinkStatus = prog->LinkStatus;
1781
1782 /* FINISHME: This should use the linker-generated code */
1783 if (prog->LinkStatus) {
1784 for (i = 0; i < prog->NumShaders; i++) {
1785 struct gl_program *linked_prog;
1786
1787 linked_prog = get_mesa_program(ctx, prog,
1788 prog->Shaders[i]);
1789 count_resources(linked_prog);
1790
1791 link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
1792
1793 switch (prog->Shaders[i]->Type) {
1794 case GL_VERTEX_SHADER:
1795 _mesa_reference_vertprog(ctx, &prog->VertexProgram,
1796 (struct gl_vertex_program *)linked_prog);
1797 ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
1798 linked_prog);
1799 break;
1800 case GL_FRAGMENT_SHADER:
1801 _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
1802 (struct gl_fragment_program *)linked_prog);
1803 ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
1804 linked_prog);
1805 break;
1806 }
1807 }
1808 }
1809 }
1810
1811 } /* extern "C" */