ir_constant_expression.cpp revision c1ee30a14590d73217f7dbd35e6a1839435cc5b4
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_fract:
224      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
225	 switch (ir->type->base_type) {
226	 case GLSL_TYPE_UINT:
227	    data.u[c] = 0;
228	    break;
229	 case GLSL_TYPE_INT:
230	    data.i[c] = 0;
231	    break;
232	 case GLSL_TYPE_FLOAT:
233	    data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
234	    break;
235	 default:
236	    assert(0);
237	 }
238      }
239      break;
240
241   case ir_unop_neg:
242      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
243	 switch (ir->type->base_type) {
244	 case GLSL_TYPE_UINT:
245	    data.u[c] = -op[0]->value.u[c];
246	    break;
247	 case GLSL_TYPE_INT:
248	    data.i[c] = -op[0]->value.i[c];
249	    break;
250	 case GLSL_TYPE_FLOAT:
251	    data.f[c] = -op[0]->value.f[c];
252	    break;
253	 default:
254	    assert(0);
255	 }
256      }
257      break;
258
259   case ir_unop_abs:
260      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
261	 switch (ir->type->base_type) {
262	 case GLSL_TYPE_UINT:
263	    data.u[c] = op[0]->value.u[c];
264	    break;
265	 case GLSL_TYPE_INT:
266	    data.i[c] = op[0]->value.i[c];
267	    if (data.i[c] < 0)
268	       data.i[c] = -data.i[c];
269	    break;
270	 case GLSL_TYPE_FLOAT:
271	    data.f[c] = fabs(op[0]->value.f[c]);
272	    break;
273	 default:
274	    assert(0);
275	 }
276      }
277      break;
278
279   case ir_unop_sign:
280      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
281	 switch (ir->type->base_type) {
282	 case GLSL_TYPE_UINT:
283	    data.u[c] = op[0]->value.i[c] > 0;
284	    break;
285	 case GLSL_TYPE_INT:
286	    data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
287	    break;
288	 case GLSL_TYPE_FLOAT:
289	    data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
290	    break;
291	 default:
292	    assert(0);
293	 }
294      }
295      break;
296
297   case ir_unop_rcp:
298      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
299      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
300	 switch (ir->type->base_type) {
301	 case GLSL_TYPE_UINT:
302	    if (op[0]->value.u[c] != 0.0)
303	       data.u[c] = 1 / op[0]->value.u[c];
304	    break;
305	 case GLSL_TYPE_INT:
306	    if (op[0]->value.i[c] != 0.0)
307	       data.i[c] = 1 / op[0]->value.i[c];
308	    break;
309	 case GLSL_TYPE_FLOAT:
310	    if (op[0]->value.f[c] != 0.0)
311	       data.f[c] = 1.0 / op[0]->value.f[c];
312	    break;
313	 default:
314	    assert(0);
315	 }
316      }
317      break;
318
319   case ir_unop_rsq:
320      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
321      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
322	 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
323      }
324      break;
325
326   case ir_unop_sqrt:
327      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
328      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
329	 data.f[c] = sqrtf(op[0]->value.f[c]);
330      }
331      break;
332
333   case ir_unop_exp:
334      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
335      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
336	 data.f[c] = expf(op[0]->value.f[c]);
337      }
338      break;
339
340   case ir_unop_exp2:
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] = exp2f(op[0]->value.f[c]);
344      }
345      break;
346
347   case ir_unop_log:
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] = logf(op[0]->value.f[c]);
351      }
352      break;
353
354   case ir_unop_log2:
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] = log2f(op[0]->value.f[c]);
358      }
359      break;
360
361   case ir_unop_dFdx:
362   case ir_unop_dFdy:
363      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
364      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
365	 data.f[c] = 0.0;
366      }
367      break;
368
369   case ir_binop_dot:
370      assert(op[0]->type->is_vector() && op[1]->type->is_vector());
371      data.f[0] = 0;
372      for (unsigned c = 0; c < op[0]->type->components(); c++) {
373	 switch (ir->operands[0]->type->base_type) {
374	 case GLSL_TYPE_UINT:
375	    data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
376	    break;
377	 case GLSL_TYPE_INT:
378	    data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
379	    break;
380	 case GLSL_TYPE_FLOAT:
381	    data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
382	    break;
383	 default:
384	    assert(0);
385	 }
386      }
387
388      break;
389   case ir_binop_add:
390      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
391      for (unsigned c = 0, c0 = 0, c1 = 0;
392	   c < components;
393	   c0 += c0_inc, c1 += c1_inc, c++) {
394
395	 switch (ir->operands[0]->type->base_type) {
396	 case GLSL_TYPE_UINT:
397	    data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
398	    break;
399	 case GLSL_TYPE_INT:
400	    data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
401	    break;
402	 case GLSL_TYPE_FLOAT:
403	    data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
404	    break;
405	 default:
406	    assert(0);
407	 }
408      }
409
410      break;
411   case ir_binop_sub:
412      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
413      for (unsigned c = 0, c0 = 0, c1 = 0;
414	   c < components;
415	   c0 += c0_inc, c1 += c1_inc, c++) {
416
417	 switch (ir->operands[0]->type->base_type) {
418	 case GLSL_TYPE_UINT:
419	    data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
420	    break;
421	 case GLSL_TYPE_INT:
422	    data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
423	    break;
424	 case GLSL_TYPE_FLOAT:
425	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
426	    break;
427	 default:
428	    assert(0);
429	 }
430      }
431
432      break;
433   case ir_binop_mul:
434      /* Check for equal types, or unequal types involving scalars */
435      if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
436	  || op0_scalar || op1_scalar) {
437	 for (unsigned c = 0, c0 = 0, c1 = 0;
438	      c < components;
439	      c0 += c0_inc, c1 += c1_inc, c++) {
440
441	    switch (ir->operands[0]->type->base_type) {
442	    case GLSL_TYPE_UINT:
443	       data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
444	       break;
445	    case GLSL_TYPE_INT:
446	       data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
447	       break;
448	    case GLSL_TYPE_FLOAT:
449	       data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
450	       break;
451	    default:
452	       assert(0);
453	    }
454	 }
455      } else {
456	 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
457
458	 /* Multiply an N-by-M matrix with an M-by-P matrix.  Since either
459	  * matrix can be a GLSL vector, either N or P can be 1.
460	  *
461	  * For vec*mat, the vector is treated as a row vector.  This
462	  * means the vector is a 1-row x M-column matrix.
463	  *
464	  * For mat*vec, the vector is treated as a column vector.  Since
465	  * matrix_columns is 1 for vectors, this just works.
466	  */
467	 const unsigned n = op[0]->type->is_vector()
468	    ? 1 : op[0]->type->vector_elements;
469	 const unsigned m = op[1]->type->vector_elements;
470	 const unsigned p = op[1]->type->matrix_columns;
471	 for (unsigned j = 0; j < p; j++) {
472	    for (unsigned i = 0; i < n; i++) {
473	       for (unsigned k = 0; k < m; k++) {
474		  data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
475	       }
476	    }
477	 }
478      }
479
480      break;
481   case ir_binop_div:
482      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
483      for (unsigned c = 0, c0 = 0, c1 = 0;
484	   c < components;
485	   c0 += c0_inc, c1 += c1_inc, c++) {
486
487	 switch (ir->operands[0]->type->base_type) {
488	 case GLSL_TYPE_UINT:
489	    data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
490	    break;
491	 case GLSL_TYPE_INT:
492	    data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
493	    break;
494	 case GLSL_TYPE_FLOAT:
495	    data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
496	    break;
497	 default:
498	    assert(0);
499	 }
500      }
501
502      break;
503   case ir_binop_logic_and:
504      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
505      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
506	 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
507      break;
508   case ir_binop_logic_xor:
509      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
510      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
511	 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
512      break;
513   case ir_binop_logic_or:
514      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
515      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
516	 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
517      break;
518
519   case ir_binop_less:
520      switch (ir->operands[0]->type->base_type) {
521      case GLSL_TYPE_UINT:
522	 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
523	 break;
524      case GLSL_TYPE_INT:
525	 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
526	 break;
527      case GLSL_TYPE_FLOAT:
528	 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
529	 break;
530      default:
531	 assert(0);
532      }
533      break;
534   case ir_binop_greater:
535      switch (ir->operands[0]->type->base_type) {
536      case GLSL_TYPE_UINT:
537	 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
538	 break;
539      case GLSL_TYPE_INT:
540	 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
541	 break;
542      case GLSL_TYPE_FLOAT:
543	 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
544	 break;
545      default:
546	 assert(0);
547      }
548      break;
549   case ir_binop_lequal:
550      switch (ir->operands[0]->type->base_type) {
551      case GLSL_TYPE_UINT:
552	 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
553	 break;
554      case GLSL_TYPE_INT:
555	 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
556	 break;
557      case GLSL_TYPE_FLOAT:
558	 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
559	 break;
560      default:
561	 assert(0);
562      }
563      break;
564   case ir_binop_gequal:
565      switch (ir->operands[0]->type->base_type) {
566      case GLSL_TYPE_UINT:
567	 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
568	 break;
569      case GLSL_TYPE_INT:
570	 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
571	 break;
572      case GLSL_TYPE_FLOAT:
573	 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
574	 break;
575      default:
576	 assert(0);
577      }
578      break;
579
580   case ir_binop_equal:
581      data.b[0] = true;
582      for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
583	 switch (ir->operands[0]->type->base_type) {
584	 case GLSL_TYPE_UINT:
585	    data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
586	    break;
587	 case GLSL_TYPE_INT:
588	    data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
589	    break;
590	 case GLSL_TYPE_FLOAT:
591	    data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
592	    break;
593	 case GLSL_TYPE_BOOL:
594	    data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
595	    break;
596	 default:
597	    assert(0);
598	 }
599      }
600      break;
601   case ir_binop_nequal:
602      data.b[0] = false;
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
623   default:
624      /* FINISHME: Should handle all expression types. */
625      return;
626   }
627
628   void *ctx = talloc_parent(ir);
629   this->value = new(ctx) ir_constant(ir->type, &data);
630}
631
632
633void
634ir_constant_visitor::visit(ir_texture *ir)
635{
636   // FINISHME: Do stuff with texture lookups
637   (void) ir;
638   value = NULL;
639}
640
641
642void
643ir_constant_visitor::visit(ir_swizzle *ir)
644{
645   ir_constant *v = ir->val->constant_expression_value();
646
647   this->value = NULL;
648
649   if (v != NULL) {
650      ir_constant_data data;
651
652      const unsigned swiz_idx[4] = {
653	 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
654      };
655
656      for (unsigned i = 0; i < ir->mask.num_components; i++) {
657	 switch (v->type->base_type) {
658	 case GLSL_TYPE_UINT:
659	 case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
660	 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
661	 case GLSL_TYPE_BOOL:  data.b[i] = v->value.b[swiz_idx[i]]; break;
662	 default:              assert(!"Should not get here."); break;
663	 }
664      }
665
666      void *ctx = talloc_parent(ir);
667      this->value = new(ctx) ir_constant(ir->type, &data);
668   }
669}
670
671
672void
673ir_constant_visitor::visit(ir_dereference_variable *ir)
674{
675   value = NULL;
676
677   ir_variable *var = ir->variable_referenced();
678   if (var && var->constant_value)
679      value = var->constant_value->clone(NULL);
680}
681
682
683void
684ir_constant_visitor::visit(ir_dereference_array *ir)
685{
686   void *ctx = talloc_parent(ir);
687   ir_constant *array = ir->array->constant_expression_value();
688   ir_constant *idx = ir->array_index->constant_expression_value();
689
690   this->value = NULL;
691
692   if ((array != NULL) && (idx != NULL)) {
693      if (array->type->is_matrix()) {
694	 /* Array access of a matrix results in a vector.
695	  */
696	 const unsigned column = idx->value.u[0];
697
698	 const glsl_type *const column_type = array->type->column_type();
699
700	 /* Offset in the constant matrix to the first element of the column
701	  * to be extracted.
702	  */
703	 const unsigned mat_idx = column * column_type->vector_elements;
704
705	 ir_constant_data data;
706
707	 switch (column_type->base_type) {
708	 case GLSL_TYPE_UINT:
709	 case GLSL_TYPE_INT:
710	    for (unsigned i = 0; i < column_type->vector_elements; i++)
711	       data.u[i] = array->value.u[mat_idx + i];
712
713	    break;
714
715	 case GLSL_TYPE_FLOAT:
716	    for (unsigned i = 0; i < column_type->vector_elements; i++)
717	       data.f[i] = array->value.f[mat_idx + i];
718
719	    break;
720
721	 default:
722	    assert(!"Should not get here.");
723	    break;
724	 }
725
726	 this->value = new(ctx) ir_constant(column_type, &data);
727      } else if (array->type->is_vector()) {
728	 const unsigned component = idx->value.u[0];
729
730	 this->value = new(ctx) ir_constant(array, component);
731      } else {
732	 /* FINISHME: Handle access of constant arrays. */
733      }
734   }
735}
736
737
738void
739ir_constant_visitor::visit(ir_dereference_record *ir)
740{
741   ir_constant *v = ir->record->constant_expression_value();
742
743   this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
744}
745
746
747void
748ir_constant_visitor::visit(ir_assignment *ir)
749{
750   (void) ir;
751   value = NULL;
752}
753
754
755void
756ir_constant_visitor::visit(ir_constant *ir)
757{
758   value = ir;
759}
760
761
762void
763ir_constant_visitor::visit(ir_call *ir)
764{
765   (void) ir;
766   value = NULL;
767}
768
769
770void
771ir_constant_visitor::visit(ir_return *ir)
772{
773   (void) ir;
774   value = NULL;
775}
776
777
778void
779ir_constant_visitor::visit(ir_discard *ir)
780{
781   (void) ir;
782   value = NULL;
783}
784
785
786void
787ir_constant_visitor::visit(ir_if *ir)
788{
789   (void) ir;
790   value = NULL;
791}
792
793
794void
795ir_constant_visitor::visit(ir_loop *ir)
796{
797   (void) ir;
798   value = NULL;
799}
800
801
802void
803ir_constant_visitor::visit(ir_loop_jump *ir)
804{
805   (void) ir;
806   value = NULL;
807}
808