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