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