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