• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# Copyright (C) 2015 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 DEALINGS
21# IN THE SOFTWARE.
22
23import mako.template
24import sys
25
26class type(object):
27   def __init__(self, c_type, union_field, glsl_type):
28      self.c_type = c_type
29      self.union_field = union_field
30      self.glsl_type = glsl_type
31
32
33class type_signature_iter(object):
34   """Basic iterator for a set of type signatures.  Various kinds of sequences of
35   types come in, and an iteration of type_signature objects come out.
36
37   """
38
39   def __init__(self, source_types, num_operands):
40      """Initialize an iterator from a sequence of input types and a number
41      operands.  This is for signatures where all the operands have the same
42      type and the result type of the operation is the same as the input type.
43
44      """
45      self.dest_type = None
46      self.source_types = source_types
47      self.num_operands = num_operands
48      self.i = 0
49
50   def __init__(self, dest_type, source_types, num_operands):
51      """Initialize an iterator from a result tpye, a sequence of input types and a
52      number operands.  This is for signatures where all the operands have the
53      same type but the result type of the operation is different from the
54      input type.
55
56      """
57      self.dest_type = dest_type
58      self.source_types = source_types
59      self.num_operands = num_operands
60      self.i = 0
61
62   def __iter__(self):
63      return self
64
65   def next(self):
66      if self.i < len(self.source_types):
67         i = self.i
68         self.i += 1
69
70         if self.dest_type is None:
71            dest_type = self.source_types[i]
72         else:
73            dest_type = self.dest_type
74
75         return (dest_type, self.num_operands * (self.source_types[i],))
76      else:
77         raise StopIteration()
78
79
80uint_type = type("unsigned", "u", "GLSL_TYPE_UINT")
81int_type = type("int", "i", "GLSL_TYPE_INT")
82uint64_type = type("uint64_t", "u64", "GLSL_TYPE_UINT64")
83int64_type = type("int64_t", "i64", "GLSL_TYPE_INT64")
84float_type = type("float", "f", "GLSL_TYPE_FLOAT")
85double_type = type("double", "d", "GLSL_TYPE_DOUBLE")
86bool_type = type("bool", "b", "GLSL_TYPE_BOOL")
87
88all_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type, bool_type)
89numeric_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type)
90signed_numeric_types = (int_type, float_type, double_type, int64_type)
91integer_types = (uint_type, int_type, uint64_type, int64_type)
92real_types = (float_type, double_type)
93
94# This template is for operations that can have operands of a several
95# different types, and each type may or may not has a different C expression.
96# This is used by most operations.
97constant_template_common = mako.template.Template("""\
98   case ${op.get_enum_name()}:
99      for (unsigned c = 0; c < op[0]->type->components(); c++) {
100         switch (op[0]->type->base_type) {
101    % for dst_type, src_types in op.signatures():
102         case ${src_types[0].glsl_type}:
103            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)};
104            break;
105    % endfor
106         default:
107            unreachable("invalid type");
108         }
109      }
110      break;""")
111
112# This template is for binary operations that can operate on some combination
113# of scalar and vector operands.
114constant_template_vector_scalar = mako.template.Template("""\
115   case ${op.get_enum_name()}:
116    % if "mixed" in op.flags:
117        % for i in xrange(op.num_operands):
118      assert(op[${i}]->type->base_type == ${op.source_types[0].glsl_type} ||
119            % for src_type in op.source_types[1:-1]:
120             op[${i}]->type->base_type == ${src_type.glsl_type} ||
121            % endfor
122             op[${i}]->type->base_type == ${op.source_types[-1].glsl_type});
123        % endfor
124    % else:
125      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
126    % endif
127      for (unsigned c = 0, c0 = 0, c1 = 0;
128           c < components;
129           c0 += c0_inc, c1 += c1_inc, c++) {
130
131         switch (op[0]->type->base_type) {
132    % for dst_type, src_types in op.signatures():
133         case ${src_types[0].glsl_type}:
134            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c0", "c1", "c2"))};
135            break;
136    % endfor
137         default:
138            unreachable("invalid type");
139         }
140      }
141      break;""")
142
143# This template is for multiplication.  It is unique because it has to support
144# matrix * vector and matrix * matrix operations, and those are just different.
145constant_template_mul = mako.template.Template("""\
146   case ${op.get_enum_name()}:
147      /* Check for equal types, or unequal types involving scalars */
148      if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
149          || op0_scalar || op1_scalar) {
150         for (unsigned c = 0, c0 = 0, c1 = 0;
151              c < components;
152              c0 += c0_inc, c1 += c1_inc, c++) {
153
154            switch (op[0]->type->base_type) {
155    % for dst_type, src_types in op.signatures():
156            case ${src_types[0].glsl_type}:
157               data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c0", "c1", "c2"))};
158               break;
159    % endfor
160            default:
161               unreachable("invalid type");
162            }
163         }
164      } else {
165         assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
166
167         /* Multiply an N-by-M matrix with an M-by-P matrix.  Since either
168          * matrix can be a GLSL vector, either N or P can be 1.
169          *
170          * For vec*mat, the vector is treated as a row vector.  This
171          * means the vector is a 1-row x M-column matrix.
172          *
173          * For mat*vec, the vector is treated as a column vector.  Since
174          * matrix_columns is 1 for vectors, this just works.
175          */
176         const unsigned n = op[0]->type->is_vector()
177            ? 1 : op[0]->type->vector_elements;
178         const unsigned m = op[1]->type->vector_elements;
179         const unsigned p = op[1]->type->matrix_columns;
180         for (unsigned j = 0; j < p; j++) {
181            for (unsigned i = 0; i < n; i++) {
182               for (unsigned k = 0; k < m; k++) {
183                  if (op[0]->type->is_double())
184                     data.d[i+n*j] += op[0]->value.d[i+n*k]*op[1]->value.d[k+m*j];
185                  else
186                     data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
187               }
188            }
189         }
190      }
191      break;""")
192
193# This template is for operations that are horizontal and either have only a
194# single type or the implementation for all types is identical.  That is, the
195# operation consumes a vector and produces a scalar.
196constant_template_horizontal_single_implementation = mako.template.Template("""\
197   case ${op.get_enum_name()}:
198      data.${op.dest_type.union_field}[0] = ${op.c_expression['default']};
199      break;""")
200
201# This template is for operations that are horizontal and do not assign the
202# result.  The various unpack operations are examples.
203constant_template_horizontal_nonassignment = mako.template.Template("""\
204   case ${op.get_enum_name()}:
205      ${op.c_expression['default']};
206      break;""")
207
208# This template is for binary operations that are horizontal.  That is, the
209# operation consumes a vector and produces a scalar.
210constant_template_horizontal = mako.template.Template("""\
211   case ${op.get_enum_name()}:
212      switch (op[0]->type->base_type) {
213    % for dst_type, src_types in op.signatures():
214      case ${src_types[0].glsl_type}:
215         data.${dst_type.union_field}[0] = ${op.get_c_expression(src_types)};
216         break;
217    % endfor
218      default:
219         unreachable("invalid type");
220      }
221      break;""")
222
223# This template is for ir_binop_vector_extract.
224constant_template_vector_extract = mako.template.Template("""\
225   case ${op.get_enum_name()}: {
226      const int c = CLAMP(op[1]->value.i[0], 0,
227                          (int) op[0]->type->vector_elements - 1);
228
229      switch (op[0]->type->base_type) {
230    % for dst_type, src_types in op.signatures():
231      case ${src_types[0].glsl_type}:
232         data.${dst_type.union_field}[0] = op[0]->value.${src_types[0].union_field}[c];
233         break;
234    % endfor
235      default:
236         unreachable("invalid type");
237      }
238      break;
239   }""")
240
241# This template is for ir_triop_vector_insert.
242constant_template_vector_insert = mako.template.Template("""\
243   case ${op.get_enum_name()}: {
244      const unsigned idx = op[2]->value.u[0];
245
246      memcpy(&data, &op[0]->value, sizeof(data));
247
248      switch (this->type->base_type) {
249    % for dst_type, src_types in op.signatures():
250      case ${src_types[0].glsl_type}:
251         data.${dst_type.union_field}[idx] = op[1]->value.${src_types[0].union_field}[0];
252         break;
253    % endfor
254      default:
255         unreachable("invalid type");
256      }
257      break;
258   }""")
259
260# This template is for ir_quadop_vector.
261constant_template_vector = mako.template.Template("""\
262   case ${op.get_enum_name()}:
263      for (unsigned c = 0; c < this->type->vector_elements; c++) {
264         switch (this->type->base_type) {
265    % for dst_type, src_types in op.signatures():
266         case ${src_types[0].glsl_type}:
267            data.${dst_type.union_field}[c] = op[c]->value.${src_types[0].union_field}[0];
268            break;
269    % endfor
270         default:
271            unreachable("invalid type");
272         }
273      }
274      break;""")
275
276# This template is for ir_triop_lrp.
277constant_template_lrp = mako.template.Template("""\
278   case ${op.get_enum_name()}: {
279      assert(op[0]->type->is_float() || op[0]->type->is_double());
280      assert(op[1]->type->is_float() || op[1]->type->is_double());
281      assert(op[2]->type->is_float() || op[2]->type->is_double());
282
283      unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
284      for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
285         switch (this->type->base_type) {
286    % for dst_type, src_types in op.signatures():
287         case ${src_types[0].glsl_type}:
288            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c", "c", "c2"))};
289            break;
290    % endfor
291         default:
292            unreachable("invalid type");
293         }
294      }
295      break;
296   }""")
297
298# This template is for ir_triop_csel.  This expression is really unique
299# because not all of the operands are the same type, and the second operand
300# determines the type of the expression (instead of the first).
301constant_template_csel = mako.template.Template("""\
302   case ${op.get_enum_name()}:
303      for (unsigned c = 0; c < components; c++) {
304         switch (this->type->base_type) {
305    % for dst_type, src_types in op.signatures():
306         case ${src_types[1].glsl_type}:
307            data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)};
308            break;
309    % endfor
310         default:
311            unreachable("invalid type");
312         }
313      }
314      break;""")
315
316
317vector_scalar_operation = "vector-scalar"
318horizontal_operation = "horizontal"
319types_identical_operation = "identical"
320non_assign_operation = "nonassign"
321mixed_type_operation = "mixed"
322
323class operation(object):
324   def __init__(self, name, num_operands, printable_name = None, source_types = None, dest_type = None, c_expression = None, flags = None, all_signatures = None):
325      self.name = name
326      self.num_operands = num_operands
327
328      if printable_name is None:
329         self.printable_name = name
330      else:
331         self.printable_name = printable_name
332
333      self.all_signatures = all_signatures
334
335      if source_types is None:
336         self.source_types = tuple()
337      else:
338         self.source_types = source_types
339
340      self.dest_type = dest_type
341
342      if c_expression is None:
343         self.c_expression = None
344      elif isinstance(c_expression, str):
345         self.c_expression = {'default': c_expression}
346      else:
347         self.c_expression = c_expression
348
349      if flags is None:
350         self.flags = frozenset()
351      elif isinstance(flags, str):
352         self.flags = frozenset([flags])
353      else:
354         self.flags = frozenset(flags)
355
356
357   def get_enum_name(self):
358      return "ir_{0}op_{1}".format(("un", "bin", "tri", "quad")[self.num_operands-1], self.name)
359
360
361   def get_template(self):
362      if self.c_expression is None:
363         return None
364
365      if horizontal_operation in self.flags:
366         if non_assign_operation in self.flags:
367            return constant_template_horizontal_nonassignment.render(op=self)
368         elif types_identical_operation in self.flags:
369            return constant_template_horizontal_single_implementation.render(op=self)
370         else:
371            return constant_template_horizontal.render(op=self)
372
373      if self.num_operands == 2:
374         if self.name == "mul":
375            return constant_template_mul.render(op=self)
376         elif self.name == "vector_extract":
377            return constant_template_vector_extract.render(op=self)
378         elif vector_scalar_operation in self.flags:
379            return constant_template_vector_scalar.render(op=self)
380      elif self.num_operands == 3:
381         if self.name == "vector_insert":
382            return constant_template_vector_insert.render(op=self)
383         elif self.name == "lrp":
384            return constant_template_lrp.render(op=self)
385         elif self.name == "csel":
386            return constant_template_csel.render(op=self)
387      elif self.num_operands == 4:
388         if self.name == "vector":
389            return constant_template_vector.render(op=self)
390
391      return constant_template_common.render(op=self)
392
393
394   def get_c_expression(self, types, indices=("c", "c", "c")):
395      src0 = "op[0]->value.{0}[{1}]".format(types[0].union_field, indices[0])
396      src1 = "op[1]->value.{0}[{1}]".format(types[1].union_field, indices[1]) if len(types) >= 2 else "ERROR"
397      src2 = "op[2]->value.{0}[{1}]".format(types[2].union_field, indices[2]) if len(types) >= 3 else "ERROR"
398      src3 = "op[3]->value.{0}[c]".format(types[3].union_field) if len(types) >= 4 else "ERROR"
399
400      expr = self.c_expression[types[0].union_field] if types[0].union_field in self.c_expression else self.c_expression['default']
401
402      return expr.format(src0=src0,
403                         src1=src1,
404                         src2=src2,
405                         src3=src3)
406
407
408   def signatures(self):
409      if self.all_signatures is not None:
410         return self.all_signatures
411      else:
412         return type_signature_iter(self.dest_type, self.source_types, self.num_operands)
413
414
415ir_expression_operation = [
416   operation("bit_not", 1, printable_name="~", source_types=integer_types, c_expression="~ {src0}"),
417   operation("logic_not", 1, printable_name="!", source_types=(bool_type,), c_expression="!{src0}"),
418   operation("neg", 1, source_types=numeric_types, c_expression={'u': "-((int) {src0})", 'default': "-{src0}"}),
419   operation("abs", 1, source_types=signed_numeric_types, c_expression={'i': "{src0} < 0 ? -{src0} : {src0}", 'f': "fabsf({src0})", 'd': "fabs({src0})", 'i64': "{src0} < 0 ? -{src0} : {src0}"}),
420   operation("sign", 1, source_types=signed_numeric_types, c_expression={'i': "({src0} > 0) - ({src0} < 0)", 'f': "float(({src0} > 0.0F) - ({src0} < 0.0F))", 'd': "double(({src0} > 0.0) - ({src0} < 0.0))", 'i64': "({src0} > 0) - ({src0} < 0)"}),
421   operation("rcp", 1, source_types=real_types, c_expression={'f': "1.0F / {src0}", 'd': "1.0 / {src0}"}),
422   operation("rsq", 1, source_types=real_types, c_expression={'f': "1.0F / sqrtf({src0})", 'd': "1.0 / sqrt({src0})"}),
423   operation("sqrt", 1, source_types=real_types, c_expression={'f': "sqrtf({src0})", 'd': "sqrt({src0})"}),
424   operation("exp", 1, source_types=(float_type,), c_expression="expf({src0})"),         # Log base e on gentype
425   operation("log", 1, source_types=(float_type,), c_expression="logf({src0})"),         # Natural log on gentype
426   operation("exp2", 1, source_types=(float_type,), c_expression="exp2f({src0})"),
427   operation("log2", 1, source_types=(float_type,), c_expression="log2f({src0})"),
428
429   # Float-to-integer conversion.
430   operation("f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="(int) {src0}"),
431   # Float-to-unsigned conversion.
432   operation("f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="(unsigned) {src0}"),
433   # Integer-to-float conversion.
434   operation("i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="(float) {src0}"),
435   # Float-to-boolean conversion
436   operation("f2b", 1, source_types=(float_type,), dest_type=bool_type, c_expression="{src0} != 0.0F ? true : false"),
437   # Boolean-to-float conversion
438   operation("b2f", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"),
439   # int-to-boolean conversion
440   operation("i2b", 1, source_types=(uint_type, int_type), dest_type=bool_type, c_expression="{src0} ? true : false"),
441   # Boolean-to-int conversion
442   operation("b2i", 1, source_types=(bool_type,), dest_type=int_type, c_expression="{src0} ? 1 : 0"),
443   # Unsigned-to-float conversion.
444   operation("u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="(float) {src0}"),
445   # Integer-to-unsigned conversion.
446   operation("i2u", 1, source_types=(int_type,), dest_type=uint_type, c_expression="{src0}"),
447   # Unsigned-to-integer conversion.
448   operation("u2i", 1, source_types=(uint_type,), dest_type=int_type, c_expression="{src0}"),
449   # Double-to-float conversion.
450   operation("d2f", 1, source_types=(double_type,), dest_type=float_type, c_expression="{src0}"),
451   # Float-to-double conversion.
452   operation("f2d", 1, source_types=(float_type,), dest_type=double_type, c_expression="{src0}"),
453   # Double-to-integer conversion.
454   operation("d2i", 1, source_types=(double_type,), dest_type=int_type, c_expression="{src0}"),
455   # Integer-to-double conversion.
456   operation("i2d", 1, source_types=(int_type,), dest_type=double_type, c_expression="{src0}"),
457   # Double-to-unsigned conversion.
458   operation("d2u", 1, source_types=(double_type,), dest_type=uint_type, c_expression="{src0}"),
459   # Unsigned-to-double conversion.
460   operation("u2d", 1, source_types=(uint_type,), dest_type=double_type, c_expression="{src0}"),
461   # Double-to-boolean conversion.
462   operation("d2b", 1, source_types=(double_type,), dest_type=bool_type, c_expression="{src0} != 0.0"),
463   # 'Bit-identical int-to-float "conversion"
464   operation("bitcast_i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
465   # 'Bit-identical float-to-int "conversion"
466   operation("bitcast_f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="bitcast_f2u({src0})"),
467   # 'Bit-identical uint-to-float "conversion"
468   operation("bitcast_u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
469   # 'Bit-identical float-to-uint "conversion"
470   operation("bitcast_f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="bitcast_f2u({src0})"),
471   # Bit-identical u64-to-double "conversion"
472   operation("bitcast_u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="bitcast_u642d({src0})"),
473   # Bit-identical i64-to-double "conversion"
474   operation("bitcast_i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="bitcast_i642d({src0})"),
475   # Bit-identical double-to_u64 "conversion"
476   operation("bitcast_d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="bitcast_d2u64({src0})"),
477   # Bit-identical double-to-i64 "conversion"
478   operation("bitcast_d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="bitcast_d2i64({src0})"),
479   # i64-to-i32 conversion
480   operation("i642i", 1, source_types=(int64_type,), dest_type=int_type, c_expression="{src0}"),
481   # ui64-to-i32 conversion
482   operation("u642i", 1, source_types=(uint64_type,), dest_type=int_type, c_expression="{src0}"),
483   operation("i642u", 1, source_types=(int64_type,), dest_type=uint_type, c_expression="{src0}"),
484   operation("u642u", 1, source_types=(uint64_type,), dest_type=uint_type, c_expression="{src0}"),
485   operation("i642b", 1, source_types=(int64_type,), dest_type=bool_type, c_expression="{src0} != 0"),
486   operation("i642f", 1, source_types=(int64_type,), dest_type=float_type, c_expression="{src0}"),
487   operation("u642f", 1, source_types=(uint64_type,), dest_type=float_type, c_expression="{src0}"),
488   operation("i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="{src0}"),
489   operation("u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="{src0}"),
490   operation("i2i64", 1, source_types=(int_type,), dest_type=int64_type, c_expression="{src0}"),
491   operation("u2i64", 1, source_types=(uint_type,), dest_type=int64_type, c_expression="{src0}"),
492   operation("b2i64", 1, source_types=(bool_type,), dest_type=int64_type, c_expression="{src0}"),
493   operation("f2i64", 1, source_types=(float_type,), dest_type=int64_type, c_expression="{src0}"),
494   operation("d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="{src0}"),
495   operation("i2u64", 1, source_types=(int_type,), dest_type=uint64_type, c_expression="{src0}"),
496   operation("u2u64", 1, source_types=(uint_type,), dest_type=uint64_type, c_expression="{src0}"),
497   operation("f2u64", 1, source_types=(float_type,), dest_type=uint64_type, c_expression="{src0}"),
498   operation("d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="{src0}"),
499   operation("u642i64", 1, source_types=(uint64_type,), dest_type=int64_type, c_expression="{src0}"),
500   operation("i642u64", 1, source_types=(int64_type,), dest_type=uint64_type, c_expression="{src0}"),
501
502
503   # Unary floating-point rounding operations.
504   operation("trunc", 1, source_types=real_types, c_expression={'f': "truncf({src0})", 'd': "trunc({src0})"}),
505   operation("ceil", 1, source_types=real_types, c_expression={'f': "ceilf({src0})", 'd': "ceil({src0})"}),
506   operation("floor", 1, source_types=real_types, c_expression={'f': "floorf({src0})", 'd': "floor({src0})"}),
507   operation("fract", 1, source_types=real_types, c_expression={'f': "{src0} - floorf({src0})", 'd': "{src0} - floor({src0})"}),
508   operation("round_even", 1, source_types=real_types, c_expression={'f': "_mesa_roundevenf({src0})", 'd': "_mesa_roundeven({src0})"}),
509
510   # Trigonometric operations.
511   operation("sin", 1, source_types=(float_type,), c_expression="sinf({src0})"),
512   operation("cos", 1, source_types=(float_type,), c_expression="cosf({src0})"),
513
514   # Partial derivatives.
515   operation("dFdx", 1, source_types=(float_type,), c_expression="0.0f"),
516   operation("dFdx_coarse", 1, printable_name="dFdxCoarse", source_types=(float_type,), c_expression="0.0f"),
517   operation("dFdx_fine", 1, printable_name="dFdxFine", source_types=(float_type,), c_expression="0.0f"),
518   operation("dFdy", 1, source_types=(float_type,), c_expression="0.0f"),
519   operation("dFdy_coarse", 1, printable_name="dFdyCoarse", source_types=(float_type,), c_expression="0.0f"),
520   operation("dFdy_fine", 1, printable_name="dFdyFine", source_types=(float_type,), c_expression="0.0f"),
521
522   # Floating point pack and unpack operations.
523   operation("pack_snorm_2x16", 1, printable_name="packSnorm2x16", source_types=(float_type,), dest_type=uint_type, c_expression="pack_2x16(pack_snorm_1x16, op[0]->value.f[0], op[0]->value.f[1])", flags=horizontal_operation),
524   operation("pack_snorm_4x8", 1, printable_name="packSnorm4x8", source_types=(float_type,), dest_type=uint_type, c_expression="pack_4x8(pack_snorm_1x8, op[0]->value.f[0], op[0]->value.f[1], op[0]->value.f[2], op[0]->value.f[3])", flags=horizontal_operation),
525   operation("pack_unorm_2x16", 1, printable_name="packUnorm2x16", source_types=(float_type,), dest_type=uint_type, c_expression="pack_2x16(pack_unorm_1x16, op[0]->value.f[0], op[0]->value.f[1])", flags=horizontal_operation),
526   operation("pack_unorm_4x8", 1, printable_name="packUnorm4x8", source_types=(float_type,), dest_type=uint_type, c_expression="pack_4x8(pack_unorm_1x8, op[0]->value.f[0], op[0]->value.f[1], op[0]->value.f[2], op[0]->value.f[3])", flags=horizontal_operation),
527   operation("pack_half_2x16", 1, printable_name="packHalf2x16", source_types=(float_type,), dest_type=uint_type, c_expression="pack_2x16(pack_half_1x16, op[0]->value.f[0], op[0]->value.f[1])", flags=horizontal_operation),
528   operation("unpack_snorm_2x16", 1, printable_name="unpackSnorm2x16", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_2x16(unpack_snorm_1x16, op[0]->value.u[0], &data.f[0], &data.f[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
529   operation("unpack_snorm_4x8", 1, printable_name="unpackSnorm4x8", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_4x8(unpack_snorm_1x8, op[0]->value.u[0], &data.f[0], &data.f[1], &data.f[2], &data.f[3])", flags=frozenset((horizontal_operation, non_assign_operation))),
530   operation("unpack_unorm_2x16", 1, printable_name="unpackUnorm2x16", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_2x16(unpack_unorm_1x16, op[0]->value.u[0], &data.f[0], &data.f[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
531   operation("unpack_unorm_4x8", 1, printable_name="unpackUnorm4x8", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_4x8(unpack_unorm_1x8, op[0]->value.u[0], &data.f[0], &data.f[1], &data.f[2], &data.f[3])", flags=frozenset((horizontal_operation, non_assign_operation))),
532   operation("unpack_half_2x16", 1, printable_name="unpackHalf2x16", source_types=(uint_type,), dest_type=float_type, c_expression="unpack_2x16(unpack_half_1x16, op[0]->value.u[0], &data.f[0], &data.f[1])", flags=frozenset((horizontal_operation, non_assign_operation))),
533
534   # Bit operations, part of ARB_gpu_shader5.
535   operation("bitfield_reverse", 1, source_types=(uint_type, int_type), c_expression="bitfield_reverse({src0})"),
536   operation("bit_count", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="_mesa_bitcount({src0})"),
537   operation("find_msb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression={'u': "find_msb_uint({src0})", 'i': "find_msb_int({src0})"}),
538   operation("find_lsb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="find_msb_uint({src0} & -{src0})"),
539
540   operation("saturate", 1, printable_name="sat", source_types=(float_type,), c_expression="CLAMP({src0}, 0.0f, 1.0f)"),
541
542   # Double packing, part of ARB_gpu_shader_fp64.
543   operation("pack_double_2x32", 1, printable_name="packDouble2x32", source_types=(uint_type,), dest_type=double_type, c_expression="memcpy(&data.d[0], &op[0]->value.u[0], sizeof(double))", flags=frozenset((horizontal_operation, non_assign_operation))),
544   operation("unpack_double_2x32", 1, printable_name="unpackDouble2x32", source_types=(double_type,), dest_type=uint_type, c_expression="memcpy(&data.u[0], &op[0]->value.d[0], sizeof(double))", flags=frozenset((horizontal_operation, non_assign_operation))),
545
546   # Sampler/Image packing, part of ARB_bindless_texture.
547   operation("pack_sampler_2x32", 1, printable_name="packSampler2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="memcpy(&data.u64[0], &op[0]->value.u[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
548   operation("pack_image_2x32", 1, printable_name="packImage2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="memcpy(&data.u64[0], &op[0]->value.u[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
549   operation("unpack_sampler_2x32", 1, printable_name="unpackSampler2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="memcpy(&data.u[0], &op[0]->value.u64[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
550   operation("unpack_image_2x32", 1, printable_name="unpackImage2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="memcpy(&data.u[0], &op[0]->value.u64[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
551
552   operation("frexp_sig", 1),
553   operation("frexp_exp", 1),
554
555   operation("noise", 1),
556
557   operation("subroutine_to_int", 1),
558
559   # Interpolate fs input at centroid
560   #
561   # operand0 is the fs input.
562   operation("interpolate_at_centroid", 1),
563
564   # Ask the driver for the total size of a buffer block.
565   # operand0 is the ir_constant buffer block index in the linked shader.
566   operation("get_buffer_size", 1),
567
568   # Calculate length of an unsized array inside a buffer block.
569   # This opcode is going to be replaced in a lowering pass inside
570   # the linker.
571   #
572   # operand0 is the unsized array's ir_value for the calculation
573   # of its length.
574   operation("ssbo_unsized_array_length", 1),
575
576   # 64-bit integer packing ops.
577   operation("pack_int_2x32", 1, printable_name="packInt2x32", source_types=(int_type,), dest_type=int64_type, c_expression="memcpy(&data.i64[0], &op[0]->value.i[0], sizeof(int64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
578   operation("pack_uint_2x32", 1, printable_name="packUint2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="memcpy(&data.u64[0], &op[0]->value.u[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
579   operation("unpack_int_2x32", 1, printable_name="unpackInt2x32", source_types=(int64_type,), dest_type=int_type, c_expression="memcpy(&data.i[0], &op[0]->value.i64[0], sizeof(int64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
580   operation("unpack_uint_2x32", 1, printable_name="unpackUint2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="memcpy(&data.u[0], &op[0]->value.u64[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))),
581
582   operation("add", 2, printable_name="+", source_types=numeric_types, c_expression="{src0} + {src1}", flags=vector_scalar_operation),
583   operation("sub", 2, printable_name="-", source_types=numeric_types, c_expression="{src0} - {src1}", flags=vector_scalar_operation),
584   # "Floating-point or low 32-bit integer multiply."
585   operation("mul", 2, printable_name="*", source_types=numeric_types, c_expression="{src0} * {src1}"),
586   operation("imul_high", 2),       # Calculates the high 32-bits of a 64-bit multiply.
587   operation("div", 2, printable_name="/", source_types=numeric_types, c_expression={'u': "{src1} == 0 ? 0 : {src0} / {src1}", 'i': "{src1} == 0 ? 0 : {src0} / {src1}", 'u64': "{src1} == 0 ? 0 : {src0} / {src1}", 'i64': "{src1} == 0 ? 0 : {src0} / {src1}", 'default': "{src0} / {src1}"}, flags=vector_scalar_operation),
588
589   # Returns the carry resulting from the addition of the two arguments.
590   operation("carry", 2),
591
592   # Returns the borrow resulting from the subtraction of the second argument
593   # from the first argument.
594   operation("borrow", 2),
595
596   # Either (vector % vector) or (vector % scalar)
597   #
598   # We don't use fmod because it rounds toward zero; GLSL specifies the use
599   # of floor.
600   operation("mod", 2, printable_name="%", source_types=numeric_types, c_expression={'u': "{src1} == 0 ? 0 : {src0} % {src1}", 'i': "{src1} == 0 ? 0 : {src0} % {src1}", 'f': "{src0} - {src1} * floorf({src0} / {src1})", 'd': "{src0} - {src1} * floor({src0} / {src1})", 'u64': "{src1} == 0 ? 0 : {src0} % {src1}", 'i64': "{src1} == 0 ? 0 : {src0} % {src1}"}, flags=vector_scalar_operation),
601
602   # Binary comparison operators which return a boolean vector.
603   # The type of both operands must be equal.
604   operation("less", 2, printable_name="<", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} < {src1}"),
605   operation("gequal", 2, printable_name=">=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} >= {src1}"),
606   operation("equal", 2, printable_name="==", source_types=all_types, dest_type=bool_type, c_expression="{src0} == {src1}"),
607   operation("nequal", 2, printable_name="!=", source_types=all_types, dest_type=bool_type, c_expression="{src0} != {src1}"),
608
609   # Returns single boolean for whether all components of operands[0]
610   # equal the components of operands[1].
611   operation("all_equal", 2, source_types=all_types, dest_type=bool_type, c_expression="op[0]->has_value(op[1])", flags=frozenset((horizontal_operation, types_identical_operation))),
612
613   # Returns single boolean for whether any component of operands[0]
614   # is not equal to the corresponding component of operands[1].
615   operation("any_nequal", 2, source_types=all_types, dest_type=bool_type, c_expression="!op[0]->has_value(op[1])", flags=frozenset((horizontal_operation, types_identical_operation))),
616
617   # Bit-wise binary operations.
618   operation("lshift", 2, printable_name="<<", source_types=integer_types, c_expression="{src0} << {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
619   operation("rshift", 2, printable_name=">>", source_types=integer_types, c_expression="{src0} >> {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
620   operation("bit_and", 2, printable_name="&", source_types=integer_types, c_expression="{src0} & {src1}", flags=vector_scalar_operation),
621   operation("bit_xor", 2, printable_name="^", source_types=integer_types, c_expression="{src0} ^ {src1}", flags=vector_scalar_operation),
622   operation("bit_or", 2, printable_name="|", source_types=integer_types, c_expression="{src0} | {src1}", flags=vector_scalar_operation),
623
624   operation("logic_and", 2, printable_name="&&", source_types=(bool_type,), c_expression="{src0} && {src1}"),
625   operation("logic_xor", 2, printable_name="^^", source_types=(bool_type,), c_expression="{src0} != {src1}"),
626   operation("logic_or", 2, printable_name="||", source_types=(bool_type,), c_expression="{src0} || {src1}"),
627
628   operation("dot", 2, source_types=real_types, c_expression={'f': "dot_f(op[0], op[1])", 'd': "dot_d(op[0], op[1])"}, flags=horizontal_operation),
629   operation("min", 2, source_types=numeric_types, c_expression="MIN2({src0}, {src1})", flags=vector_scalar_operation),
630   operation("max", 2, source_types=numeric_types, c_expression="MAX2({src0}, {src1})", flags=vector_scalar_operation),
631
632   operation("pow", 2, source_types=(float_type,), c_expression="powf({src0}, {src1})"),
633
634   # Load a value the size of a given GLSL type from a uniform block.
635   #
636   # operand0 is the ir_constant uniform block index in the linked shader.
637   # operand1 is a byte offset within the uniform block.
638   operation("ubo_load", 2),
639
640   # Multiplies a number by two to a power, part of ARB_gpu_shader5.
641   operation("ldexp", 2,
642             all_signatures=((float_type, (float_type, int_type)),
643                             (double_type, (double_type, int_type))),
644             c_expression={'f': "ldexpf_flush_subnormal({src0}, {src1})",
645                           'd': "ldexp_flush_subnormal({src0}, {src1})"}),
646
647   # Extract a scalar from a vector
648   #
649   # operand0 is the vector
650   # operand1 is the index of the field to read from operand0
651   operation("vector_extract", 2, source_types=all_types, c_expression="anything-except-None"),
652
653   # Interpolate fs input at offset
654   #
655   # operand0 is the fs input
656   # operand1 is the offset from the pixel center
657   operation("interpolate_at_offset", 2),
658
659   # Interpolate fs input at sample position
660   #
661   # operand0 is the fs input
662   # operand1 is the sample ID
663   operation("interpolate_at_sample", 2),
664
665   # Fused floating-point multiply-add, part of ARB_gpu_shader5.
666   operation("fma", 3, source_types=real_types, c_expression="{src0} * {src1} + {src2}"),
667
668   operation("lrp", 3, source_types=real_types, c_expression={'f': "{src0} * (1.0f - {src2}) + ({src1} * {src2})", 'd': "{src0} * (1.0 - {src2}) + ({src1} * {src2})"}),
669
670   # Conditional Select
671   #
672   # A vector conditional select instruction (like ?:, but operating per-
673   # component on vectors).
674   #
675   # See also lower_instructions_visitor::ldexp_to_arith
676   operation("csel", 3,
677             all_signatures=zip(all_types, zip(len(all_types) * (bool_type,), all_types, all_types)),
678             c_expression="{src0} ? {src1} : {src2}"),
679
680   operation("bitfield_extract", 3,
681             all_signatures=((int_type, (uint_type, int_type, int_type)),
682                             (int_type, (int_type, int_type, int_type))),
683             c_expression={'u': "bitfield_extract_uint({src0}, {src1}, {src2})",
684                           'i': "bitfield_extract_int({src0}, {src1}, {src2})"}),
685
686   # Generate a value with one field of a vector changed
687   #
688   # operand0 is the vector
689   # operand1 is the value to write into the vector result
690   # operand2 is the index in operand0 to be modified
691   operation("vector_insert", 3, source_types=all_types, c_expression="anything-except-None"),
692
693   operation("bitfield_insert", 4,
694             all_signatures=((uint_type, (uint_type, uint_type, int_type, int_type)),
695                             (int_type, (int_type, int_type, int_type, int_type))),
696             c_expression="bitfield_insert({src0}, {src1}, {src2}, {src3})"),
697
698   operation("vector", 4, source_types=all_types, c_expression="anything-except-None"),
699]
700
701
702if __name__ == "__main__":
703   copyright = """/*
704 * Copyright (C) 2010 Intel Corporation
705 *
706 * Permission is hereby granted, free of charge, to any person obtaining a
707 * copy of this software and associated documentation files (the "Software"),
708 * to deal in the Software without restriction, including without limitation
709 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
710 * and/or sell copies of the Software, and to permit persons to whom the
711 * Software is furnished to do so, subject to the following conditions:
712 *
713 * The above copyright notice and this permission notice (including the next
714 * paragraph) shall be included in all copies or substantial portions of the
715 * Software.
716 *
717 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
718 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
719 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
720 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
721 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
722 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
723 * DEALINGS IN THE SOFTWARE.
724 */
725"""
726   enum_template = mako.template.Template(copyright + """
727enum ir_expression_operation {
728% for item in values:
729   ${item.get_enum_name()},
730% endfor
731
732   /* Sentinels marking the last of each kind of operation. */
733% for item in lasts:
734   ir_last_${("un", "bin", "tri", "quad")[item.num_operands - 1]}op = ${item.get_enum_name()},
735% endfor
736   ir_last_opcode = ir_quadop_${lasts[3].name}
737};""")
738
739   strings_template = mako.template.Template(copyright + """
740const char *const ir_expression_operation_strings[] = {
741% for item in values:
742   "${item.printable_name}",
743% endfor
744};
745
746const char *const ir_expression_operation_enum_strings[] = {
747% for item in values:
748   "${item.name}",
749% endfor
750};""")
751
752   constant_template = mako.template.Template("""\
753   switch (this->operation) {
754% for op in values:
755    % if op.c_expression is not None:
756${op.get_template()}
757
758    % endif
759% endfor
760   default:
761      /* FINISHME: Should handle all expression types. */
762      return NULL;
763   }
764""")
765
766   if sys.argv[1] == "enum":
767      lasts = [None, None, None, None]
768      for item in reversed(ir_expression_operation):
769         i = item.num_operands - 1
770         if lasts[i] is None:
771            lasts[i] = item
772
773      print(enum_template.render(values=ir_expression_operation,
774                                 lasts=lasts))
775   elif sys.argv[1] == "strings":
776      print(strings_template.render(values=ir_expression_operation))
777   elif sys.argv[1] == "constant":
778      print(constant_template.render(values=ir_expression_operation))
779