ir_constant_expression.cpp revision 3fab376bef8c5f407d4011b89a17ea4fd414f213
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_constant_expression.cpp
26 * Evaluate and process constant valued expressions
27 *
28 * In GLSL, constant valued expressions are used in several places.  These
29 * must be processed and evaluated very early in the compilation process.
30 *
31 *    * Sizes of arrays
32 *    * Initializers for uniforms
33 *    * Initializers for \c const variables
34 */
35
36#include <math.h>
37#include "ir.h"
38#include "ir_visitor.h"
39#include "glsl_types.h"
40
41/**
42 * Visitor class for evaluating constant expressions
43 */
44class ir_constant_visitor : public ir_visitor {
45public:
46   ir_constant_visitor()
47      : value(NULL)
48   {
49      /* empty */
50   }
51
52   virtual ~ir_constant_visitor()
53   {
54      /* empty */
55   }
56
57   /**
58    * \name Visit methods
59    *
60    * As typical for the visitor pattern, there must be one \c visit method for
61    * each concrete subclass of \c ir_instruction.  Virtual base classes within
62    * the hierarchy should not have \c visit methods.
63    */
64   /*@{*/
65   virtual void visit(ir_variable *);
66   virtual void visit(ir_function_signature *);
67   virtual void visit(ir_function *);
68   virtual void visit(ir_expression *);
69   virtual void visit(ir_texture *);
70   virtual void visit(ir_swizzle *);
71   virtual void visit(ir_dereference_variable *);
72   virtual void visit(ir_dereference_array *);
73   virtual void visit(ir_dereference_record *);
74   virtual void visit(ir_assignment *);
75   virtual void visit(ir_constant *);
76   virtual void visit(ir_call *);
77   virtual void visit(ir_return *);
78   virtual void visit(ir_discard *);
79   virtual void visit(ir_if *);
80   virtual void visit(ir_loop *);
81   virtual void visit(ir_loop_jump *);
82   /*@}*/
83
84   /**
85    * Value of the constant expression.
86    *
87    * \note
88    * This field will be \c NULL if the expression is not constant valued.
89    */
90   /* FINIHSME: This cannot hold values for constant arrays or structures. */
91   ir_constant *value;
92};
93
94
95ir_constant *
96ir_instruction::constant_expression_value()
97{
98   ir_constant_visitor visitor;
99
100   this->accept(& visitor);
101   return visitor.value;
102}
103
104
105void
106ir_constant_visitor::visit(ir_variable *ir)
107{
108   (void) ir;
109   value = NULL;
110}
111
112
113void
114ir_constant_visitor::visit(ir_function_signature *ir)
115{
116   (void) ir;
117   value = NULL;
118}
119
120
121void
122ir_constant_visitor::visit(ir_function *ir)
123{
124   (void) ir;
125   value = NULL;
126}
127
128void
129ir_constant_visitor::visit(ir_expression *ir)
130{
131   value = NULL;
132   ir_constant *op[2] = { NULL, NULL };
133   ir_constant_data data;
134
135   memset(&data, 0, sizeof(data));
136
137   for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
138      op[operand] = ir->operands[operand]->constant_expression_value();
139      if (!op[operand])
140	 return;
141   }
142
143   if (op[1] != NULL)
144      assert(op[0]->type->base_type == op[1]->type->base_type);
145
146   bool op0_scalar = op[0]->type->is_scalar();
147   bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
148
149   /* When iterating over a vector or matrix's components, we want to increase
150    * the loop counter.  However, for scalars, we want to stay at 0.
151    */
152   unsigned c0_inc = op0_scalar ? 0 : 1;
153   unsigned c1_inc = op1_scalar ? 0 : 1;
154   unsigned components;
155   if (op1_scalar || !op[1]) {
156      components = op[0]->type->components();
157   } else {
158      components = op[1]->type->components();
159   }
160
161   switch (ir->operation) {
162   case ir_unop_logic_not:
163      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
164      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
165	 data.b[c] = !op[0]->value.b[c];
166      break;
167
168   case ir_unop_f2i:
169      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
170      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
171	 data.i[c] = op[0]->value.f[c];
172      }
173      break;
174   case ir_unop_i2f:
175      assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
176	     op[0]->type->base_type == GLSL_TYPE_INT);
177      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
178	 if (op[0]->type->base_type == GLSL_TYPE_INT)
179	    data.f[c] = op[0]->value.i[c];
180	 else
181	    data.f[c] = op[0]->value.u[c];
182      }
183      break;
184   case ir_unop_b2f:
185      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
186      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
187	 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
188      }
189      break;
190   case ir_unop_f2b:
191      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
192      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
193	 data.b[c] = bool(op[0]->value.f[c]);
194      }
195      break;
196   case ir_unop_b2i:
197      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
198      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
199	 data.u[c] = op[0]->value.b[c] ? 1 : 0;
200      }
201      break;
202   case ir_unop_i2b:
203      assert(op[0]->type->is_integer());
204      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
205	 data.b[c] = bool(op[0]->value.u[c]);
206      }
207      break;
208
209   case ir_unop_trunc:
210      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
211      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
212	 data.f[c] = truncf(op[0]->value.f[c]);
213      }
214      break;
215
216   case ir_unop_ceil:
217      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
218      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
219	 data.f[c] = ceilf(op[0]->value.f[c]);
220      }
221      break;
222
223   case ir_unop_floor:
224      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
225      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
226	 data.f[c] = floorf(op[0]->value.f[c]);
227      }
228      break;
229
230   case ir_unop_fract:
231      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
232	 switch (ir->type->base_type) {
233	 case GLSL_TYPE_UINT:
234	    data.u[c] = 0;
235	    break;
236	 case GLSL_TYPE_INT:
237	    data.i[c] = 0;
238	    break;
239	 case GLSL_TYPE_FLOAT:
240	    data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
241	    break;
242	 default:
243	    assert(0);
244	 }
245      }
246      break;
247
248   case ir_unop_sin:
249      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
250      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
251	 data.f[c] = sinf(op[0]->value.f[c]);
252      }
253      break;
254
255   case ir_unop_cos:
256      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
257      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
258	 data.f[c] = cosf(op[0]->value.f[c]);
259      }
260      break;
261
262   case ir_unop_neg:
263      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
264	 switch (ir->type->base_type) {
265	 case GLSL_TYPE_UINT:
266	    data.u[c] = -op[0]->value.u[c];
267	    break;
268	 case GLSL_TYPE_INT:
269	    data.i[c] = -op[0]->value.i[c];
270	    break;
271	 case GLSL_TYPE_FLOAT:
272	    data.f[c] = -op[0]->value.f[c];
273	    break;
274	 default:
275	    assert(0);
276	 }
277      }
278      break;
279
280   case ir_unop_abs:
281      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
282	 switch (ir->type->base_type) {
283	 case GLSL_TYPE_UINT:
284	    data.u[c] = op[0]->value.u[c];
285	    break;
286	 case GLSL_TYPE_INT:
287	    data.i[c] = op[0]->value.i[c];
288	    if (data.i[c] < 0)
289	       data.i[c] = -data.i[c];
290	    break;
291	 case GLSL_TYPE_FLOAT:
292	    data.f[c] = fabs(op[0]->value.f[c]);
293	    break;
294	 default:
295	    assert(0);
296	 }
297      }
298      break;
299
300   case ir_unop_sign:
301      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
302	 switch (ir->type->base_type) {
303	 case GLSL_TYPE_UINT:
304	    data.u[c] = op[0]->value.i[c] > 0;
305	    break;
306	 case GLSL_TYPE_INT:
307	    data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
308	    break;
309	 case GLSL_TYPE_FLOAT:
310	    data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
311	    break;
312	 default:
313	    assert(0);
314	 }
315      }
316      break;
317
318   case ir_unop_rcp:
319      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
320      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
321	 switch (ir->type->base_type) {
322	 case GLSL_TYPE_UINT:
323	    if (op[0]->value.u[c] != 0.0)
324	       data.u[c] = 1 / op[0]->value.u[c];
325	    break;
326	 case GLSL_TYPE_INT:
327	    if (op[0]->value.i[c] != 0.0)
328	       data.i[c] = 1 / op[0]->value.i[c];
329	    break;
330	 case GLSL_TYPE_FLOAT:
331	    if (op[0]->value.f[c] != 0.0)
332	       data.f[c] = 1.0 / op[0]->value.f[c];
333	    break;
334	 default:
335	    assert(0);
336	 }
337      }
338      break;
339
340   case ir_unop_rsq:
341      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
342      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
343	 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
344      }
345      break;
346
347   case ir_unop_sqrt:
348      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
349      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
350	 data.f[c] = sqrtf(op[0]->value.f[c]);
351      }
352      break;
353
354   case ir_unop_exp:
355      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
356      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
357	 data.f[c] = expf(op[0]->value.f[c]);
358      }
359      break;
360
361   case ir_unop_exp2:
362      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
363      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
364	 data.f[c] = exp2f(op[0]->value.f[c]);
365      }
366      break;
367
368   case ir_unop_log:
369      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
370      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
371	 data.f[c] = logf(op[0]->value.f[c]);
372      }
373      break;
374
375   case ir_unop_log2:
376      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
377      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
378	 data.f[c] = log2f(op[0]->value.f[c]);
379      }
380      break;
381
382   case ir_unop_dFdx:
383   case ir_unop_dFdy:
384      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
385      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
386	 data.f[c] = 0.0;
387      }
388      break;
389
390   case ir_binop_dot:
391      assert(op[0]->type->is_vector() && op[1]->type->is_vector());
392      data.f[0] = 0;
393      for (unsigned c = 0; c < op[0]->type->components(); c++) {
394	 switch (ir->operands[0]->type->base_type) {
395	 case GLSL_TYPE_UINT:
396	    data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
397	    break;
398	 case GLSL_TYPE_INT:
399	    data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
400	    break;
401	 case GLSL_TYPE_FLOAT:
402	    data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
403	    break;
404	 default:
405	    assert(0);
406	 }
407      }
408
409      break;
410   case ir_binop_add:
411      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
412      for (unsigned c = 0, c0 = 0, c1 = 0;
413	   c < components;
414	   c0 += c0_inc, c1 += c1_inc, c++) {
415
416	 switch (ir->operands[0]->type->base_type) {
417	 case GLSL_TYPE_UINT:
418	    data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
419	    break;
420	 case GLSL_TYPE_INT:
421	    data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
422	    break;
423	 case GLSL_TYPE_FLOAT:
424	    data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
425	    break;
426	 default:
427	    assert(0);
428	 }
429      }
430
431      break;
432   case ir_binop_sub:
433      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
434      for (unsigned c = 0, c0 = 0, c1 = 0;
435	   c < components;
436	   c0 += c0_inc, c1 += c1_inc, c++) {
437
438	 switch (ir->operands[0]->type->base_type) {
439	 case GLSL_TYPE_UINT:
440	    data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
441	    break;
442	 case GLSL_TYPE_INT:
443	    data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
444	    break;
445	 case GLSL_TYPE_FLOAT:
446	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
447	    break;
448	 default:
449	    assert(0);
450	 }
451      }
452
453      break;
454   case ir_binop_mul:
455      /* Check for equal types, or unequal types involving scalars */
456      if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
457	  || op0_scalar || op1_scalar) {
458	 for (unsigned c = 0, c0 = 0, c1 = 0;
459	      c < components;
460	      c0 += c0_inc, c1 += c1_inc, c++) {
461
462	    switch (ir->operands[0]->type->base_type) {
463	    case GLSL_TYPE_UINT:
464	       data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
465	       break;
466	    case GLSL_TYPE_INT:
467	       data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
468	       break;
469	    case GLSL_TYPE_FLOAT:
470	       data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
471	       break;
472	    default:
473	       assert(0);
474	    }
475	 }
476      } else {
477	 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
478
479	 /* Multiply an N-by-M matrix with an M-by-P matrix.  Since either
480	  * matrix can be a GLSL vector, either N or P can be 1.
481	  *
482	  * For vec*mat, the vector is treated as a row vector.  This
483	  * means the vector is a 1-row x M-column matrix.
484	  *
485	  * For mat*vec, the vector is treated as a column vector.  Since
486	  * matrix_columns is 1 for vectors, this just works.
487	  */
488	 const unsigned n = op[0]->type->is_vector()
489	    ? 1 : op[0]->type->vector_elements;
490	 const unsigned m = op[1]->type->vector_elements;
491	 const unsigned p = op[1]->type->matrix_columns;
492	 for (unsigned j = 0; j < p; j++) {
493	    for (unsigned i = 0; i < n; i++) {
494	       for (unsigned k = 0; k < m; k++) {
495		  data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
496	       }
497	    }
498	 }
499      }
500
501      break;
502   case ir_binop_div:
503      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
504      for (unsigned c = 0, c0 = 0, c1 = 0;
505	   c < components;
506	   c0 += c0_inc, c1 += c1_inc, c++) {
507
508	 switch (ir->operands[0]->type->base_type) {
509	 case GLSL_TYPE_UINT:
510	    data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
511	    break;
512	 case GLSL_TYPE_INT:
513	    data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
514	    break;
515	 case GLSL_TYPE_FLOAT:
516	    data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
517	    break;
518	 default:
519	    assert(0);
520	 }
521      }
522
523      break;
524   case ir_binop_logic_and:
525      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
526      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
527	 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
528      break;
529   case ir_binop_logic_xor:
530      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
531      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
532	 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
533      break;
534   case ir_binop_logic_or:
535      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
536      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
537	 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
538      break;
539
540   case ir_binop_less:
541      switch (ir->operands[0]->type->base_type) {
542      case GLSL_TYPE_UINT:
543	 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
544	 break;
545      case GLSL_TYPE_INT:
546	 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
547	 break;
548      case GLSL_TYPE_FLOAT:
549	 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
550	 break;
551      default:
552	 assert(0);
553      }
554      break;
555   case ir_binop_greater:
556      switch (ir->operands[0]->type->base_type) {
557      case GLSL_TYPE_UINT:
558	 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
559	 break;
560      case GLSL_TYPE_INT:
561	 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
562	 break;
563      case GLSL_TYPE_FLOAT:
564	 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
565	 break;
566      default:
567	 assert(0);
568      }
569      break;
570   case ir_binop_lequal:
571      switch (ir->operands[0]->type->base_type) {
572      case GLSL_TYPE_UINT:
573	 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
574	 break;
575      case GLSL_TYPE_INT:
576	 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
577	 break;
578      case GLSL_TYPE_FLOAT:
579	 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
580	 break;
581      default:
582	 assert(0);
583      }
584      break;
585   case ir_binop_gequal:
586      switch (ir->operands[0]->type->base_type) {
587      case GLSL_TYPE_UINT:
588	 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
589	 break;
590      case GLSL_TYPE_INT:
591	 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
592	 break;
593      case GLSL_TYPE_FLOAT:
594	 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
595	 break;
596      default:
597	 assert(0);
598      }
599      break;
600
601   case ir_binop_equal:
602      data.b[0] = true;
603      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
604	 switch (ir->operands[0]->type->base_type) {
605	 case GLSL_TYPE_UINT:
606	    data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
607	    break;
608	 case GLSL_TYPE_INT:
609	    data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
610	    break;
611	 case GLSL_TYPE_FLOAT:
612	    data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
613	    break;
614	 case GLSL_TYPE_BOOL:
615	    data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
616	    break;
617	 default:
618	    assert(0);
619	 }
620      }
621      break;
622   case ir_binop_nequal:
623      data.b[0] = false;
624      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
625	 switch (ir->operands[0]->type->base_type) {
626	 case GLSL_TYPE_UINT:
627	    data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
628	    break;
629	 case GLSL_TYPE_INT:
630	    data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
631	    break;
632	 case GLSL_TYPE_FLOAT:
633	    data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
634	    break;
635	 case GLSL_TYPE_BOOL:
636	    data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
637	    break;
638	 default:
639	    assert(0);
640	 }
641      }
642      break;
643
644   default:
645      /* FINISHME: Should handle all expression types. */
646      return;
647   }
648
649   void *ctx = talloc_parent(ir);
650   this->value = new(ctx) ir_constant(ir->type, &data);
651}
652
653
654void
655ir_constant_visitor::visit(ir_texture *ir)
656{
657   // FINISHME: Do stuff with texture lookups
658   (void) ir;
659   value = NULL;
660}
661
662
663void
664ir_constant_visitor::visit(ir_swizzle *ir)
665{
666   ir_constant *v = ir->val->constant_expression_value();
667
668   this->value = NULL;
669
670   if (v != NULL) {
671      ir_constant_data data;
672
673      const unsigned swiz_idx[4] = {
674	 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
675      };
676
677      for (unsigned i = 0; i < ir->mask.num_components; i++) {
678	 switch (v->type->base_type) {
679	 case GLSL_TYPE_UINT:
680	 case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
681	 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
682	 case GLSL_TYPE_BOOL:  data.b[i] = v->value.b[swiz_idx[i]]; break;
683	 default:              assert(!"Should not get here."); break;
684	 }
685      }
686
687      void *ctx = talloc_parent(ir);
688      this->value = new(ctx) ir_constant(ir->type, &data);
689   }
690}
691
692
693void
694ir_constant_visitor::visit(ir_dereference_variable *ir)
695{
696   value = NULL;
697
698   ir_variable *var = ir->variable_referenced();
699   if (var && var->constant_value)
700      value = var->constant_value->clone(NULL);
701}
702
703
704void
705ir_constant_visitor::visit(ir_dereference_array *ir)
706{
707   void *ctx = talloc_parent(ir);
708   ir_constant *array = ir->array->constant_expression_value();
709   ir_constant *idx = ir->array_index->constant_expression_value();
710
711   this->value = NULL;
712
713   if ((array != NULL) && (idx != NULL)) {
714      if (array->type->is_matrix()) {
715	 /* Array access of a matrix results in a vector.
716	  */
717	 const unsigned column = idx->value.u[0];
718
719	 const glsl_type *const column_type = array->type->column_type();
720
721	 /* Offset in the constant matrix to the first element of the column
722	  * to be extracted.
723	  */
724	 const unsigned mat_idx = column * column_type->vector_elements;
725
726	 ir_constant_data data;
727
728	 switch (column_type->base_type) {
729	 case GLSL_TYPE_UINT:
730	 case GLSL_TYPE_INT:
731	    for (unsigned i = 0; i < column_type->vector_elements; i++)
732	       data.u[i] = array->value.u[mat_idx + i];
733
734	    break;
735
736	 case GLSL_TYPE_FLOAT:
737	    for (unsigned i = 0; i < column_type->vector_elements; i++)
738	       data.f[i] = array->value.f[mat_idx + i];
739
740	    break;
741
742	 default:
743	    assert(!"Should not get here.");
744	    break;
745	 }
746
747	 this->value = new(ctx) ir_constant(column_type, &data);
748      } else if (array->type->is_vector()) {
749	 const unsigned component = idx->value.u[0];
750
751	 this->value = new(ctx) ir_constant(array, component);
752      } else {
753	 /* FINISHME: Handle access of constant arrays. */
754      }
755   }
756}
757
758
759void
760ir_constant_visitor::visit(ir_dereference_record *ir)
761{
762   ir_constant *v = ir->record->constant_expression_value();
763
764   this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
765}
766
767
768void
769ir_constant_visitor::visit(ir_assignment *ir)
770{
771   (void) ir;
772   value = NULL;
773}
774
775
776void
777ir_constant_visitor::visit(ir_constant *ir)
778{
779   value = ir;
780}
781
782
783void
784ir_constant_visitor::visit(ir_call *ir)
785{
786   (void) ir;
787   value = NULL;
788}
789
790
791void
792ir_constant_visitor::visit(ir_return *ir)
793{
794   (void) ir;
795   value = NULL;
796}
797
798
799void
800ir_constant_visitor::visit(ir_discard *ir)
801{
802   (void) ir;
803   value = NULL;
804}
805
806
807void
808ir_constant_visitor::visit(ir_if *ir)
809{
810   (void) ir;
811   value = NULL;
812}
813
814
815void
816ir_constant_visitor::visit(ir_loop *ir)
817{
818   (void) ir;
819   value = NULL;
820}
821
822
823void
824ir_constant_visitor::visit(ir_loop_jump *ir)
825{
826   (void) ir;
827   value = NULL;
828}
829