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