ir_to_mesa: Set up our instruction nodes with zeroed data.
[mesa.git] / src / mesa / program / 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 "main/compiler.h"
35 #include "ir.h"
36 #include "ir_visitor.h"
37 #include "ir_print_visitor.h"
38 #include "ir_expression_flattening.h"
39 #include "glsl_types.h"
40 #include "glsl_parser_extras.h"
41 #include "../glsl/program.h"
42 #include "ir_optimization.h"
43 #include "ast.h"
44
45 extern "C" {
46 #include "main/mtypes.h"
47 #include "main/shaderapi.h"
48 #include "main/shaderobj.h"
49 #include "main/uniforms.h"
50 #include "program/hash_table.h"
51 #include "program/prog_instruction.h"
52 #include "program/prog_optimize.h"
53 #include "program/prog_print.h"
54 #include "program/program.h"
55 #include "program/prog_uniform.h"
56 #include "program/prog_parameter.h"
57 }
58
59 static int swizzle_for_size(int size);
60
61 /**
62 * This struct is a corresponding struct to Mesa prog_src_register, with
63 * wider fields.
64 */
65 typedef struct ir_to_mesa_src_reg {
66 ir_to_mesa_src_reg(int file, int index, const glsl_type *type)
67 {
68 this->file = file;
69 this->index = index;
70 if (type && (type->is_scalar() || type->is_vector() || type->is_matrix()))
71 this->swizzle = swizzle_for_size(type->vector_elements);
72 else
73 this->swizzle = SWIZZLE_XYZW;
74 this->negate = 0;
75 this->reladdr = NULL;
76 }
77
78 ir_to_mesa_src_reg()
79 {
80 this->file = PROGRAM_UNDEFINED;
81 this->index = 0;
82 this->swizzle = 0;
83 this->negate = 0;
84 this->reladdr = NULL;
85 }
86
87 int file; /**< PROGRAM_* from Mesa */
88 int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
89 GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
90 int negate; /**< NEGATE_XYZW mask from mesa */
91 /** Register index should be offset by the integer in this reg. */
92 ir_to_mesa_src_reg *reladdr;
93 } ir_to_mesa_src_reg;
94
95 typedef struct ir_to_mesa_dst_reg {
96 int file; /**< PROGRAM_* from Mesa */
97 int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
98 int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
99 GLuint cond_mask:4;
100 /** Register index should be offset by the integer in this reg. */
101 ir_to_mesa_src_reg *reladdr;
102 } ir_to_mesa_dst_reg;
103
104 extern ir_to_mesa_src_reg ir_to_mesa_undef;
105
106 class ir_to_mesa_instruction : public exec_node {
107 public:
108 /* Callers of this talloc-based new need not call delete. It's
109 * easier to just talloc_free 'ctx' (or any of its ancestors). */
110 static void* operator new(size_t size, void *ctx)
111 {
112 void *node;
113
114 node = talloc_zero_size(ctx, size);
115 assert(node != NULL);
116
117 return node;
118 }
119
120 enum prog_opcode op;
121 ir_to_mesa_dst_reg dst_reg;
122 ir_to_mesa_src_reg src_reg[3];
123 /** Pointer to the ir source this tree came from for debugging */
124 ir_instruction *ir;
125 GLboolean cond_update;
126 int sampler; /**< sampler index */
127 int tex_target; /**< One of TEXTURE_*_INDEX */
128 GLboolean tex_shadow;
129
130 class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
131 };
132
133 class variable_storage : public exec_node {
134 public:
135 variable_storage(ir_variable *var, int file, int index)
136 : file(file), index(index), var(var)
137 {
138 /* empty */
139 }
140
141 int file;
142 int index;
143 ir_variable *var; /* variable that maps to this, if any */
144 };
145
146 class function_entry : public exec_node {
147 public:
148 ir_function_signature *sig;
149
150 /**
151 * identifier of this function signature used by the program.
152 *
153 * At the point that Mesa instructions for function calls are
154 * generated, we don't know the address of the first instruction of
155 * the function body. So we make the BranchTarget that is called a
156 * small integer and rewrite them during set_branchtargets().
157 */
158 int sig_id;
159
160 /**
161 * Pointer to first instruction of the function body.
162 *
163 * Set during function body emits after main() is processed.
164 */
165 ir_to_mesa_instruction *bgn_inst;
166
167 /**
168 * Index of the first instruction of the function body in actual
169 * Mesa IR.
170 *
171 * Set after convertion from ir_to_mesa_instruction to prog_instruction.
172 */
173 int inst;
174
175 /** Storage for the return value. */
176 ir_to_mesa_src_reg return_reg;
177 };
178
179 class ir_to_mesa_visitor : public ir_visitor {
180 public:
181 ir_to_mesa_visitor();
182 ~ir_to_mesa_visitor();
183
184 function_entry *current_function;
185
186 GLcontext *ctx;
187 struct gl_program *prog;
188 struct gl_shader_program *shader_program;
189
190 int next_temp;
191
192 variable_storage *find_variable_storage(ir_variable *var);
193
194 function_entry *get_function_signature(ir_function_signature *sig);
195
196 ir_to_mesa_src_reg get_temp(const glsl_type *type);
197 void reladdr_to_temp(ir_instruction *ir,
198 ir_to_mesa_src_reg *reg, int *num_reladdr);
199
200 struct ir_to_mesa_src_reg src_reg_for_float(float val);
201
202 /**
203 * \name Visit methods
204 *
205 * As typical for the visitor pattern, there must be one \c visit method for
206 * each concrete subclass of \c ir_instruction. Virtual base classes within
207 * the hierarchy should not have \c visit methods.
208 */
209 /*@{*/
210 virtual void visit(ir_variable *);
211 virtual void visit(ir_loop *);
212 virtual void visit(ir_loop_jump *);
213 virtual void visit(ir_function_signature *);
214 virtual void visit(ir_function *);
215 virtual void visit(ir_expression *);
216 virtual void visit(ir_swizzle *);
217 virtual void visit(ir_dereference_variable *);
218 virtual void visit(ir_dereference_array *);
219 virtual void visit(ir_dereference_record *);
220 virtual void visit(ir_assignment *);
221 virtual void visit(ir_constant *);
222 virtual void visit(ir_call *);
223 virtual void visit(ir_return *);
224 virtual void visit(ir_discard *);
225 virtual void visit(ir_texture *);
226 virtual void visit(ir_if *);
227 /*@}*/
228
229 struct ir_to_mesa_src_reg result;
230
231 /** List of variable_storage */
232 exec_list variables;
233
234 /** List of function_entry */
235 exec_list function_signatures;
236 int next_signature_id;
237
238 /** List of ir_to_mesa_instruction */
239 exec_list instructions;
240
241 ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
242 enum prog_opcode op);
243
244 ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
245 enum prog_opcode op,
246 ir_to_mesa_dst_reg dst,
247 ir_to_mesa_src_reg src0);
248
249 ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
250 enum prog_opcode op,
251 ir_to_mesa_dst_reg dst,
252 ir_to_mesa_src_reg src0,
253 ir_to_mesa_src_reg src1);
254
255 ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
256 enum prog_opcode op,
257 ir_to_mesa_dst_reg dst,
258 ir_to_mesa_src_reg src0,
259 ir_to_mesa_src_reg src1,
260 ir_to_mesa_src_reg src2);
261
262 void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
263 enum prog_opcode op,
264 ir_to_mesa_dst_reg dst,
265 ir_to_mesa_src_reg src0);
266
267 void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
268 enum prog_opcode op,
269 ir_to_mesa_dst_reg dst,
270 ir_to_mesa_src_reg src0,
271 ir_to_mesa_src_reg src1);
272
273 GLboolean try_emit_mad(ir_expression *ir,
274 int mul_operand);
275
276 int get_sampler_uniform_value(ir_dereference *deref);
277
278 void *mem_ctx;
279 };
280
281 ir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL);
282
283 ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
284 PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
285 };
286
287 ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
288 PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
289 };
290
291 static int swizzle_for_size(int size)
292 {
293 int size_swizzles[4] = {
294 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
295 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
296 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
297 MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
298 };
299
300 return size_swizzles[size - 1];
301 }
302
303 ir_to_mesa_instruction *
304 ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
305 enum prog_opcode op,
306 ir_to_mesa_dst_reg dst,
307 ir_to_mesa_src_reg src0,
308 ir_to_mesa_src_reg src1,
309 ir_to_mesa_src_reg src2)
310 {
311 ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
312 int num_reladdr = 0;
313
314 /* If we have to do relative addressing, we want to load the ARL
315 * reg directly for one of the regs, and preload the other reladdr
316 * sources into temps.
317 */
318 num_reladdr += dst.reladdr != NULL;
319 num_reladdr += src0.reladdr != NULL;
320 num_reladdr += src1.reladdr != NULL;
321 num_reladdr += src2.reladdr != NULL;
322
323 reladdr_to_temp(ir, &src2, &num_reladdr);
324 reladdr_to_temp(ir, &src1, &num_reladdr);
325 reladdr_to_temp(ir, &src0, &num_reladdr);
326
327 if (dst.reladdr) {
328 ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
329 *dst.reladdr);
330
331 num_reladdr--;
332 }
333 assert(num_reladdr == 0);
334
335 inst->op = op;
336 inst->dst_reg = dst;
337 inst->src_reg[0] = src0;
338 inst->src_reg[1] = src1;
339 inst->src_reg[2] = src2;
340 inst->ir = ir;
341
342 inst->function = NULL;
343
344 this->instructions.push_tail(inst);
345
346 return inst;
347 }
348
349
350 ir_to_mesa_instruction *
351 ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
352 enum prog_opcode op,
353 ir_to_mesa_dst_reg dst,
354 ir_to_mesa_src_reg src0,
355 ir_to_mesa_src_reg src1)
356 {
357 return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
358 }
359
360 ir_to_mesa_instruction *
361 ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
362 enum prog_opcode op,
363 ir_to_mesa_dst_reg dst,
364 ir_to_mesa_src_reg src0)
365 {
366 assert(dst.writemask != 0);
367 return ir_to_mesa_emit_op3(ir, op, dst,
368 src0, ir_to_mesa_undef, ir_to_mesa_undef);
369 }
370
371 ir_to_mesa_instruction *
372 ir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
373 enum prog_opcode op)
374 {
375 return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
376 ir_to_mesa_undef,
377 ir_to_mesa_undef,
378 ir_to_mesa_undef);
379 }
380
381 inline ir_to_mesa_dst_reg
382 ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
383 {
384 ir_to_mesa_dst_reg dst_reg;
385
386 dst_reg.file = reg.file;
387 dst_reg.index = reg.index;
388 dst_reg.writemask = WRITEMASK_XYZW;
389 dst_reg.cond_mask = COND_TR;
390 dst_reg.reladdr = reg.reladdr;
391
392 return dst_reg;
393 }
394
395 inline ir_to_mesa_src_reg
396 ir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
397 {
398 return ir_to_mesa_src_reg(reg.file, reg.index, NULL);
399 }
400
401 /**
402 * Emits Mesa scalar opcodes to produce unique answers across channels.
403 *
404 * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X
405 * channel determines the result across all channels. So to do a vec4
406 * of this operation, we want to emit a scalar per source channel used
407 * to produce dest channels.
408 */
409 void
410 ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
411 enum prog_opcode op,
412 ir_to_mesa_dst_reg dst,
413 ir_to_mesa_src_reg orig_src0,
414 ir_to_mesa_src_reg orig_src1)
415 {
416 int i, j;
417 int done_mask = ~dst.writemask;
418
419 /* Mesa RCP is a scalar operation splatting results to all channels,
420 * like ARB_fp/vp. So emit as many RCPs as necessary to cover our
421 * dst channels.
422 */
423 for (i = 0; i < 4; i++) {
424 GLuint this_mask = (1 << i);
425 ir_to_mesa_instruction *inst;
426 ir_to_mesa_src_reg src0 = orig_src0;
427 ir_to_mesa_src_reg src1 = orig_src1;
428
429 if (done_mask & this_mask)
430 continue;
431
432 GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
433 GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
434 for (j = i + 1; j < 4; j++) {
435 if (!(done_mask & (1 << j)) &&
436 GET_SWZ(src0.swizzle, j) == src0_swiz &&
437 GET_SWZ(src1.swizzle, j) == src1_swiz) {
438 this_mask |= (1 << j);
439 }
440 }
441 src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
442 src0_swiz, src0_swiz);
443 src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
444 src1_swiz, src1_swiz);
445
446 inst = ir_to_mesa_emit_op2(ir, op,
447 dst,
448 src0,
449 src1);
450 inst->dst_reg.writemask = this_mask;
451 done_mask |= this_mask;
452 }
453 }
454
455 void
456 ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
457 enum prog_opcode op,
458 ir_to_mesa_dst_reg dst,
459 ir_to_mesa_src_reg src0)
460 {
461 ir_to_mesa_src_reg undef = ir_to_mesa_undef;
462
463 undef.swizzle = SWIZZLE_XXXX;
464
465 ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
466 }
467
468 struct ir_to_mesa_src_reg
469 ir_to_mesa_visitor::src_reg_for_float(float val)
470 {
471 ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL);
472
473 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
474 &val, 1, &src_reg.swizzle);
475
476 return src_reg;
477 }
478
479 static int
480 type_size(const struct glsl_type *type)
481 {
482 unsigned int i;
483 int size;
484
485 switch (type->base_type) {
486 case GLSL_TYPE_UINT:
487 case GLSL_TYPE_INT:
488 case GLSL_TYPE_FLOAT:
489 case GLSL_TYPE_BOOL:
490 if (type->is_matrix()) {
491 return type->matrix_columns;
492 } else {
493 /* Regardless of size of vector, it gets a vec4. This is bad
494 * packing for things like floats, but otherwise arrays become a
495 * mess. Hopefully a later pass over the code can pack scalars
496 * down if appropriate.
497 */
498 return 1;
499 }
500 case GLSL_TYPE_ARRAY:
501 return type_size(type->fields.array) * type->length;
502 case GLSL_TYPE_STRUCT:
503 size = 0;
504 for (i = 0; i < type->length; i++) {
505 size += type_size(type->fields.structure[i].type);
506 }
507 return size;
508 case GLSL_TYPE_SAMPLER:
509 /* Samplers take up one slot in UNIFORMS[], but they're baked in
510 * at link time.
511 */
512 return 1;
513 default:
514 assert(0);
515 return 0;
516 }
517 }
518
519 /**
520 * In the initial pass of codegen, we assign temporary numbers to
521 * intermediate results. (not SSA -- variable assignments will reuse
522 * storage). Actual register allocation for the Mesa VM occurs in a
523 * pass over the Mesa IR later.
524 */
525 ir_to_mesa_src_reg
526 ir_to_mesa_visitor::get_temp(const glsl_type *type)
527 {
528 ir_to_mesa_src_reg src_reg;
529 int swizzle[4];
530 int i;
531
532 src_reg.file = PROGRAM_TEMPORARY;
533 src_reg.index = next_temp;
534 src_reg.reladdr = NULL;
535 next_temp += type_size(type);
536
537 if (type->is_array() || type->is_record()) {
538 src_reg.swizzle = SWIZZLE_NOOP;
539 } else {
540 for (i = 0; i < type->vector_elements; i++)
541 swizzle[i] = i;
542 for (; i < 4; i++)
543 swizzle[i] = type->vector_elements - 1;
544 src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
545 swizzle[2], swizzle[3]);
546 }
547 src_reg.negate = 0;
548
549 return src_reg;
550 }
551
552 variable_storage *
553 ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
554 {
555
556 variable_storage *entry;
557
558 foreach_iter(exec_list_iterator, iter, this->variables) {
559 entry = (variable_storage *)iter.get();
560
561 if (entry->var == var)
562 return entry;
563 }
564
565 return NULL;
566 }
567
568 void
569 ir_to_mesa_visitor::visit(ir_variable *ir)
570 {
571 if (strcmp(ir->name, "gl_FragCoord") == 0) {
572 struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
573
574 fp->OriginUpperLeft = ir->origin_upper_left;
575 fp->PixelCenterInteger = ir->pixel_center_integer;
576 }
577 }
578
579 void
580 ir_to_mesa_visitor::visit(ir_loop *ir)
581 {
582 assert(!ir->from);
583 assert(!ir->to);
584 assert(!ir->increment);
585 assert(!ir->counter);
586
587 ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
588 visit_exec_list(&ir->body_instructions, this);
589 ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
590 }
591
592 void
593 ir_to_mesa_visitor::visit(ir_loop_jump *ir)
594 {
595 switch (ir->mode) {
596 case ir_loop_jump::jump_break:
597 ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
598 break;
599 case ir_loop_jump::jump_continue:
600 ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
601 break;
602 }
603 }
604
605
606 void
607 ir_to_mesa_visitor::visit(ir_function_signature *ir)
608 {
609 assert(0);
610 (void)ir;
611 }
612
613 void
614 ir_to_mesa_visitor::visit(ir_function *ir)
615 {
616 /* Ignore function bodies other than main() -- we shouldn't see calls to
617 * them since they should all be inlined before we get to ir_to_mesa.
618 */
619 if (strcmp(ir->name, "main") == 0) {
620 const ir_function_signature *sig;
621 exec_list empty;
622
623 sig = ir->matching_signature(&empty);
624
625 assert(sig);
626
627 foreach_iter(exec_list_iterator, iter, sig->body) {
628 ir_instruction *ir = (ir_instruction *)iter.get();
629
630 ir->accept(this);
631 }
632 }
633 }
634
635 GLboolean
636 ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
637 {
638 int nonmul_operand = 1 - mul_operand;
639 ir_to_mesa_src_reg a, b, c;
640
641 ir_expression *expr = ir->operands[mul_operand]->as_expression();
642 if (!expr || expr->operation != ir_binop_mul)
643 return false;
644
645 expr->operands[0]->accept(this);
646 a = this->result;
647 expr->operands[1]->accept(this);
648 b = this->result;
649 ir->operands[nonmul_operand]->accept(this);
650 c = this->result;
651
652 this->result = get_temp(ir->type);
653 ir_to_mesa_emit_op3(ir, OPCODE_MAD,
654 ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
655
656 return true;
657 }
658
659 void
660 ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
661 ir_to_mesa_src_reg *reg, int *num_reladdr)
662 {
663 if (!reg->reladdr)
664 return;
665
666 ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
667
668 if (*num_reladdr != 1) {
669 ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
670
671 ir_to_mesa_emit_op1(ir, OPCODE_MOV,
672 ir_to_mesa_dst_reg_from_src(temp), *reg);
673 *reg = temp;
674 }
675
676 (*num_reladdr)--;
677 }
678
679 void
680 ir_to_mesa_visitor::visit(ir_expression *ir)
681 {
682 unsigned int operand;
683 struct ir_to_mesa_src_reg op[2];
684 struct ir_to_mesa_src_reg result_src;
685 struct ir_to_mesa_dst_reg result_dst;
686 const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
687 const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
688 const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
689
690 /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
691 */
692 if (ir->operation == ir_binop_add) {
693 if (try_emit_mad(ir, 1))
694 return;
695 if (try_emit_mad(ir, 0))
696 return;
697 }
698
699 for (operand = 0; operand < ir->get_num_operands(); operand++) {
700 this->result.file = PROGRAM_UNDEFINED;
701 ir->operands[operand]->accept(this);
702 if (this->result.file == PROGRAM_UNDEFINED) {
703 ir_print_visitor v;
704 printf("Failed to get tree for expression operand:\n");
705 ir->operands[operand]->accept(&v);
706 exit(1);
707 }
708 op[operand] = this->result;
709
710 /* Matrix expression operands should have been broken down to vector
711 * operations already.
712 */
713 assert(!ir->operands[operand]->type->is_matrix());
714 }
715
716 this->result.file = PROGRAM_UNDEFINED;
717
718 /* Storage for our result. Ideally for an assignment we'd be using
719 * the actual storage for the result here, instead.
720 */
721 result_src = get_temp(ir->type);
722 /* convenience for the emit functions below. */
723 result_dst = ir_to_mesa_dst_reg_from_src(result_src);
724 /* Limit writes to the channels that will be used by result_src later.
725 * This does limit this temp's use as a temporary for multi-instruction
726 * sequences.
727 */
728 result_dst.writemask = (1 << ir->type->vector_elements) - 1;
729
730 switch (ir->operation) {
731 case ir_unop_logic_not:
732 ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
733 op[0], src_reg_for_float(0.0));
734 break;
735 case ir_unop_neg:
736 op[0].negate = ~op[0].negate;
737 result_src = op[0];
738 break;
739 case ir_unop_abs:
740 ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
741 break;
742 case ir_unop_sign:
743 ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
744 break;
745 case ir_unop_rcp:
746 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
747 break;
748
749 case ir_unop_exp2:
750 ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
751 break;
752 case ir_unop_exp:
753 case ir_unop_log:
754 assert(!"not reached: should be handled by ir_explog_to_explog2");
755 break;
756 case ir_unop_log2:
757 ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
758 break;
759 case ir_unop_sin:
760 ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
761 break;
762 case ir_unop_cos:
763 ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
764 break;
765
766 case ir_unop_dFdx:
767 ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
768 break;
769 case ir_unop_dFdy:
770 ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
771 break;
772
773 case ir_binop_add:
774 ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
775 break;
776 case ir_binop_sub:
777 ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
778 break;
779
780 case ir_binop_mul:
781 ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
782 break;
783 case ir_binop_div:
784 assert(!"not reached: should be handled by ir_div_to_mul_rcp");
785 case ir_binop_mod:
786 assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
787 break;
788
789 case ir_binop_less:
790 ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
791 break;
792 case ir_binop_greater:
793 ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
794 break;
795 case ir_binop_lequal:
796 ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
797 break;
798 case ir_binop_gequal:
799 ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
800 break;
801 case ir_binop_equal:
802 /* "==" operator producing a scalar boolean. */
803 if (ir->operands[0]->type->is_vector() ||
804 ir->operands[1]->type->is_vector()) {
805 ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
806 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
807 ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
808 ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
809 ir_to_mesa_emit_op2(ir, OPCODE_SEQ,
810 result_dst, result_src, src_reg_for_float(0.0));
811 } else {
812 ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
813 }
814 break;
815 case ir_binop_nequal:
816 /* "!=" operator producing a scalar boolean. */
817 if (ir->operands[0]->type->is_vector() ||
818 ir->operands[1]->type->is_vector()) {
819 ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
820 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
821 ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
822 ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
823 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
824 result_dst, result_src, src_reg_for_float(0.0));
825 } else {
826 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
827 }
828 break;
829
830 case ir_unop_any:
831 switch (ir->operands[0]->type->vector_elements) {
832 case 4:
833 ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, op[0], op[0]);
834 break;
835 case 3:
836 ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, op[0], op[0]);
837 break;
838 case 2:
839 ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, op[0], op[0]);
840 break;
841 default:
842 assert(!"unreached: ir_unop_any of non-bvec");
843 break;
844 }
845 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
846 result_dst, result_src, src_reg_for_float(0.0));
847 break;
848
849 case ir_binop_logic_xor:
850 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
851 break;
852
853 case ir_binop_logic_or:
854 /* This could be a saturated add and skip the SNE. */
855 ir_to_mesa_emit_op2(ir, OPCODE_ADD,
856 result_dst,
857 op[0], op[1]);
858
859 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
860 result_dst,
861 result_src, src_reg_for_float(0.0));
862 break;
863
864 case ir_binop_logic_and:
865 /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
866 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
867 result_dst,
868 op[0], op[1]);
869 break;
870
871 case ir_binop_dot:
872 if (ir->operands[0]->type == vec4_type) {
873 assert(ir->operands[1]->type == vec4_type);
874 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
875 result_dst,
876 op[0], op[1]);
877 } else if (ir->operands[0]->type == vec3_type) {
878 assert(ir->operands[1]->type == vec3_type);
879 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
880 result_dst,
881 op[0], op[1]);
882 } else if (ir->operands[0]->type == vec2_type) {
883 assert(ir->operands[1]->type == vec2_type);
884 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
885 result_dst,
886 op[0], op[1]);
887 }
888 break;
889
890 case ir_binop_cross:
891 ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
892 break;
893
894 case ir_unop_sqrt:
895 /* sqrt(x) = x * rsq(x). */
896 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
897 ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, result_src, op[0]);
898 /* For incoming channels < 0, set the result to 0. */
899 ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
900 op[0], src_reg_for_float(0.0), result_src);
901 break;
902 case ir_unop_rsq:
903 ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
904 break;
905 case ir_unop_i2f:
906 case ir_unop_b2f:
907 case ir_unop_b2i:
908 /* Mesa IR lacks types, ints are stored as truncated floats. */
909 result_src = op[0];
910 break;
911 case ir_unop_f2i:
912 ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
913 break;
914 case ir_unop_f2b:
915 case ir_unop_i2b:
916 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
917 op[0], src_reg_for_float(0.0));
918 break;
919 case ir_unop_trunc:
920 ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
921 break;
922 case ir_unop_ceil:
923 op[0].negate = ~op[0].negate;
924 ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
925 result_src.negate = ~result_src.negate;
926 break;
927 case ir_unop_floor:
928 ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
929 break;
930 case ir_unop_fract:
931 ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
932 break;
933
934 case ir_binop_min:
935 ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
936 break;
937 case ir_binop_max:
938 ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
939 break;
940 case ir_binop_pow:
941 ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
942 break;
943
944 case ir_unop_bit_not:
945 case ir_unop_u2f:
946 case ir_binop_lshift:
947 case ir_binop_rshift:
948 case ir_binop_bit_and:
949 case ir_binop_bit_xor:
950 case ir_binop_bit_or:
951 assert(!"GLSL 1.30 features unsupported");
952 break;
953 }
954
955 this->result = result_src;
956 }
957
958
959 void
960 ir_to_mesa_visitor::visit(ir_swizzle *ir)
961 {
962 ir_to_mesa_src_reg src_reg;
963 int i;
964 int swizzle[4];
965
966 /* Note that this is only swizzles in expressions, not those on the left
967 * hand side of an assignment, which do write masking. See ir_assignment
968 * for that.
969 */
970
971 ir->val->accept(this);
972 src_reg = this->result;
973 assert(src_reg.file != PROGRAM_UNDEFINED);
974
975 for (i = 0; i < 4; i++) {
976 if (i < ir->type->vector_elements) {
977 switch (i) {
978 case 0:
979 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
980 break;
981 case 1:
982 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
983 break;
984 case 2:
985 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
986 break;
987 case 3:
988 swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
989 break;
990 }
991 } else {
992 /* If the type is smaller than a vec4, replicate the last
993 * channel out.
994 */
995 swizzle[i] = swizzle[ir->type->vector_elements - 1];
996 }
997 }
998
999 src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
1000 swizzle[1],
1001 swizzle[2],
1002 swizzle[3]);
1003
1004 this->result = src_reg;
1005 }
1006
1007 static const struct {
1008 const char *name;
1009 const char *field;
1010 int tokens[STATE_LENGTH];
1011 int swizzle;
1012 bool array_indexed;
1013 } statevars[] = {
1014 {"gl_DepthRange", "near",
1015 {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX, false},
1016 {"gl_DepthRange", "far",
1017 {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY, false},
1018 {"gl_DepthRange", "diff",
1019 {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ, false},
1020
1021 {"gl_ClipPlane", NULL,
1022 {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW, true}
1023 ,
1024 {"gl_Point", "size",
1025 {STATE_POINT_SIZE}, SWIZZLE_XXXX, false},
1026 {"gl_Point", "sizeMin",
1027 {STATE_POINT_SIZE}, SWIZZLE_YYYY, false},
1028 {"gl_Point", "sizeMax",
1029 {STATE_POINT_SIZE}, SWIZZLE_ZZZZ, false},
1030 {"gl_Point", "fadeThresholdSize",
1031 {STATE_POINT_SIZE}, SWIZZLE_WWWW, false},
1032 {"gl_Point", "distanceConstantAttenuation",
1033 {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX, false},
1034 {"gl_Point", "distanceLinearAttenuation",
1035 {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY, false},
1036 {"gl_Point", "distanceQuadraticAttenuation",
1037 {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ, false},
1038
1039 {"gl_FrontMaterial", "emission",
1040 {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW, false},
1041 {"gl_FrontMaterial", "ambient",
1042 {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW, false},
1043 {"gl_FrontMaterial", "diffuse",
1044 {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, false},
1045 {"gl_FrontMaterial", "specular",
1046 {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW, false},
1047 {"gl_FrontMaterial", "shininess",
1048 {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX, false},
1049
1050 {"gl_BackMaterial", "emission",
1051 {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW, false},
1052 {"gl_BackMaterial", "ambient",
1053 {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW, false},
1054 {"gl_BackMaterial", "diffuse",
1055 {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, false},
1056 {"gl_BackMaterial", "specular",
1057 {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW, false},
1058 {"gl_BackMaterial", "shininess",
1059 {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX, false},
1060
1061 {"gl_LightSource", "ambient",
1062 {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1063 {"gl_LightSource", "diffuse",
1064 {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1065 {"gl_LightSource", "specular",
1066 {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1067 {"gl_LightSource", "position",
1068 {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW, true},
1069 {"gl_LightSource", "halfVector",
1070 {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW, true},
1071 {"gl_LightSource", "spotDirection",
1072 {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW, true},
1073 {"gl_LightSource", "spotCosCutoff",
1074 {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW, true},
1075 {"gl_LightSource", "spotCutoff",
1076 {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX, true},
1077 {"gl_LightSource", "spotExponent",
1078 {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW, true},
1079 {"gl_LightSource", "constantAttenuation",
1080 {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX, true},
1081 {"gl_LightSource", "linearAttenuation",
1082 {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY, true},
1083 {"gl_LightSource", "quadraticAttenuation",
1084 {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ, true},
1085
1086 {"gl_LightModel", "ambient",
1087 {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW, false},
1088
1089 {"gl_FrontLightModelProduct", "sceneColor",
1090 {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW, false},
1091 {"gl_BackLightModelProduct", "sceneColor",
1092 {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW, false},
1093
1094 {"gl_FrontLightProduct", "ambient",
1095 {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1096 {"gl_FrontLightProduct", "diffuse",
1097 {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1098 {"gl_FrontLightProduct", "specular",
1099 {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1100
1101 {"gl_BackLightProduct", "ambient",
1102 {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1103 {"gl_BackLightProduct", "diffuse",
1104 {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1105 {"gl_BackLightProduct", "specular",
1106 {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1107
1108 {"gl_TextureEnvColor", NULL,
1109 {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW, true},
1110
1111 {"gl_EyePlaneS", NULL,
1112 {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW, true},
1113 {"gl_EyePlaneT", NULL,
1114 {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW, true},
1115 {"gl_EyePlaneR", NULL,
1116 {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW, true},
1117 {"gl_EyePlaneQ", NULL,
1118 {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW, true},
1119
1120 {"gl_ObjectPlaneS", NULL,
1121 {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW, true},
1122 {"gl_ObjectPlaneT", NULL,
1123 {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW, true},
1124 {"gl_ObjectPlaneR", NULL,
1125 {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW, true},
1126 {"gl_ObjectPlaneQ", NULL,
1127 {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW, true},
1128
1129 {"gl_Fog", "color",
1130 {STATE_FOG_COLOR}, SWIZZLE_XYZW, false},
1131 {"gl_Fog", "density",
1132 {STATE_FOG_PARAMS}, SWIZZLE_XXXX, false},
1133 {"gl_Fog", "start",
1134 {STATE_FOG_PARAMS}, SWIZZLE_YYYY, false},
1135 {"gl_Fog", "end",
1136 {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ, false},
1137 {"gl_Fog", "scale",
1138 {STATE_FOG_PARAMS}, SWIZZLE_WWWW, false},
1139 };
1140
1141 static ir_to_mesa_src_reg
1142 get_builtin_uniform_reg(struct gl_program *prog,
1143 const char *name, int array_index, const char *field)
1144 {
1145 unsigned int i;
1146 ir_to_mesa_src_reg src_reg;
1147 int tokens[STATE_LENGTH];
1148
1149 for (i = 0; i < Elements(statevars); i++) {
1150 if (strcmp(statevars[i].name, name) != 0)
1151 continue;
1152 if (!field && statevars[i].field) {
1153 assert(!"FINISHME: whole-structure state var dereference");
1154 }
1155 if (field && (!statevars[i].field || strcmp(statevars[i].field, field) != 0))
1156 continue;
1157 break;
1158 }
1159
1160 if (i == Elements(statevars)) {
1161 printf("builtin uniform %s%s%s not found\n",
1162 name,
1163 field ? "." : "",
1164 field ? field : "");
1165 abort();
1166 }
1167
1168 memcpy(&tokens, statevars[i].tokens, sizeof(tokens));
1169 if (statevars[i].array_indexed)
1170 tokens[1] = array_index;
1171
1172 src_reg.file = PROGRAM_STATE_VAR;
1173 src_reg.index = _mesa_add_state_reference(prog->Parameters,
1174 (gl_state_index *)tokens);
1175 src_reg.swizzle = statevars[i].swizzle;
1176 src_reg.negate = 0;
1177 src_reg.reladdr = false;
1178
1179 return src_reg;
1180 }
1181
1182 static int
1183 add_matrix_ref(struct gl_program *prog, int *tokens)
1184 {
1185 int base_pos = -1;
1186 int i;
1187
1188 /* Add a ref for each column. It looks like the reason we do
1189 * it this way is that _mesa_add_state_reference doesn't work
1190 * for things that aren't vec4s, so the tokens[2]/tokens[3]
1191 * range has to be equal.
1192 */
1193 for (i = 0; i < 4; i++) {
1194 tokens[2] = i;
1195 tokens[3] = i;
1196 int pos = _mesa_add_state_reference(prog->Parameters,
1197 (gl_state_index *)tokens);
1198 if (base_pos == -1)
1199 base_pos = pos;
1200 else
1201 assert(base_pos + i == pos);
1202 }
1203
1204 return base_pos;
1205 }
1206
1207 static variable_storage *
1208 get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
1209 ir_rvalue *array_index)
1210 {
1211 /*
1212 * NOTE: The ARB_vertex_program extension specified that matrices get
1213 * loaded in registers in row-major order. With GLSL, we want column-
1214 * major order. So, we need to transpose all matrices here...
1215 */
1216 static const struct {
1217 const char *name;
1218 int matrix;
1219 int modifier;
1220 } matrices[] = {
1221 { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
1222 { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
1223 { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
1224 { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1225
1226 { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
1227 { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
1228 { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
1229 { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
1230
1231 { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
1232 { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
1233 { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
1234 { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
1235
1236 { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
1237 { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
1238 { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
1239 { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
1240
1241 { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1242
1243 };
1244 unsigned int i;
1245 variable_storage *entry;
1246
1247 /* C++ gets angry when we try to use an int as a gl_state_index, so we use
1248 * ints for gl_state_index. Make sure they're compatible.
1249 */
1250 assert(sizeof(gl_state_index) == sizeof(int));
1251
1252 for (i = 0; i < Elements(matrices); i++) {
1253 if (strcmp(var->name, matrices[i].name) == 0) {
1254 int tokens[STATE_LENGTH];
1255 int base_pos = -1;
1256
1257 tokens[0] = matrices[i].matrix;
1258 tokens[4] = matrices[i].modifier;
1259 if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
1260 ir_constant *index = array_index->constant_expression_value();
1261 if (index) {
1262 tokens[1] = index->value.i[0];
1263 base_pos = add_matrix_ref(prog, tokens);
1264 } else {
1265 for (i = 0; i < var->type->length; i++) {
1266 tokens[1] = i;
1267 int pos = add_matrix_ref(prog, tokens);
1268 if (base_pos == -1)
1269 base_pos = pos;
1270 else
1271 assert(base_pos + (int)i * 4 == pos);
1272 }
1273 }
1274 } else {
1275 tokens[1] = 0; /* unused array index */
1276 base_pos = add_matrix_ref(prog, tokens);
1277 }
1278
1279 entry = new(mem_ctx) variable_storage(var,
1280 PROGRAM_STATE_VAR,
1281 base_pos);
1282
1283 return entry;
1284 }
1285 }
1286
1287 return NULL;
1288 }
1289
1290 void
1291 ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
1292 {
1293 variable_storage *entry = find_variable_storage(ir->var);
1294
1295 if (!entry) {
1296 switch (ir->var->mode) {
1297 case ir_var_uniform:
1298 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
1299 NULL);
1300 if (entry)
1301 break;
1302
1303 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM,
1304 ir->var->location);
1305 this->variables.push_tail(entry);
1306 break;
1307 case ir_var_in:
1308 case ir_var_out:
1309 case ir_var_inout:
1310 /* The linker assigns locations for varyings and attributes,
1311 * including deprecated builtins (like gl_Color), user-assign
1312 * generic attributes (glBindVertexLocation), and
1313 * user-defined varyings.
1314 *
1315 * FINISHME: We would hit this path for function arguments. Fix!
1316 */
1317 assert(ir->var->location != -1);
1318 if (ir->var->mode == ir_var_in ||
1319 ir->var->mode == ir_var_inout) {
1320 entry = new(mem_ctx) variable_storage(ir->var,
1321 PROGRAM_INPUT,
1322 ir->var->location);
1323
1324 if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1325 ir->var->location >= VERT_ATTRIB_GENERIC0) {
1326 _mesa_add_attribute(prog->Attributes,
1327 ir->var->name,
1328 _mesa_sizeof_glsl_type(ir->var->type->gl_type),
1329 ir->var->type->gl_type,
1330 ir->var->location - VERT_ATTRIB_GENERIC0);
1331 }
1332 } else {
1333 entry = new(mem_ctx) variable_storage(ir->var,
1334 PROGRAM_OUTPUT,
1335 ir->var->location);
1336 }
1337
1338 break;
1339 case ir_var_auto:
1340 case ir_var_temporary:
1341 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
1342 this->next_temp);
1343 this->variables.push_tail(entry);
1344
1345 next_temp += type_size(ir->var->type);
1346 break;
1347 }
1348
1349 if (!entry) {
1350 printf("Failed to make storage for %s\n", ir->var->name);
1351 exit(1);
1352 }
1353 }
1354
1355 this->result = ir_to_mesa_src_reg(entry->file, entry->index, ir->var->type);
1356 }
1357
1358 void
1359 ir_to_mesa_visitor::visit(ir_dereference_array *ir)
1360 {
1361 ir_variable *var = ir->variable_referenced();
1362 ir_constant *index;
1363 ir_to_mesa_src_reg src_reg;
1364 ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
1365 int element_size = type_size(ir->type);
1366
1367 index = ir->array_index->constant_expression_value();
1368
1369 if (deref_var && strncmp(deref_var->var->name,
1370 "gl_TextureMatrix",
1371 strlen("gl_TextureMatrix")) == 0) {
1372 struct variable_storage *entry;
1373
1374 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
1375 ir->array_index);
1376 assert(entry);
1377
1378 ir_to_mesa_src_reg src_reg(entry->file, entry->index, ir->type);
1379
1380 if (index) {
1381 src_reg.reladdr = NULL;
1382 } else {
1383 ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
1384
1385 ir->array_index->accept(this);
1386 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
1387 ir_to_mesa_dst_reg_from_src(index_reg),
1388 this->result, src_reg_for_float(element_size));
1389
1390 src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
1391 memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
1392 }
1393
1394 this->result = src_reg;
1395 return;
1396 }
1397
1398 if (var &&
1399 strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform &&
1400 !var->type->is_matrix()) {
1401 ir_dereference_record *record = NULL;
1402 if (ir->array->ir_type == ir_type_dereference_record)
1403 record = (ir_dereference_record *)ir->array;
1404
1405 assert(index || !"FINISHME: variable-indexed builtin uniform access");
1406
1407 this->result = get_builtin_uniform_reg(prog,
1408 var->name,
1409 index->value.i[0],
1410 record ? record->field : NULL);
1411 }
1412
1413 ir->array->accept(this);
1414 src_reg = this->result;
1415
1416 if (index) {
1417 src_reg.index += index->value.i[0] * element_size;
1418 } else {
1419 ir_to_mesa_src_reg array_base = this->result;
1420 /* Variable index array dereference. It eats the "vec4" of the
1421 * base of the array and an index that offsets the Mesa register
1422 * index.
1423 */
1424 ir->array_index->accept(this);
1425
1426 ir_to_mesa_src_reg index_reg;
1427
1428 if (element_size == 1) {
1429 index_reg = this->result;
1430 } else {
1431 index_reg = get_temp(glsl_type::float_type);
1432
1433 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
1434 ir_to_mesa_dst_reg_from_src(index_reg),
1435 this->result, src_reg_for_float(element_size));
1436 }
1437
1438 src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
1439 memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
1440 }
1441
1442 /* If the type is smaller than a vec4, replicate the last channel out. */
1443 if (ir->type->is_scalar() || ir->type->is_vector())
1444 src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
1445 else
1446 src_reg.swizzle = SWIZZLE_NOOP;
1447
1448 this->result = src_reg;
1449 }
1450
1451 void
1452 ir_to_mesa_visitor::visit(ir_dereference_record *ir)
1453 {
1454 unsigned int i;
1455 const glsl_type *struct_type = ir->record->type;
1456 int offset = 0;
1457 ir_variable *var = ir->record->variable_referenced();
1458
1459 if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform) {
1460 assert(var);
1461
1462 this->result = get_builtin_uniform_reg(prog,
1463 var->name,
1464 0,
1465 ir->field);
1466 return;
1467 }
1468
1469 ir->record->accept(this);
1470
1471 for (i = 0; i < struct_type->length; i++) {
1472 if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
1473 break;
1474 offset += type_size(struct_type->fields.structure[i].type);
1475 }
1476 this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
1477 this->result.index += offset;
1478 }
1479
1480 /**
1481 * We want to be careful in assignment setup to hit the actual storage
1482 * instead of potentially using a temporary like we might with the
1483 * ir_dereference handler.
1484 */
1485 static struct ir_to_mesa_dst_reg
1486 get_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v)
1487 {
1488 /* The LHS must be a dereference. If the LHS is a variable indexed array
1489 * access of a vector, it must be separated into a series conditional moves
1490 * before reaching this point (see ir_vec_index_to_cond_assign).
1491 */
1492 assert(ir->as_dereference());
1493 ir_dereference_array *deref_array = ir->as_dereference_array();
1494 if (deref_array) {
1495 assert(!deref_array->array->type->is_vector());
1496 }
1497
1498 /* Use the rvalue deref handler for the most part. We'll ignore
1499 * swizzles in it and write swizzles using writemask, though.
1500 */
1501 ir->accept(v);
1502 return ir_to_mesa_dst_reg_from_src(v->result);
1503 }
1504
1505 void
1506 ir_to_mesa_visitor::visit(ir_assignment *ir)
1507 {
1508 struct ir_to_mesa_dst_reg l;
1509 struct ir_to_mesa_src_reg r;
1510 int i;
1511
1512 ir->rhs->accept(this);
1513 r = this->result;
1514
1515 l = get_assignment_lhs(ir->lhs, this);
1516
1517 /* FINISHME: This should really set to the correct maximal writemask for each
1518 * FINISHME: component written (in the loops below). This case can only
1519 * FINISHME: occur for matrices, arrays, and structures.
1520 */
1521 if (ir->write_mask == 0) {
1522 assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
1523 l.writemask = WRITEMASK_XYZW;
1524 } else if (ir->lhs->type->is_scalar()) {
1525 /* FINISHME: This hack makes writing to gl_FragData, which lives in the
1526 * FINISHME: W component of fragment shader output zero, work correctly.
1527 */
1528 l.writemask = WRITEMASK_XYZW;
1529 } else {
1530 assert(ir->lhs->type->is_vector());
1531 l.writemask = ir->write_mask;
1532 }
1533
1534 assert(l.file != PROGRAM_UNDEFINED);
1535 assert(r.file != PROGRAM_UNDEFINED);
1536
1537 if (ir->condition) {
1538 ir_to_mesa_src_reg condition;
1539
1540 ir->condition->accept(this);
1541 condition = this->result;
1542
1543 /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
1544 * and the condition we produced is 0.0 or 1.0. By flipping the
1545 * sign, we can choose which value OPCODE_CMP produces without
1546 * an extra computing the condition.
1547 */
1548 condition.negate = ~condition.negate;
1549 for (i = 0; i < type_size(ir->lhs->type); i++) {
1550 ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
1551 condition, r, ir_to_mesa_src_reg_from_dst(l));
1552 l.index++;
1553 r.index++;
1554 }
1555 } else {
1556 for (i = 0; i < type_size(ir->lhs->type); i++) {
1557 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
1558 l.index++;
1559 r.index++;
1560 }
1561 }
1562 }
1563
1564
1565 void
1566 ir_to_mesa_visitor::visit(ir_constant *ir)
1567 {
1568 ir_to_mesa_src_reg src_reg;
1569 GLfloat stack_vals[4] = { 0 };
1570 GLfloat *values = stack_vals;
1571 unsigned int i;
1572
1573 /* Unfortunately, 4 floats is all we can get into
1574 * _mesa_add_unnamed_constant. So, make a temp to store an
1575 * aggregate constant and move each constant value into it. If we
1576 * get lucky, copy propagation will eliminate the extra moves.
1577 */
1578
1579 if (ir->type->base_type == GLSL_TYPE_STRUCT) {
1580 ir_to_mesa_src_reg temp_base = get_temp(ir->type);
1581 ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
1582
1583 foreach_iter(exec_list_iterator, iter, ir->components) {
1584 ir_constant *field_value = (ir_constant *)iter.get();
1585 int size = type_size(field_value->type);
1586
1587 assert(size > 0);
1588
1589 field_value->accept(this);
1590 src_reg = this->result;
1591
1592 for (i = 0; i < (unsigned int)size; i++) {
1593 ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
1594
1595 src_reg.index++;
1596 temp.index++;
1597 }
1598 }
1599 this->result = temp_base;
1600 return;
1601 }
1602
1603 if (ir->type->is_array()) {
1604 ir_to_mesa_src_reg temp_base = get_temp(ir->type);
1605 ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
1606 int size = type_size(ir->type->fields.array);
1607
1608 assert(size > 0);
1609
1610 for (i = 0; i < ir->type->length; i++) {
1611 ir->array_elements[i]->accept(this);
1612 src_reg = this->result;
1613 for (int j = 0; j < size; j++) {
1614 ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
1615
1616 src_reg.index++;
1617 temp.index++;
1618 }
1619 }
1620 this->result = temp_base;
1621 return;
1622 }
1623
1624 if (ir->type->is_matrix()) {
1625 ir_to_mesa_src_reg mat = get_temp(ir->type);
1626 ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
1627
1628 for (i = 0; i < ir->type->matrix_columns; i++) {
1629 assert(ir->type->base_type == GLSL_TYPE_FLOAT);
1630 values = &ir->value.f[i * ir->type->vector_elements];
1631
1632 src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL);
1633 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
1634 values,
1635 ir->type->vector_elements,
1636 &src_reg.swizzle);
1637 ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
1638
1639 mat_column.index++;
1640 }
1641
1642 this->result = mat;
1643 return;
1644 }
1645
1646 src_reg.file = PROGRAM_CONSTANT;
1647 switch (ir->type->base_type) {
1648 case GLSL_TYPE_FLOAT:
1649 values = &ir->value.f[0];
1650 break;
1651 case GLSL_TYPE_UINT:
1652 for (i = 0; i < ir->type->vector_elements; i++) {
1653 values[i] = ir->value.u[i];
1654 }
1655 break;
1656 case GLSL_TYPE_INT:
1657 for (i = 0; i < ir->type->vector_elements; i++) {
1658 values[i] = ir->value.i[i];
1659 }
1660 break;
1661 case GLSL_TYPE_BOOL:
1662 for (i = 0; i < ir->type->vector_elements; i++) {
1663 values[i] = ir->value.b[i];
1664 }
1665 break;
1666 default:
1667 assert(!"Non-float/uint/int/bool constant");
1668 }
1669
1670 this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type);
1671 this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters,
1672 values,
1673 ir->type->vector_elements,
1674 &this->result.swizzle);
1675 }
1676
1677 function_entry *
1678 ir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
1679 {
1680 function_entry *entry;
1681
1682 foreach_iter(exec_list_iterator, iter, this->function_signatures) {
1683 entry = (function_entry *)iter.get();
1684
1685 if (entry->sig == sig)
1686 return entry;
1687 }
1688
1689 entry = talloc(mem_ctx, function_entry);
1690 entry->sig = sig;
1691 entry->sig_id = this->next_signature_id++;
1692 entry->bgn_inst = NULL;
1693
1694 /* Allocate storage for all the parameters. */
1695 foreach_iter(exec_list_iterator, iter, sig->parameters) {
1696 ir_variable *param = (ir_variable *)iter.get();
1697 variable_storage *storage;
1698
1699 storage = find_variable_storage(param);
1700 assert(!storage);
1701
1702 storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
1703 this->next_temp);
1704 this->variables.push_tail(storage);
1705
1706 this->next_temp += type_size(param->type);
1707 }
1708
1709 if (!sig->return_type->is_void()) {
1710 entry->return_reg = get_temp(sig->return_type);
1711 } else {
1712 entry->return_reg = ir_to_mesa_undef;
1713 }
1714
1715 this->function_signatures.push_tail(entry);
1716 return entry;
1717 }
1718
1719 void
1720 ir_to_mesa_visitor::visit(ir_call *ir)
1721 {
1722 ir_to_mesa_instruction *call_inst;
1723 ir_function_signature *sig = ir->get_callee();
1724 function_entry *entry = get_function_signature(sig);
1725 int i;
1726
1727 /* Process in parameters. */
1728 exec_list_iterator sig_iter = sig->parameters.iterator();
1729 foreach_iter(exec_list_iterator, iter, *ir) {
1730 ir_rvalue *param_rval = (ir_rvalue *)iter.get();
1731 ir_variable *param = (ir_variable *)sig_iter.get();
1732
1733 if (param->mode == ir_var_in ||
1734 param->mode == ir_var_inout) {
1735 variable_storage *storage = find_variable_storage(param);
1736 assert(storage);
1737
1738 param_rval->accept(this);
1739 ir_to_mesa_src_reg r = this->result;
1740
1741 ir_to_mesa_dst_reg l;
1742 l.file = storage->file;
1743 l.index = storage->index;
1744 l.reladdr = NULL;
1745 l.writemask = WRITEMASK_XYZW;
1746 l.cond_mask = COND_TR;
1747
1748 for (i = 0; i < type_size(param->type); i++) {
1749 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
1750 l.index++;
1751 r.index++;
1752 }
1753 }
1754
1755 sig_iter.next();
1756 }
1757 assert(!sig_iter.has_next());
1758
1759 /* Emit call instruction */
1760 call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
1761 ir_to_mesa_undef_dst, ir_to_mesa_undef);
1762 call_inst->function = entry;
1763
1764 /* Process out parameters. */
1765 sig_iter = sig->parameters.iterator();
1766 foreach_iter(exec_list_iterator, iter, *ir) {
1767 ir_rvalue *param_rval = (ir_rvalue *)iter.get();
1768 ir_variable *param = (ir_variable *)sig_iter.get();
1769
1770 if (param->mode == ir_var_out ||
1771 param->mode == ir_var_inout) {
1772 variable_storage *storage = find_variable_storage(param);
1773 assert(storage);
1774
1775 ir_to_mesa_src_reg r;
1776 r.file = storage->file;
1777 r.index = storage->index;
1778 r.reladdr = NULL;
1779 r.swizzle = SWIZZLE_NOOP;
1780 r.negate = 0;
1781
1782 param_rval->accept(this);
1783 ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
1784
1785 for (i = 0; i < type_size(param->type); i++) {
1786 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
1787 l.index++;
1788 r.index++;
1789 }
1790 }
1791
1792 sig_iter.next();
1793 }
1794 assert(!sig_iter.has_next());
1795
1796 /* Process return value. */
1797 this->result = entry->return_reg;
1798 }
1799
1800 class get_sampler_name : public ir_hierarchical_visitor
1801 {
1802 public:
1803 get_sampler_name(ir_to_mesa_visitor *mesa, ir_dereference *last)
1804 {
1805 this->mem_ctx = mesa->mem_ctx;
1806 this->mesa = mesa;
1807 this->name = NULL;
1808 this->offset = 0;
1809 this->last = last;
1810 }
1811
1812 virtual ir_visitor_status visit(ir_dereference_variable *ir)
1813 {
1814 this->name = ir->var->name;
1815 return visit_continue;
1816 }
1817
1818 virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
1819 {
1820 this->name = talloc_asprintf(mem_ctx, "%s.%s", name, ir->field);
1821 return visit_continue;
1822 }
1823
1824 virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
1825 {
1826 ir_constant *index = ir->array_index->as_constant();
1827 int i;
1828
1829 if (index) {
1830 i = index->value.i[0];
1831 } else {
1832 /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
1833 * while GLSL 1.30 requires that the array indices be
1834 * constant integer expressions. We don't expect any driver
1835 * to actually work with a really variable array index, so
1836 * all that would work would be an unrolled loop counter that ends
1837 * up being constant above.
1838 */
1839 mesa->shader_program->InfoLog =
1840 talloc_asprintf_append(mesa->shader_program->InfoLog,
1841 "warning: Variable sampler array index "
1842 "unsupported.\nThis feature of the language "
1843 "was removed in GLSL 1.20 and is unlikely "
1844 "to be supported for 1.10 in Mesa.\n");
1845 i = 0;
1846 }
1847 if (ir != last) {
1848 this->name = talloc_asprintf(mem_ctx, "%s[%d]", name, i);
1849 } else {
1850 offset = i;
1851 }
1852 return visit_continue;
1853 }
1854
1855 ir_to_mesa_visitor *mesa;
1856 const char *name;
1857 void *mem_ctx;
1858 int offset;
1859 ir_dereference *last;
1860 };
1861
1862 int
1863 ir_to_mesa_visitor::get_sampler_uniform_value(ir_dereference *sampler)
1864 {
1865 get_sampler_name getname(this, sampler);
1866
1867 sampler->accept(&getname);
1868
1869 GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
1870 getname.name);
1871
1872 if (index < 0) {
1873 this->shader_program->InfoLog =
1874 talloc_asprintf_append(this->shader_program->InfoLog,
1875 "failed to find sampler named %s.\n",
1876 getname.name);
1877 this->shader_program->LinkStatus = GL_FALSE;
1878 return 0;
1879 }
1880
1881 index += getname.offset;
1882
1883 return this->prog->Parameters->ParameterValues[index][0];
1884 }
1885
1886 void
1887 ir_to_mesa_visitor::visit(ir_texture *ir)
1888 {
1889 ir_to_mesa_src_reg result_src, coord, lod_info, projector;
1890 ir_to_mesa_dst_reg result_dst, coord_dst;
1891 ir_to_mesa_instruction *inst = NULL;
1892 prog_opcode opcode = OPCODE_NOP;
1893
1894 ir->coordinate->accept(this);
1895
1896 /* Put our coords in a temp. We'll need to modify them for shadow,
1897 * projection, or LOD, so the only case we'd use it as is is if
1898 * we're doing plain old texturing. Mesa IR optimization should
1899 * handle cleaning up our mess in that case.
1900 */
1901 coord = get_temp(glsl_type::vec4_type);
1902 coord_dst = ir_to_mesa_dst_reg_from_src(coord);
1903 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
1904 this->result);
1905
1906 if (ir->projector) {
1907 ir->projector->accept(this);
1908 projector = this->result;
1909 }
1910
1911 /* Storage for our result. Ideally for an assignment we'd be using
1912 * the actual storage for the result here, instead.
1913 */
1914 result_src = get_temp(glsl_type::vec4_type);
1915 result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1916
1917 switch (ir->op) {
1918 case ir_tex:
1919 opcode = OPCODE_TEX;
1920 break;
1921 case ir_txb:
1922 opcode = OPCODE_TXB;
1923 ir->lod_info.bias->accept(this);
1924 lod_info = this->result;
1925 break;
1926 case ir_txl:
1927 opcode = OPCODE_TXL;
1928 ir->lod_info.lod->accept(this);
1929 lod_info = this->result;
1930 break;
1931 case ir_txd:
1932 case ir_txf:
1933 assert(!"GLSL 1.30 features unsupported");
1934 break;
1935 }
1936
1937 if (ir->projector) {
1938 if (opcode == OPCODE_TEX) {
1939 /* Slot the projector in as the last component of the coord. */
1940 coord_dst.writemask = WRITEMASK_W;
1941 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
1942 coord_dst.writemask = WRITEMASK_XYZW;
1943 opcode = OPCODE_TXP;
1944 } else {
1945 ir_to_mesa_src_reg coord_w = coord;
1946 coord_w.swizzle = SWIZZLE_WWWW;
1947
1948 /* For the other TEX opcodes there's no projective version
1949 * since the last slot is taken up by lod info. Do the
1950 * projective divide now.
1951 */
1952 coord_dst.writemask = WRITEMASK_W;
1953 ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
1954
1955 coord_dst.writemask = WRITEMASK_XYZ;
1956 ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
1957
1958 coord_dst.writemask = WRITEMASK_XYZW;
1959 coord.swizzle = SWIZZLE_XYZW;
1960 }
1961 }
1962
1963 if (ir->shadow_comparitor) {
1964 /* Slot the shadow value in as the second to last component of the
1965 * coord.
1966 */
1967 ir->shadow_comparitor->accept(this);
1968 coord_dst.writemask = WRITEMASK_Z;
1969 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
1970 coord_dst.writemask = WRITEMASK_XYZW;
1971 }
1972
1973 if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
1974 /* Mesa IR stores lod or lod bias in the last channel of the coords. */
1975 coord_dst.writemask = WRITEMASK_W;
1976 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
1977 coord_dst.writemask = WRITEMASK_XYZW;
1978 }
1979
1980 inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
1981
1982 if (ir->shadow_comparitor)
1983 inst->tex_shadow = GL_TRUE;
1984
1985 inst->sampler = get_sampler_uniform_value(ir->sampler);
1986
1987 const glsl_type *sampler_type = ir->sampler->type;
1988
1989 switch (sampler_type->sampler_dimensionality) {
1990 case GLSL_SAMPLER_DIM_1D:
1991 inst->tex_target = (sampler_type->sampler_array)
1992 ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
1993 break;
1994 case GLSL_SAMPLER_DIM_2D:
1995 inst->tex_target = (sampler_type->sampler_array)
1996 ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
1997 break;
1998 case GLSL_SAMPLER_DIM_3D:
1999 inst->tex_target = TEXTURE_3D_INDEX;
2000 break;
2001 case GLSL_SAMPLER_DIM_CUBE:
2002 inst->tex_target = TEXTURE_CUBE_INDEX;
2003 break;
2004 case GLSL_SAMPLER_DIM_RECT:
2005 inst->tex_target = TEXTURE_RECT_INDEX;
2006 break;
2007 case GLSL_SAMPLER_DIM_BUF:
2008 assert(!"FINISHME: Implement ARB_texture_buffer_object");
2009 break;
2010 default:
2011 assert(!"Should not get here.");
2012 }
2013
2014 this->result = result_src;
2015 }
2016
2017 void
2018 ir_to_mesa_visitor::visit(ir_return *ir)
2019 {
2020 if (ir->get_value()) {
2021 ir_to_mesa_dst_reg l;
2022 int i;
2023
2024 assert(current_function);
2025
2026 ir->get_value()->accept(this);
2027 ir_to_mesa_src_reg r = this->result;
2028
2029 l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
2030
2031 for (i = 0; i < type_size(current_function->sig->return_type); i++) {
2032 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
2033 l.index++;
2034 r.index++;
2035 }
2036 }
2037
2038 ir_to_mesa_emit_op0(ir, OPCODE_RET);
2039 }
2040
2041 void
2042 ir_to_mesa_visitor::visit(ir_discard *ir)
2043 {
2044 assert(ir->condition == NULL); /* FINISHME */
2045
2046 ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
2047 }
2048
2049 void
2050 ir_to_mesa_visitor::visit(ir_if *ir)
2051 {
2052 ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
2053 ir_to_mesa_instruction *prev_inst;
2054
2055 prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
2056
2057 ir->condition->accept(this);
2058 assert(this->result.file != PROGRAM_UNDEFINED);
2059
2060 if (ctx->Shader.EmitCondCodes) {
2061 cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
2062
2063 /* See if we actually generated any instruction for generating
2064 * the condition. If not, then cook up a move to a temp so we
2065 * have something to set cond_update on.
2066 */
2067 if (cond_inst == prev_inst) {
2068 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
2069 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
2070 ir_to_mesa_dst_reg_from_src(temp),
2071 result);
2072 }
2073 cond_inst->cond_update = GL_TRUE;
2074
2075 if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
2076 if_inst->dst_reg.cond_mask = COND_NE;
2077 } else {
2078 if_inst = ir_to_mesa_emit_op1(ir->condition,
2079 OPCODE_IF, ir_to_mesa_undef_dst,
2080 this->result);
2081 }
2082
2083 this->instructions.push_tail(if_inst);
2084
2085 visit_exec_list(&ir->then_instructions, this);
2086
2087 if (!ir->else_instructions.is_empty()) {
2088 else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
2089 visit_exec_list(&ir->else_instructions, this);
2090 }
2091
2092 if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
2093 ir_to_mesa_undef_dst, ir_to_mesa_undef);
2094 }
2095
2096 ir_to_mesa_visitor::ir_to_mesa_visitor()
2097 {
2098 result.file = PROGRAM_UNDEFINED;
2099 next_temp = 1;
2100 next_signature_id = 1;
2101 current_function = NULL;
2102 mem_ctx = talloc_new(NULL);
2103 }
2104
2105 ir_to_mesa_visitor::~ir_to_mesa_visitor()
2106 {
2107 talloc_free(mem_ctx);
2108 }
2109
2110 static struct prog_src_register
2111 mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
2112 {
2113 struct prog_src_register mesa_reg;
2114
2115 mesa_reg.File = reg.file;
2116 assert(reg.index < (1 << INST_INDEX_BITS) - 1);
2117 mesa_reg.Index = reg.index;
2118 mesa_reg.Swizzle = reg.swizzle;
2119 mesa_reg.RelAddr = reg.reladdr != NULL;
2120 mesa_reg.Negate = reg.negate;
2121 mesa_reg.Abs = 0;
2122 mesa_reg.HasIndex2 = GL_FALSE;
2123 mesa_reg.RelAddr2 = 0;
2124 mesa_reg.Index2 = 0;
2125
2126 return mesa_reg;
2127 }
2128
2129 static void
2130 set_branchtargets(ir_to_mesa_visitor *v,
2131 struct prog_instruction *mesa_instructions,
2132 int num_instructions)
2133 {
2134 int if_count = 0, loop_count = 0;
2135 int *if_stack, *loop_stack;
2136 int if_stack_pos = 0, loop_stack_pos = 0;
2137 int i, j;
2138
2139 for (i = 0; i < num_instructions; i++) {
2140 switch (mesa_instructions[i].Opcode) {
2141 case OPCODE_IF:
2142 if_count++;
2143 break;
2144 case OPCODE_BGNLOOP:
2145 loop_count++;
2146 break;
2147 case OPCODE_BRK:
2148 case OPCODE_CONT:
2149 mesa_instructions[i].BranchTarget = -1;
2150 break;
2151 default:
2152 break;
2153 }
2154 }
2155
2156 if_stack = talloc_zero_array(v->mem_ctx, int, if_count);
2157 loop_stack = talloc_zero_array(v->mem_ctx, int, loop_count);
2158
2159 for (i = 0; i < num_instructions; i++) {
2160 switch (mesa_instructions[i].Opcode) {
2161 case OPCODE_IF:
2162 if_stack[if_stack_pos] = i;
2163 if_stack_pos++;
2164 break;
2165 case OPCODE_ELSE:
2166 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
2167 if_stack[if_stack_pos - 1] = i;
2168 break;
2169 case OPCODE_ENDIF:
2170 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
2171 if_stack_pos--;
2172 break;
2173 case OPCODE_BGNLOOP:
2174 loop_stack[loop_stack_pos] = i;
2175 loop_stack_pos++;
2176 break;
2177 case OPCODE_ENDLOOP:
2178 loop_stack_pos--;
2179 /* Rewrite any breaks/conts at this nesting level (haven't
2180 * already had a BranchTarget assigned) to point to the end
2181 * of the loop.
2182 */
2183 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
2184 if (mesa_instructions[j].Opcode == OPCODE_BRK ||
2185 mesa_instructions[j].Opcode == OPCODE_CONT) {
2186 if (mesa_instructions[j].BranchTarget == -1) {
2187 mesa_instructions[j].BranchTarget = i;
2188 }
2189 }
2190 }
2191 /* The loop ends point at each other. */
2192 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
2193 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
2194 break;
2195 case OPCODE_CAL:
2196 foreach_iter(exec_list_iterator, iter, v->function_signatures) {
2197 function_entry *entry = (function_entry *)iter.get();
2198
2199 if (entry->sig_id == mesa_instructions[i].BranchTarget) {
2200 mesa_instructions[i].BranchTarget = entry->inst;
2201 break;
2202 }
2203 }
2204 break;
2205 default:
2206 break;
2207 }
2208 }
2209 }
2210
2211 static void
2212 print_program(struct prog_instruction *mesa_instructions,
2213 ir_instruction **mesa_instruction_annotation,
2214 int num_instructions)
2215 {
2216 ir_instruction *last_ir = NULL;
2217 int i;
2218 int indent = 0;
2219
2220 for (i = 0; i < num_instructions; i++) {
2221 struct prog_instruction *mesa_inst = mesa_instructions + i;
2222 ir_instruction *ir = mesa_instruction_annotation[i];
2223
2224 fprintf(stdout, "%3d: ", i);
2225
2226 if (last_ir != ir && ir) {
2227 int j;
2228
2229 for (j = 0; j < indent; j++) {
2230 fprintf(stdout, " ");
2231 }
2232 ir->print();
2233 printf("\n");
2234 last_ir = ir;
2235
2236 fprintf(stdout, " "); /* line number spacing. */
2237 }
2238
2239 indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
2240 PROG_PRINT_DEBUG, NULL);
2241 }
2242 }
2243
2244 static void
2245 count_resources(struct gl_program *prog)
2246 {
2247 unsigned int i;
2248
2249 prog->SamplersUsed = 0;
2250
2251 for (i = 0; i < prog->NumInstructions; i++) {
2252 struct prog_instruction *inst = &prog->Instructions[i];
2253
2254 if (_mesa_is_tex_instruction(inst->Opcode)) {
2255 prog->SamplerTargets[inst->TexSrcUnit] =
2256 (gl_texture_index)inst->TexSrcTarget;
2257 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
2258 if (inst->TexShadow) {
2259 prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
2260 }
2261 }
2262 }
2263
2264 _mesa_update_shader_textures_used(prog);
2265 }
2266
2267 /* Add the uniforms to the parameters. The linker chose locations
2268 * in our parameters lists (which weren't created yet), which the
2269 * uniforms code will use to poke values into our parameters list
2270 * when uniforms are updated.
2271 */
2272 static void
2273 add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
2274 struct gl_shader *shader,
2275 struct gl_program *prog)
2276 {
2277 unsigned int i;
2278 unsigned int next_sampler = 0;
2279
2280 for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) {
2281 struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i;
2282 const glsl_type *type = uniform->Type;
2283 unsigned int size;
2284 int parameter_index = -1;
2285
2286 switch (shader->Type) {
2287 case GL_VERTEX_SHADER:
2288 parameter_index = uniform->VertPos;
2289 break;
2290 case GL_FRAGMENT_SHADER:
2291 parameter_index = uniform->FragPos;
2292 break;
2293 case GL_GEOMETRY_SHADER:
2294 parameter_index = uniform->GeomPos;
2295 break;
2296 }
2297
2298 /* Only add uniforms used in our target. */
2299 if (parameter_index == -1)
2300 continue;
2301
2302 if (type->is_vector() ||
2303 type->is_scalar()) {
2304 size = type->vector_elements;
2305 } else {
2306 size = type_size(type) * 4;
2307 }
2308
2309 gl_register_file file;
2310 if (type->is_sampler() ||
2311 (type->is_array() && type->fields.array->is_sampler())) {
2312 file = PROGRAM_SAMPLER;
2313 } else {
2314 file = PROGRAM_UNIFORM;
2315 }
2316
2317 GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
2318 uniform->Name);
2319
2320 if (index < 0) {
2321 index = _mesa_add_parameter(prog->Parameters, file,
2322 uniform->Name, size, type->gl_type,
2323 NULL, NULL, 0x0);
2324
2325 /* Sampler uniform values are stored in prog->SamplerUnits,
2326 * and the entry in that array is selected by this index we
2327 * store in ParameterValues[].
2328 */
2329 if (file == PROGRAM_SAMPLER) {
2330 for (unsigned int j = 0; j < size / 4; j++)
2331 prog->Parameters->ParameterValues[index + j][0] = next_sampler++;
2332 }
2333
2334 /* The location chosen in the Parameters list here (returned
2335 * from _mesa_add_uniform) has to match what the linker chose.
2336 */
2337 if (index != parameter_index) {
2338 shader_program->InfoLog =
2339 talloc_asprintf_append(shader_program->InfoLog,
2340 "Allocation of uniform `%s' to target "
2341 "failed (%d vs %d)\n", uniform->Name,
2342 index, parameter_index);
2343 shader_program->LinkStatus = false;
2344 }
2345 }
2346 }
2347 }
2348
2349 static void
2350 set_uniform_initializer(GLcontext *ctx, void *mem_ctx,
2351 struct gl_shader_program *shader_program,
2352 const char *name, const glsl_type *type,
2353 ir_constant *val)
2354 {
2355 if (type->is_record()) {
2356 ir_constant *field_constant;
2357
2358 field_constant = (ir_constant *)val->components.get_head();
2359
2360 for (unsigned int i = 0; i < type->length; i++) {
2361 const glsl_type *field_type = type->fields.structure[i].type;
2362 const char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name,
2363 type->fields.structure[i].name);
2364 set_uniform_initializer(ctx, mem_ctx, shader_program, field_name,
2365 field_type, field_constant);
2366 field_constant = (ir_constant *)field_constant->next;
2367 }
2368 return;
2369 }
2370
2371 int loc = _mesa_get_uniform_location(ctx, shader_program, name);
2372
2373 if (loc == -1) {
2374 shader_program->InfoLog =
2375 talloc_asprintf_append(shader_program->InfoLog,
2376 "Couldn't find uniform for "
2377 "initializer %s\n", name);
2378 shader_program->LinkStatus = false;
2379 abort();
2380 }
2381
2382 for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) {
2383 ir_constant *element;
2384 const glsl_type *element_type;
2385 if (type->is_array()) {
2386 element = val->array_elements[i];
2387 element_type = type->fields.array;
2388 } else {
2389 element = val;
2390 element_type = type;
2391 }
2392
2393 void *values;
2394
2395 if (element_type->base_type == GLSL_TYPE_BOOL) {
2396 int *conv = talloc_array(mem_ctx, int, element_type->components());
2397 for (unsigned int j = 0; j < element_type->components(); j++) {
2398 conv[j] = element->value.b[j];
2399 }
2400 values = (void *)conv;
2401 element_type = glsl_type::get_instance(GLSL_TYPE_INT,
2402 element_type->vector_elements,
2403 1);
2404 } else {
2405 values = &element->value;
2406 }
2407
2408 if (element_type->is_matrix()) {
2409 _mesa_uniform_matrix(ctx, shader_program,
2410 element_type->matrix_columns,
2411 element_type->vector_elements,
2412 loc, 1, GL_FALSE, (GLfloat *)values);
2413 loc += element_type->matrix_columns;
2414 } else {
2415 _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
2416 values, element_type->gl_type);
2417 loc += type_size(element_type);
2418 }
2419 }
2420 }
2421
2422 static void
2423 set_uniform_initializers(GLcontext *ctx,
2424 struct gl_shader_program *shader_program)
2425 {
2426 void *mem_ctx = NULL;
2427
2428 for (unsigned int i = 0; i < shader_program->_NumLinkedShaders; i++) {
2429 struct gl_shader *shader = shader_program->_LinkedShaders[i];
2430 foreach_iter(exec_list_iterator, iter, *shader->ir) {
2431 ir_instruction *ir = (ir_instruction *)iter.get();
2432 ir_variable *var = ir->as_variable();
2433
2434 if (!var || var->mode != ir_var_uniform || !var->constant_value)
2435 continue;
2436
2437 if (!mem_ctx)
2438 mem_ctx = talloc_new(NULL);
2439
2440 set_uniform_initializer(ctx, mem_ctx, shader_program, var->name,
2441 var->type, var->constant_value);
2442 }
2443 }
2444
2445 talloc_free(mem_ctx);
2446 }
2447
2448 struct gl_program *
2449 get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
2450 struct gl_shader *shader)
2451 {
2452 ir_to_mesa_visitor v;
2453 struct prog_instruction *mesa_instructions, *mesa_inst;
2454 ir_instruction **mesa_instruction_annotation;
2455 int i;
2456 struct gl_program *prog;
2457 GLenum target;
2458 const char *target_string;
2459 GLboolean progress;
2460
2461 switch (shader->Type) {
2462 case GL_VERTEX_SHADER:
2463 target = GL_VERTEX_PROGRAM_ARB;
2464 target_string = "vertex";
2465 break;
2466 case GL_FRAGMENT_SHADER:
2467 target = GL_FRAGMENT_PROGRAM_ARB;
2468 target_string = "fragment";
2469 break;
2470 default:
2471 assert(!"should not be reached");
2472 return NULL;
2473 }
2474
2475 validate_ir_tree(shader->ir);
2476
2477 prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name);
2478 if (!prog)
2479 return NULL;
2480 prog->Parameters = _mesa_new_parameter_list();
2481 prog->Varying = _mesa_new_parameter_list();
2482 prog->Attributes = _mesa_new_parameter_list();
2483 v.ctx = ctx;
2484 v.prog = prog;
2485 v.shader_program = shader_program;
2486
2487 add_uniforms_to_parameters_list(shader_program, shader, prog);
2488
2489 /* Emit Mesa IR for main(). */
2490 visit_exec_list(shader->ir, &v);
2491 v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
2492
2493 /* Now emit bodies for any functions that were used. */
2494 do {
2495 progress = GL_FALSE;
2496
2497 foreach_iter(exec_list_iterator, iter, v.function_signatures) {
2498 function_entry *entry = (function_entry *)iter.get();
2499
2500 if (!entry->bgn_inst) {
2501 v.current_function = entry;
2502
2503 entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
2504 entry->bgn_inst->function = entry;
2505
2506 visit_exec_list(&entry->sig->body, &v);
2507
2508 ir_to_mesa_instruction *last;
2509 last = (ir_to_mesa_instruction *)v.instructions.get_tail();
2510 if (last->op != OPCODE_RET)
2511 v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
2512
2513 ir_to_mesa_instruction *end;
2514 end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
2515 end->function = entry;
2516
2517 progress = GL_TRUE;
2518 }
2519 }
2520 } while (progress);
2521
2522 prog->NumTemporaries = v.next_temp;
2523
2524 int num_instructions = 0;
2525 foreach_iter(exec_list_iterator, iter, v.instructions) {
2526 num_instructions++;
2527 }
2528
2529 mesa_instructions =
2530 (struct prog_instruction *)calloc(num_instructions,
2531 sizeof(*mesa_instructions));
2532 mesa_instruction_annotation = talloc_array(v.mem_ctx, ir_instruction *,
2533 num_instructions);
2534
2535 mesa_inst = mesa_instructions;
2536 i = 0;
2537 foreach_iter(exec_list_iterator, iter, v.instructions) {
2538 ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
2539
2540 mesa_inst->Opcode = inst->op;
2541 mesa_inst->CondUpdate = inst->cond_update;
2542 mesa_inst->DstReg.File = inst->dst_reg.file;
2543 mesa_inst->DstReg.Index = inst->dst_reg.index;
2544 mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
2545 mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
2546 mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
2547 mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
2548 mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
2549 mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
2550 mesa_inst->TexSrcUnit = inst->sampler;
2551 mesa_inst->TexSrcTarget = inst->tex_target;
2552 mesa_inst->TexShadow = inst->tex_shadow;
2553 mesa_instruction_annotation[i] = inst->ir;
2554
2555 /* Set IndirectRegisterFiles. */
2556 if (mesa_inst->DstReg.RelAddr)
2557 prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File;
2558
2559 for (unsigned src = 0; src < 3; src++)
2560 if (mesa_inst->SrcReg[src].RelAddr)
2561 prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File;
2562
2563 if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
2564 shader_program->InfoLog =
2565 talloc_asprintf_append(shader_program->InfoLog,
2566 "Couldn't flatten if statement\n");
2567 shader_program->LinkStatus = false;
2568 }
2569
2570 switch (mesa_inst->Opcode) {
2571 case OPCODE_BGNSUB:
2572 inst->function->inst = i;
2573 mesa_inst->Comment = strdup(inst->function->sig->function_name());
2574 break;
2575 case OPCODE_ENDSUB:
2576 mesa_inst->Comment = strdup(inst->function->sig->function_name());
2577 break;
2578 case OPCODE_CAL:
2579 mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
2580 break;
2581 case OPCODE_ARL:
2582 prog->NumAddressRegs = 1;
2583 break;
2584 default:
2585 break;
2586 }
2587
2588 mesa_inst++;
2589 i++;
2590 }
2591
2592 set_branchtargets(&v, mesa_instructions, num_instructions);
2593
2594 if (ctx->Shader.Flags & GLSL_DUMP) {
2595 printf("\n");
2596 printf("GLSL IR for linked %s program %d:\n", target_string,
2597 shader_program->Name);
2598 _mesa_print_ir(shader->ir, NULL);
2599 printf("\n");
2600 printf("\n");
2601 printf("Mesa IR for linked %s program %d:\n", target_string,
2602 shader_program->Name);
2603 print_program(mesa_instructions, mesa_instruction_annotation,
2604 num_instructions);
2605 }
2606
2607 prog->Instructions = mesa_instructions;
2608 prog->NumInstructions = num_instructions;
2609
2610 do_set_program_inouts(shader->ir, prog);
2611 count_resources(prog);
2612
2613 _mesa_reference_program(ctx, &shader->Program, prog);
2614
2615 if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
2616 _mesa_optimize_program(ctx, prog);
2617 }
2618
2619 return prog;
2620 }
2621
2622 extern "C" {
2623 GLboolean
2624 _mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader)
2625 {
2626 assert(shader->CompileStatus);
2627 (void) ctx;
2628
2629 return GL_TRUE;
2630 }
2631
2632 GLboolean
2633 _mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
2634 {
2635 assert(prog->LinkStatus);
2636
2637 for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
2638 bool progress;
2639 exec_list *ir = prog->_LinkedShaders[i]->ir;
2640
2641 do {
2642 progress = false;
2643
2644 /* Lowering */
2645 do_mat_op_to_vec(ir);
2646 do_mod_to_fract(ir);
2647 do_div_to_mul_rcp(ir);
2648 do_explog_to_explog2(ir);
2649
2650 progress = do_common_optimization(ir, true) || progress;
2651
2652 if (ctx->Shader.EmitNoIfs)
2653 progress = do_if_to_cond_assign(ir) || progress;
2654
2655 progress = do_vec_index_to_cond_assign(ir) || progress;
2656 } while (progress);
2657
2658 validate_ir_tree(ir);
2659 }
2660
2661 for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
2662 struct gl_program *linked_prog;
2663 bool ok = true;
2664
2665 linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
2666
2667 switch (prog->_LinkedShaders[i]->Type) {
2668 case GL_VERTEX_SHADER:
2669 _mesa_reference_vertprog(ctx, &prog->VertexProgram,
2670 (struct gl_vertex_program *)linked_prog);
2671 ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
2672 linked_prog);
2673 break;
2674 case GL_FRAGMENT_SHADER:
2675 _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
2676 (struct gl_fragment_program *)linked_prog);
2677 ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
2678 linked_prog);
2679 break;
2680 }
2681 if (!ok) {
2682 return GL_FALSE;
2683 }
2684 _mesa_reference_program(ctx, &linked_prog, NULL);
2685 }
2686
2687 return GL_TRUE;
2688 }
2689
2690 void
2691 _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
2692 {
2693 struct _mesa_glsl_parse_state *state =
2694 new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
2695
2696 const char *source = shader->Source;
2697 state->error = preprocess(state, &source, &state->info_log,
2698 &ctx->Extensions);
2699
2700 if (ctx->Shader.Flags & GLSL_DUMP) {
2701 printf("GLSL source for shader %d:\n", shader->Name);
2702 printf("%s\n", shader->Source);
2703 }
2704
2705 if (!state->error) {
2706 _mesa_glsl_lexer_ctor(state, source);
2707 _mesa_glsl_parse(state);
2708 _mesa_glsl_lexer_dtor(state);
2709 }
2710
2711 talloc_free(shader->ir);
2712 shader->ir = new(shader) exec_list;
2713 if (!state->error && !state->translation_unit.is_empty())
2714 _mesa_ast_to_hir(shader->ir, state);
2715
2716 if (!state->error && !shader->ir->is_empty()) {
2717 validate_ir_tree(shader->ir);
2718
2719 /* Do some optimization at compile time to reduce shader IR size
2720 * and reduce later work if the same shader is linked multiple times
2721 */
2722 while (do_common_optimization(shader->ir, false))
2723 ;
2724
2725 validate_ir_tree(shader->ir);
2726 }
2727
2728 shader->symbols = state->symbols;
2729
2730 shader->CompileStatus = !state->error;
2731 shader->InfoLog = state->info_log;
2732 shader->Version = state->language_version;
2733 memcpy(shader->builtins_to_link, state->builtins_to_link,
2734 sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
2735 shader->num_builtins_to_link = state->num_builtins_to_link;
2736
2737 if (ctx->Shader.Flags & GLSL_LOG) {
2738 _mesa_write_shader_to_file(shader);
2739 }
2740
2741 if (ctx->Shader.Flags & GLSL_DUMP) {
2742 if (shader->CompileStatus) {
2743 printf("GLSL IR for shader %d:\n", shader->Name);
2744 _mesa_print_ir(shader->ir, NULL);
2745 printf("\n\n");
2746 } else {
2747 printf("GLSL shader %d failed to compile.\n", shader->Name);
2748 }
2749 if (shader->InfoLog && shader->InfoLog[0] != 0) {
2750 printf("GLSL shader %d info log:\n", shader->Name);
2751 printf("%s\n", shader->InfoLog);
2752 }
2753 }
2754
2755 /* Retain any live IR, but trash the rest. */
2756 reparent_ir(shader->ir, shader->ir);
2757
2758 talloc_free(state);
2759
2760 if (shader->CompileStatus) {
2761 if (!ctx->Driver.CompileShader(ctx, shader))
2762 shader->CompileStatus = GL_FALSE;
2763 }
2764 }
2765
2766 void
2767 _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
2768 {
2769 unsigned int i;
2770
2771 _mesa_clear_shader_program_data(ctx, prog);
2772
2773 prog->LinkStatus = GL_TRUE;
2774
2775 for (i = 0; i < prog->NumShaders; i++) {
2776 if (!prog->Shaders[i]->CompileStatus) {
2777 prog->InfoLog =
2778 talloc_asprintf_append(prog->InfoLog,
2779 "linking with uncompiled shader");
2780 prog->LinkStatus = GL_FALSE;
2781 }
2782 }
2783
2784 prog->Varying = _mesa_new_parameter_list();
2785 _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
2786 _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
2787
2788 if (prog->LinkStatus) {
2789 link_shaders(ctx, prog);
2790 }
2791
2792 if (prog->LinkStatus) {
2793 if (!ctx->Driver.LinkShader(ctx, prog)) {
2794 prog->LinkStatus = GL_FALSE;
2795 }
2796 }
2797
2798 set_uniform_initializers(ctx, prog);
2799
2800 if (ctx->Shader.Flags & GLSL_DUMP) {
2801 if (!prog->LinkStatus) {
2802 printf("GLSL shader program %d failed to link\n", prog->Name);
2803 }
2804
2805 if (prog->InfoLog && prog->InfoLog[0] != 0) {
2806 printf("GLSL shader program %d info log:\n", prog->Name);
2807 printf("%s\n", prog->InfoLog);
2808 }
2809 }
2810 }
2811
2812 } /* extern "C" */