26449c5a5c4e212e9e3ca170803e3dc947576982
[platform/upstream/mesa.git] / ir_to_mesa.cpp
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 /**
25  * \file ir_to_mesa.cpp
26  *
27  * Translates the IR to ARB_fragment_program text if possible,
28  * printing the result
29  */
30
31 #include <stdio.h>
32 #include "ir.h"
33 #include "ir_visitor.h"
34 #include "ir_print_visitor.h"
35 #include "ir_expression_flattening.h"
36 #include "glsl_types.h"
37
38 extern "C" {
39 #include "shader/prog_instruction.h"
40 #include "shader/prog_print.h"
41 }
42
43 /**
44  * This struct is a corresponding struct to Mesa prog_src_register, with
45  * wider fields.
46  */
47 typedef struct ir_to_mesa_src_reg {
48    int file; /**< PROGRAM_* from Mesa */
49    int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
50    int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
51    int negate; /**< NEGATE_XYZW mask from mesa */
52    bool reladdr; /**< Register index should be offset by address reg. */
53 } ir_to_mesa_src_reg;
54
55 typedef struct ir_to_mesa_dst_reg {
56    int file; /**< PROGRAM_* from Mesa */
57    int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
58    int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
59 } ir_to_mesa_dst_reg;
60
61 extern ir_to_mesa_src_reg ir_to_mesa_undef;
62
63 class ir_to_mesa_instruction : public exec_node {
64 public:
65    enum prog_opcode op;
66    ir_to_mesa_dst_reg dst_reg;
67    ir_to_mesa_src_reg src_reg[3];
68    /** Pointer to the ir source this tree came from for debugging */
69    ir_instruction *ir;
70 };
71
72 class temp_entry : public exec_node {
73 public:
74    temp_entry(ir_variable *var, int file, int index)
75       : file(file), index(index), var(var)
76    {
77       /* empty */
78    }
79
80    int file;
81    int index;
82    ir_variable *var; /* variable that maps to this, if any */
83 };
84
85 class ir_to_mesa_visitor : public ir_visitor {
86 public:
87    ir_to_mesa_visitor();
88
89    int next_temp;
90    int next_constant;
91    int next_uniform;
92
93    temp_entry *find_variable_storage(ir_variable *var);
94
95    ir_to_mesa_src_reg get_temp(const glsl_type *type);
96
97    struct ir_to_mesa_src_reg src_reg_for_float(float val);
98
99    /**
100     * \name Visit methods
101     *
102     * As typical for the visitor pattern, there must be one \c visit method for
103     * each concrete subclass of \c ir_instruction.  Virtual base classes within
104     * the hierarchy should not have \c visit methods.
105     */
106    /*@{*/
107    virtual void visit(ir_variable *);
108    virtual void visit(ir_loop *);
109    virtual void visit(ir_loop_jump *);
110    virtual void visit(ir_function_signature *);
111    virtual void visit(ir_function *);
112    virtual void visit(ir_expression *);
113    virtual void visit(ir_swizzle *);
114    virtual void visit(ir_dereference_variable  *);
115    virtual void visit(ir_dereference_array *);
116    virtual void visit(ir_dereference_record *);
117    virtual void visit(ir_assignment *);
118    virtual void visit(ir_constant *);
119    virtual void visit(ir_call *);
120    virtual void visit(ir_return *);
121    virtual void visit(ir_texture *);
122    virtual void visit(ir_if *);
123    /*@}*/
124
125    struct ir_to_mesa_src_reg result;
126
127    /** List of temp_entry */
128    exec_list variable_storage;
129
130    /** List of ir_to_mesa_instruction */
131    exec_list instructions;
132
133    ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
134                                                enum prog_opcode op,
135                                                ir_to_mesa_dst_reg dst,
136                                                ir_to_mesa_src_reg src0);
137
138    ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
139                                                enum prog_opcode op,
140                                                ir_to_mesa_dst_reg dst,
141                                                ir_to_mesa_src_reg src0,
142                                                ir_to_mesa_src_reg src1);
143
144    ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
145                                                enum prog_opcode op,
146                                                ir_to_mesa_dst_reg dst,
147                                                ir_to_mesa_src_reg src0,
148                                                ir_to_mesa_src_reg src1,
149                                                ir_to_mesa_src_reg src2);
150
151    void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
152                                    enum prog_opcode op,
153                                    ir_to_mesa_dst_reg dst,
154                                    ir_to_mesa_src_reg src0);
155
156    /* talloc context (the ) */
157    void *ctx;
158 };
159
160 ir_to_mesa_src_reg ir_to_mesa_undef = {
161    PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
162 };
163
164 ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
165    PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
166 };
167
168 ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
169    PROGRAM_ADDRESS, 0, WRITEMASK_X
170 };
171
172 static int swizzle_for_size(int size)
173 {
174    int size_swizzles[4] = {
175       MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
176       MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
177       MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
178       MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
179    };
180
181    return size_swizzles[size - 1];
182 }
183
184 /* This list should match up with builtin_variables.h */
185 static const struct {
186    const char *name;
187    int file;
188    int index;
189 } builtin_var_to_mesa_reg[] = {
190    /* core_vs */
191    {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS},
192    {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ},
193
194    /* core_fs */
195    {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS},
196    {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE},
197    {"gl_FragColor", PROGRAM_OUTPUT, FRAG_ATTRIB_COL0},
198    {"gl_FragDepth", PROGRAM_UNDEFINED, FRAG_ATTRIB_WPOS}, /* FINISHME: WPOS.z */
199
200    /* 110_deprecated_fs */
201    {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
202    {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1},
203    {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC},
204    {"gl_TexCoord", PROGRAM_INPUT, FRAG_ATTRIB_TEX0}, /* array */
205
206    /* 110_deprecated_vs */
207    {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS},
208    {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL},
209    {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0},
210    {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1},
211    {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0},
212    {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1},
213    {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2},
214    {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3},
215    {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4},
216    {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5},
217    {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6},
218    {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7},
219    {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */
220    {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC},
221    /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
222    {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0},
223    {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0},
224    {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1},
225    {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1},
226    {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC},
227
228    /* 130_vs */
229    /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
230
231    {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */
232 };
233
234 ir_to_mesa_instruction *
235 ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
236                                         enum prog_opcode op,
237                                         ir_to_mesa_dst_reg dst,
238                                         ir_to_mesa_src_reg src0,
239                                         ir_to_mesa_src_reg src1,
240                                         ir_to_mesa_src_reg src2)
241 {
242    ir_to_mesa_instruction *inst = new(ctx) ir_to_mesa_instruction();
243
244    inst->op = op;
245    inst->dst_reg = dst;
246    inst->src_reg[0] = src0;
247    inst->src_reg[1] = src1;
248    inst->src_reg[2] = src2;
249    inst->ir = ir;
250
251    this->instructions.push_tail(inst);
252
253    return inst;
254 }
255
256
257 ir_to_mesa_instruction *
258 ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
259                                         enum prog_opcode op,
260                                         ir_to_mesa_dst_reg dst,
261                                         ir_to_mesa_src_reg src0,
262                                         ir_to_mesa_src_reg src1)
263 {
264    return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
265 }
266
267 ir_to_mesa_instruction *
268 ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
269                                         enum prog_opcode op,
270                                         ir_to_mesa_dst_reg dst,
271                                         ir_to_mesa_src_reg src0)
272 {
273    return ir_to_mesa_emit_op3(ir, op, dst,
274                               src0, ir_to_mesa_undef, ir_to_mesa_undef);
275 }
276
277 inline ir_to_mesa_dst_reg
278 ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
279 {
280    ir_to_mesa_dst_reg dst_reg;
281
282    dst_reg.file = reg.file;
283    dst_reg.index = reg.index;
284    dst_reg.writemask = WRITEMASK_XYZW;
285
286    return dst_reg;
287 }
288
289 /**
290  * Emits Mesa scalar opcodes to produce unique answers across channels.
291  *
292  * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
293  * channel determines the result across all channels.  So to do a vec4
294  * of this operation, we want to emit a scalar per source channel used
295  * to produce dest channels.
296  */
297 void
298 ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
299                                                enum prog_opcode op,
300                                                ir_to_mesa_dst_reg dst,
301                                                ir_to_mesa_src_reg src0)
302 {
303    int i, j;
304    int done_mask = ~dst.writemask;
305
306    /* Mesa RCP is a scalar operation splatting results to all channels,
307     * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
308     * dst channels.
309     */
310    for (i = 0; i < 4; i++) {
311       int this_mask = (1 << i);
312       ir_to_mesa_instruction *inst;
313       ir_to_mesa_src_reg src = src0;
314
315       if (done_mask & this_mask)
316          continue;
317
318       int src_swiz = GET_SWZ(src.swizzle, i);
319       for (j = i + 1; j < 4; j++) {
320          if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) {
321             this_mask |= (1 << j);
322          }
323       }
324       src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz,
325                                   src_swiz, src_swiz);
326
327       inst = ir_to_mesa_emit_op1(ir, op,
328                                  dst,
329                                  src);
330       inst->dst_reg.writemask = this_mask;
331       done_mask |= this_mask;
332    }
333 }
334
335 struct ir_to_mesa_src_reg
336 ir_to_mesa_visitor::src_reg_for_float(float val)
337 {
338    ir_to_mesa_src_reg src_reg;
339
340    /* FINISHME: This will end up being _mesa_add_unnamed_constant,
341     * which handles sharing values and sharing channels of vec4
342     * constants for small values.
343     */
344    /* FINISHME: Do something with the constant values for now.
345     */
346    (void)val;
347    src_reg.file = PROGRAM_CONSTANT;
348    src_reg.index = this->next_constant++;
349    src_reg.swizzle = SWIZZLE_NOOP;
350
351    return src_reg;
352 }
353
354 /**
355  * In the initial pass of codegen, we assign temporary numbers to
356  * intermediate results.  (not SSA -- variable assignments will reuse
357  * storage).  Actual register allocation for the Mesa VM occurs in a
358  * pass over the Mesa IR later.
359  */
360 ir_to_mesa_src_reg
361 ir_to_mesa_visitor::get_temp(const glsl_type *type)
362 {
363    ir_to_mesa_src_reg src_reg;
364    int swizzle[4];
365    int i;
366
367    assert(!type->is_array());
368
369    src_reg.file = PROGRAM_TEMPORARY;
370    src_reg.index = type->matrix_columns;
371    src_reg.reladdr = false;
372
373    for (i = 0; i < type->vector_elements; i++)
374       swizzle[i] = i;
375    for (; i < 4; i++)
376       swizzle[i] = type->vector_elements - 1;
377    src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
378                                    swizzle[2], swizzle[3]);
379
380    return src_reg;
381 }
382
383 static int
384 type_size(const struct glsl_type *type)
385 {
386    unsigned int i;
387    int size;
388
389    switch (type->base_type) {
390    case GLSL_TYPE_UINT:
391    case GLSL_TYPE_INT:
392    case GLSL_TYPE_FLOAT:
393    case GLSL_TYPE_BOOL:
394       if (type->is_matrix()) {
395          return 4; /* FINISHME: Not all matrices are 4x4. */
396       } else {
397          /* Regardless of size of vector, it gets a vec4. This is bad
398           * packing for things like floats, but otherwise arrays become a
399           * mess.  Hopefully a later pass over the code can pack scalars
400           * down if appropriate.
401           */
402          return 1;
403       }
404    case GLSL_TYPE_ARRAY:
405       return type_size(type->fields.array) * type->length;
406    case GLSL_TYPE_STRUCT:
407       size = 0;
408       for (i = 0; i < type->length; i++) {
409          size += type_size(type->fields.structure[i].type);
410       }
411       return size;
412    default:
413       assert(0);
414    }
415 }
416
417 temp_entry *
418 ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
419 {
420    
421    temp_entry *entry;
422
423    foreach_iter(exec_list_iterator, iter, this->variable_storage) {
424       entry = (temp_entry *)iter.get();
425
426       if (entry->var == var)
427          return entry;
428    }
429
430    return NULL;
431 }
432
433 void
434 ir_to_mesa_visitor::visit(ir_variable *ir)
435 {
436    (void)ir;
437 }
438
439 void
440 ir_to_mesa_visitor::visit(ir_loop *ir)
441 {
442    assert(!ir->from);
443    assert(!ir->to);
444    assert(!ir->increment);
445    assert(!ir->counter);
446
447    ir_to_mesa_emit_op1(NULL, OPCODE_BGNLOOP,
448                        ir_to_mesa_undef_dst, ir_to_mesa_undef);
449
450    visit_exec_list(&ir->body_instructions, this);
451
452    ir_to_mesa_emit_op1(NULL, OPCODE_ENDLOOP,
453                        ir_to_mesa_undef_dst, ir_to_mesa_undef);
454 }
455
456 void
457 ir_to_mesa_visitor::visit(ir_loop_jump *ir)
458 {
459    switch (ir->mode) {
460    case ir_loop_jump::jump_break:
461       ir_to_mesa_emit_op1(NULL, OPCODE_BRK,
462                           ir_to_mesa_undef_dst, ir_to_mesa_undef);
463       break;
464    case ir_loop_jump::jump_continue:
465       ir_to_mesa_emit_op1(NULL, OPCODE_CONT,
466                           ir_to_mesa_undef_dst, ir_to_mesa_undef);
467       break;
468    }
469 }
470
471
472 void
473 ir_to_mesa_visitor::visit(ir_function_signature *ir)
474 {
475    assert(0);
476    (void)ir;
477 }
478
479 void
480 ir_to_mesa_visitor::visit(ir_function *ir)
481 {
482    /* Ignore function bodies other than main() -- we shouldn't see calls to
483     * them since they should all be inlined before we get to ir_to_mesa.
484     */
485    if (strcmp(ir->name, "main") == 0) {
486       const ir_function_signature *sig;
487       exec_list empty;
488
489       sig = ir->matching_signature(&empty);
490
491       assert(sig);
492
493       foreach_iter(exec_list_iterator, iter, sig->body) {
494          ir_instruction *ir = (ir_instruction *)iter.get();
495
496          ir->accept(this);
497       }
498    }
499 }
500
501 void
502 ir_to_mesa_visitor::visit(ir_expression *ir)
503 {
504    unsigned int operand;
505    struct ir_to_mesa_src_reg op[2];
506    struct ir_to_mesa_src_reg result_src;
507    struct ir_to_mesa_dst_reg result_dst;
508    const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
509    const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
510    const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
511
512    for (operand = 0; operand < ir->get_num_operands(); operand++) {
513       this->result.file = PROGRAM_UNDEFINED;
514       ir->operands[operand]->accept(this);
515       if (this->result.file == PROGRAM_UNDEFINED) {
516          ir_print_visitor v;
517          printf("Failed to get tree for expression operand:\n");
518          ir->operands[operand]->accept(&v);
519          exit(1);
520       }
521       op[operand] = this->result;
522
523       /* Only expression implemented for matrices yet */
524       assert(!ir->operands[operand]->type->is_matrix() ||
525              ir->operation == ir_binop_mul);
526    }
527
528    this->result.file = PROGRAM_UNDEFINED;
529
530    /* Storage for our result.  Ideally for an assignment we'd be using
531     * the actual storage for the result here, instead.
532     */
533    result_src = get_temp(ir->type);
534    /* convenience for the emit functions below. */
535    result_dst = ir_to_mesa_dst_reg_from_src(result_src);
536    /* Limit writes to the channels that will be used by result_src later.
537     * This does limit this temp's use as a temporary for multi-instruction
538     * sequences.
539     */
540    result_dst.writemask = (1 << ir->type->vector_elements) - 1;
541
542    switch (ir->operation) {
543    case ir_unop_logic_not:
544       ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
545                           op[0], src_reg_for_float(0.0));
546       break;
547    case ir_unop_neg:
548       op[0].negate = ~op[0].negate;
549       result_src = op[0];
550       break;
551    case ir_unop_exp:
552       ir_to_mesa_emit_scalar_op1(ir, OPCODE_EXP, result_dst, op[0]);
553       break;
554    case ir_unop_exp2:
555       ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
556       break;
557    case ir_unop_log:
558       ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
559       break;
560    case ir_unop_log2:
561       ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
562       break;
563    case ir_unop_sin:
564       ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
565       break;
566    case ir_unop_cos:
567       ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
568       break;
569    case ir_binop_add:
570       ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
571       break;
572    case ir_binop_sub:
573       ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
574       break;
575    case ir_binop_mul:
576       if (ir->operands[0]->type->is_matrix() &&
577           !ir->operands[1]->type->is_matrix()) {
578          if (ir->operands[0]->type->is_scalar()) {
579             ir_to_mesa_dst_reg dst_column = result_dst;
580             ir_to_mesa_src_reg src_column = op[0];
581             for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
582                ir_to_mesa_emit_op2(ir, OPCODE_MUL,
583                                    dst_column, src_column, op[1]);
584                dst_column.index++;
585                src_column.index++;
586             }
587          } else {
588             ir_to_mesa_dst_reg dst_chan = result_dst;
589             ir_to_mesa_src_reg src_column = op[0];
590             ir_to_mesa_src_reg src_chan = op[1];
591             for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
592                dst_chan.writemask = (1 << i);
593                src_chan.swizzle = MAKE_SWIZZLE4(i, i, i, i);
594                ir_to_mesa_emit_op2(ir, OPCODE_MUL,
595                                    dst_chan, src_column, src_chan);
596                src_column.index++;
597             }
598          }
599       } else {
600          assert(!ir->operands[0]->type->is_matrix());
601          assert(!ir->operands[1]->type->is_matrix());
602          ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
603       }
604       break;
605    case ir_binop_div:
606       ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[1]);
607       ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], result_src);
608       break;
609
610    case ir_binop_less:
611       ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
612       break;
613    case ir_binop_greater:
614       ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
615       break;
616    case ir_binop_lequal:
617       ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
618       break;
619    case ir_binop_gequal:
620       ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
621       break;
622    case ir_binop_equal:
623       ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
624       break;
625    case ir_binop_logic_xor:
626    case ir_binop_nequal:
627       ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
628       break;
629
630    case ir_binop_logic_or:
631       /* This could be a saturated add and skip the SNE. */
632       ir_to_mesa_emit_op2(ir, OPCODE_ADD,
633                           result_dst,
634                           op[0], op[1]);
635
636       ir_to_mesa_emit_op2(ir, OPCODE_SNE,
637                           result_dst,
638                           result_src, src_reg_for_float(0.0));
639       break;
640
641    case ir_binop_logic_and:
642       /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
643       ir_to_mesa_emit_op2(ir, OPCODE_MUL,
644                           result_dst,
645                           op[0], op[1]);
646       break;
647
648    case ir_binop_dot:
649       if (ir->operands[0]->type == vec4_type) {
650          assert(ir->operands[1]->type == vec4_type);
651          ir_to_mesa_emit_op2(ir, OPCODE_DP4,
652                              result_dst,
653                              op[0], op[1]);
654       } else if (ir->operands[0]->type == vec3_type) {
655          assert(ir->operands[1]->type == vec3_type);
656          ir_to_mesa_emit_op2(ir, OPCODE_DP3,
657                              result_dst,
658                              op[0], op[1]);
659       } else if (ir->operands[0]->type == vec2_type) {
660          assert(ir->operands[1]->type == vec2_type);
661          ir_to_mesa_emit_op2(ir, OPCODE_DP2,
662                              result_dst,
663                              op[0], op[1]);
664       }
665       break;
666    case ir_unop_sqrt:
667       ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
668       ir_to_mesa_emit_op1(ir, OPCODE_RCP, result_dst, result_src);
669       break;
670    case ir_unop_rsq:
671       ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
672       break;
673    case ir_unop_i2f:
674       /* Mesa IR lacks types, ints are stored as truncated floats. */
675       result_src = op[0];
676       break;
677    case ir_unop_f2i:
678       ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
679       break;
680    case ir_unop_f2b:
681       ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
682                           result_src, src_reg_for_float(0.0));
683       break;
684    case ir_unop_trunc:
685       ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
686       break;
687    case ir_unop_ceil:
688       op[0].negate = ~op[0].negate;
689       ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
690       result_src.negate = ~result_src.negate;
691       break;
692    case ir_unop_floor:
693       ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
694       break;
695    case ir_binop_min:
696       ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
697       break;
698    case ir_binop_max:
699       ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
700       break;
701    default:
702       ir_print_visitor v;
703       printf("Failed to get tree for expression:\n");
704       ir->accept(&v);
705       exit(1);
706       break;
707    }
708
709    this->result = result_src;
710 }
711
712
713 void
714 ir_to_mesa_visitor::visit(ir_swizzle *ir)
715 {
716    ir_to_mesa_src_reg src_reg;
717    int i;
718    int swizzle[4];
719
720    /* Note that this is only swizzles in expressions, not those on the left
721     * hand side of an assignment, which do write masking.  See ir_assignment
722     * for that.
723     */
724
725    ir->val->accept(this);
726    src_reg = this->result;
727    assert(src_reg.file != PROGRAM_UNDEFINED);
728
729    for (i = 0; i < 4; i++) {
730       if (i < ir->type->vector_elements) {
731          switch (i) {
732          case 0:
733             swizzle[i] = ir->mask.x;
734             break;
735          case 1:
736             swizzle[i] = ir->mask.y;
737             break;
738          case 2:
739             swizzle[i] = ir->mask.z;
740             break;
741          case 3:
742             swizzle[i] = ir->mask.w;
743             break;
744          }
745       } else {
746          /* If the type is smaller than a vec4, replicate the last
747           * channel out.
748           */
749          swizzle[i] = ir->type->vector_elements - 1;
750       }
751    }
752
753    src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
754                                    swizzle[1],
755                                    swizzle[2],
756                                    swizzle[3]);
757
758    this->result = src_reg;
759 }
760
761 void
762 ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
763 {
764    ir_to_mesa_src_reg src_reg;
765    temp_entry *entry = find_variable_storage(ir->var);
766    unsigned int i;
767    bool var_in;
768
769    if (!entry) {
770       switch (ir->var->mode) {
771       case ir_var_uniform:
772          entry = new(ctx)  temp_entry(ir->var, PROGRAM_UNIFORM,
773                                       this->next_uniform);
774          this->variable_storage.push_tail(entry);
775
776          this->next_uniform += type_size(ir->var->type);
777          break;
778       case ir_var_in:
779       case ir_var_out:
780       case ir_var_inout:
781          var_in = (ir->var->mode == ir_var_in ||
782                    ir->var->mode == ir_var_inout);
783
784          for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
785             bool in = builtin_var_to_mesa_reg[i].file == PROGRAM_INPUT;
786
787             if (strcmp(ir->var->name, builtin_var_to_mesa_reg[i].name) == 0 &&
788                 !(var_in ^ in))
789                break;
790          }
791          if (i == ARRAY_SIZE(builtin_var_to_mesa_reg)) {
792             printf("Failed to find builtin for %s variable %s\n",
793                    var_in ? "in" : "out",
794                    ir->var->name);
795             abort();
796          }
797          entry = new(ctx)  temp_entry(ir->var,
798                                       builtin_var_to_mesa_reg[i].file,
799                                       builtin_var_to_mesa_reg[i].index);
800          break;
801       case ir_var_auto:
802          entry = new(ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
803                                      this->next_temp);
804          this->variable_storage.push_tail(entry);
805
806          next_temp += type_size(ir->var->type);
807          break;
808       }
809
810       if (!entry) {
811          printf("Failed to make storage for %s\n", ir->var->name);
812          exit(1);
813       }
814    }
815
816    src_reg.file = entry->file;
817    src_reg.index = entry->index;
818    /* If the type is smaller than a vec4, replicate the last channel out. */
819    src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
820    src_reg.reladdr = false;
821    src_reg.negate = 0;
822
823    this->result = src_reg;
824 }
825
826 void
827 ir_to_mesa_visitor::visit(ir_dereference_array *ir)
828 {
829    ir_constant *index;
830    ir_to_mesa_src_reg src_reg;
831
832    index = ir->array_index->constant_expression_value();
833
834    /* By the time we make it to this stage, matrices should be broken down
835     * to vectors.
836     */
837    assert(!ir->type->is_matrix());
838
839    ir->array->accept(this);
840    src_reg = this->result;
841
842    if (src_reg.file == PROGRAM_INPUT ||
843        src_reg.file == PROGRAM_OUTPUT) {
844       assert(index); /* FINISHME: Handle variable indexing of builtins. */
845
846       src_reg.index += index->value.i[0];
847    } else {
848       if (index) {
849          src_reg.index += index->value.i[0];
850       } else {
851          ir_to_mesa_src_reg array_base = this->result;
852          /* Variable index array dereference.  It eats the "vec4" of the
853           * base of the array and an index that offsets the Mesa register
854           * index.
855           */
856          ir->array_index->accept(this);
857
858          /* FINISHME: This doesn't work when we're trying to do the LHS
859           * of an assignment.
860           */
861          src_reg.reladdr = true;
862          ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
863                              this->result);
864
865          this->result = get_temp(ir->type);
866          ir_to_mesa_emit_op1(ir, OPCODE_MOV,
867                              ir_to_mesa_dst_reg_from_src(this->result),
868                              src_reg);
869       }
870    }
871
872    /* If the type is smaller than a vec4, replicate the last channel out. */
873    src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
874
875    this->result = src_reg;
876 }
877
878 void
879 ir_to_mesa_visitor::visit(ir_dereference_record *ir)
880 {
881    unsigned int i;
882    const glsl_type *struct_type = ir->record->type;
883    int offset = 0;
884
885    ir->record->accept(this);
886
887    for (i = 0; i < struct_type->length; i++) {
888       if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
889          break;
890       offset += type_size(struct_type->fields.structure[i].type);
891    }
892    this->result.index += offset;
893 }
894
895 /**
896  * We want to be careful in assignment setup to hit the actual storage
897  * instead of potentially using a temporary like we might with the
898  * ir_dereference handler.
899  *
900  * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
901  * should only see potentially one variable array index of a vector,
902  * and one swizzle, before getting to actual vec4 storage.  So handle
903  * those, then go use ir_dereference to handle the rest.
904  */
905 static struct ir_to_mesa_dst_reg
906 get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
907 {
908    struct ir_to_mesa_dst_reg dst_reg;
909    ir_dereference *deref;
910    ir_swizzle *swiz;
911
912    /* Use the rvalue deref handler for the most part.  We'll ignore
913     * swizzles in it and write swizzles using writemask, though.
914     */
915    ir->accept(v);
916    dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
917
918    if ((deref = ir->as_dereference())) {
919       ir_dereference_array *deref_array = ir->as_dereference_array();
920       assert(!deref_array || deref_array->array->type->is_array());
921
922       ir->accept(v);
923    } else if ((swiz = ir->as_swizzle())) {
924       dst_reg.writemask = 0;
925       if (swiz->mask.num_components >= 1)
926          dst_reg.writemask |= (1 << swiz->mask.x);
927       if (swiz->mask.num_components >= 2)
928          dst_reg.writemask |= (1 << swiz->mask.y);
929       if (swiz->mask.num_components >= 3)
930          dst_reg.writemask |= (1 << swiz->mask.z);
931       if (swiz->mask.num_components >= 4)
932          dst_reg.writemask |= (1 << swiz->mask.w);
933    }
934
935    return dst_reg;
936 }
937
938 void
939 ir_to_mesa_visitor::visit(ir_assignment *ir)
940 {
941    struct ir_to_mesa_dst_reg l;
942    struct ir_to_mesa_src_reg r;
943
944    assert(!ir->lhs->type->is_matrix());
945    assert(!ir->lhs->type->is_array());
946    assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
947
948    l = get_assignment_lhs(ir->lhs, this);
949
950    ir->rhs->accept(this);
951    r = this->result;
952    assert(l.file != PROGRAM_UNDEFINED);
953    assert(r.file != PROGRAM_UNDEFINED);
954
955    if (ir->condition) {
956          ir_constant *condition_constant;
957
958          condition_constant = ir->condition->constant_expression_value();
959
960          assert(condition_constant && condition_constant->value.b[0]);
961    }
962
963    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
964 }
965
966
967 void
968 ir_to_mesa_visitor::visit(ir_constant *ir)
969 {
970    ir_to_mesa_src_reg src_reg;
971
972    assert(ir->type->base_type == GLSL_TYPE_FLOAT ||
973           ir->type->base_type == GLSL_TYPE_UINT ||
974           ir->type->base_type == GLSL_TYPE_INT ||
975           ir->type->base_type == GLSL_TYPE_BOOL);
976
977    /* FINISHME: This will end up being _mesa_add_unnamed_constant,
978     * which handles sharing values and sharing channels of vec4
979     * constants for small values.
980     */
981    /* FINISHME: Do something with the constant values for now.
982     */
983    src_reg.file = PROGRAM_CONSTANT;
984    src_reg.index = this->next_constant;
985    src_reg.swizzle = SWIZZLE_NOOP;
986    src_reg.reladdr = false;
987    src_reg.negate = 0;
988
989    this->next_constant += type_size(ir->type);
990
991    this->result = src_reg;
992 }
993
994
995 void
996 ir_to_mesa_visitor::visit(ir_call *ir)
997 {
998    printf("Can't support call to %s\n", ir->callee_name());
999    exit(1);
1000 }
1001
1002
1003 void
1004 ir_to_mesa_visitor::visit(ir_texture *ir)
1005 {
1006    assert(0);
1007
1008    ir->coordinate->accept(this);
1009 }
1010
1011 void
1012 ir_to_mesa_visitor::visit(ir_return *ir)
1013 {
1014    assert(0);
1015
1016    ir->get_value()->accept(this);
1017 }
1018
1019
1020 void
1021 ir_to_mesa_visitor::visit(ir_if *ir)
1022 {
1023    ir_to_mesa_instruction *if_inst, *else_inst = NULL;
1024
1025    ir->condition->accept(this);
1026    assert(this->result.file != PROGRAM_UNDEFINED);
1027
1028    if_inst = ir_to_mesa_emit_op1(ir->condition,
1029                                  OPCODE_IF, ir_to_mesa_undef_dst,
1030                                  this->result);
1031
1032    this->instructions.push_tail(if_inst);
1033
1034    visit_exec_list(&ir->then_instructions, this);
1035
1036    if (!ir->else_instructions.is_empty()) {
1037       else_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ELSE,
1038                                       ir_to_mesa_undef_dst,
1039                                       ir_to_mesa_undef);
1040       visit_exec_list(&ir->then_instructions, this);
1041    }
1042
1043    if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
1044                                  ir_to_mesa_undef_dst, ir_to_mesa_undef);
1045 }
1046
1047 ir_to_mesa_visitor::ir_to_mesa_visitor()
1048 {
1049    result.file = PROGRAM_UNDEFINED;
1050    next_temp = 1;
1051    next_constant = 0;
1052    next_uniform = 0;
1053 }
1054
1055 static struct prog_src_register
1056 mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
1057 {
1058    struct prog_src_register mesa_reg;
1059
1060    mesa_reg.File = reg.file;
1061    assert(reg.index < (1 << INST_INDEX_BITS) - 1);
1062    mesa_reg.Index = reg.index;
1063    mesa_reg.Swizzle = reg.swizzle;
1064    mesa_reg.RelAddr = reg.reladdr;
1065
1066    return mesa_reg;
1067 }
1068
1069 static void
1070 set_branchtargets(struct prog_instruction *mesa_instructions,
1071                   int num_instructions)
1072 {
1073    int if_count = 0, loop_count;
1074    int *if_stack, *loop_stack;
1075    int if_stack_pos = 0, loop_stack_pos = 0;
1076    int i, j;
1077
1078    for (i = 0; i < num_instructions; i++) {
1079       switch (mesa_instructions[i].Opcode) {
1080       case OPCODE_IF:
1081          if_count++;
1082          break;
1083       case OPCODE_BGNLOOP:
1084          loop_count++;
1085          break;
1086       case OPCODE_BRK:
1087       case OPCODE_CONT:
1088          mesa_instructions[i].BranchTarget = -1;
1089          break;
1090       default:
1091          break;
1092       }
1093    }
1094
1095    if_stack = (int *)calloc(if_count, sizeof(*if_stack));
1096    loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
1097
1098    for (i = 0; i < num_instructions; i++) {
1099       switch (mesa_instructions[i].Opcode) {
1100       case OPCODE_IF:
1101          if_stack[if_stack_pos] = i;
1102          if_stack_pos++;
1103          break;
1104       case OPCODE_ELSE:
1105          mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1106          if_stack[if_stack_pos - 1] = i;
1107          break;
1108       case OPCODE_ENDIF:
1109          mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1110          if_stack_pos--;
1111          break;
1112       case OPCODE_BGNLOOP:
1113          loop_stack[loop_stack_pos] = i;
1114          loop_stack_pos++;
1115          break;
1116       case OPCODE_ENDLOOP:
1117          loop_stack_pos--;
1118          /* Rewrite any breaks/conts at this nesting level (haven't
1119           * already had a BranchTarget assigned) to point to the end
1120           * of the loop.
1121           */
1122          for (j = loop_stack[loop_stack_pos]; j < i; j++) {
1123             if (mesa_instructions[j].Opcode == OPCODE_BRK ||
1124                 mesa_instructions[j].Opcode == OPCODE_CONT) {
1125                if (mesa_instructions[j].BranchTarget == -1) {
1126                   mesa_instructions[j].BranchTarget = i;
1127                }
1128             }
1129          }
1130          /* The loop ends point at each other. */
1131          mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
1132          mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
1133       default:
1134          break;
1135       }
1136    }
1137
1138    free(if_stack);
1139 }
1140
1141 static void
1142 print_program(struct prog_instruction *mesa_instructions,
1143               ir_instruction **mesa_instruction_annotation,
1144               int num_instructions)
1145 {
1146    ir_instruction *last_ir = NULL;
1147    int i;
1148
1149    for (i = 0; i < num_instructions; i++) {
1150       struct prog_instruction *mesa_inst = mesa_instructions + i;
1151       ir_instruction *ir = mesa_instruction_annotation[i];
1152
1153       if (last_ir != ir && ir) {
1154          ir_print_visitor print;
1155          ir->accept(&print);
1156          printf("\n");
1157          last_ir = ir;
1158       }
1159
1160       _mesa_print_instruction(mesa_inst);
1161    }
1162 }
1163
1164 void
1165 do_ir_to_mesa(exec_list *instructions)
1166 {
1167    ir_to_mesa_visitor v;
1168    struct prog_instruction *mesa_instructions, *mesa_inst;
1169    ir_instruction **mesa_instruction_annotation;
1170    int i;
1171
1172    v.ctx = talloc_new(NULL);
1173    visit_exec_list(instructions, &v);
1174
1175    int num_instructions = 0;
1176    foreach_iter(exec_list_iterator, iter, v.instructions) {
1177       num_instructions++;
1178    }
1179
1180    mesa_instructions =
1181       (struct prog_instruction *)calloc(num_instructions,
1182                                         sizeof(*mesa_instructions));
1183    mesa_instruction_annotation =
1184       (ir_instruction **)calloc(num_instructions,
1185                                 sizeof(*mesa_instruction_annotation));
1186
1187    mesa_inst = mesa_instructions;
1188    i = 0;
1189    foreach_iter(exec_list_iterator, iter, v.instructions) {
1190       ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
1191
1192       mesa_inst->Opcode = inst->op;
1193       mesa_inst->DstReg.File = inst->dst_reg.file;
1194       mesa_inst->DstReg.Index = inst->dst_reg.index;
1195       mesa_inst->DstReg.CondMask = COND_TR;
1196       mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
1197       mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
1198       mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
1199       mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
1200       mesa_instruction_annotation[i] = inst->ir;
1201
1202       mesa_inst++;
1203       i++;
1204    }
1205
1206    set_branchtargets(mesa_instructions, num_instructions);
1207    print_program(mesa_instructions, mesa_instruction_annotation, num_instructions);
1208
1209    free(mesa_instruction_annotation);
1210    talloc_free(v.ctx);
1211 }