egl: Update headers from Khronos
[mesa.git] / src / compiler / glsl / ir_expression_operation.py
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
23 import mako.template
24 import sys
25
26 class 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
33 class 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
80 uint_type = type("unsigned", "u", "GLSL_TYPE_UINT")
81 int_type = type("int", "i", "GLSL_TYPE_INT")
82 uint64_type = type("uint64_t", "u64", "GLSL_TYPE_UINT64")
83 int64_type = type("int64_t", "i64", "GLSL_TYPE_INT64")
84 float_type = type("float", "f", "GLSL_TYPE_FLOAT")
85 double_type = type("double", "d", "GLSL_TYPE_DOUBLE")
86 bool_type = type("bool", "b", "GLSL_TYPE_BOOL")
87
88 all_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type, bool_type)
89 numeric_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type)
90 signed_numeric_types = (int_type, float_type, double_type, int64_type)
91 integer_types = (uint_type, int_type, uint64_type, int64_type)
92 real_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.
97 constant_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.
114 constant_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.
145 constant_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.
196 constant_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.
203 constant_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.
210 constant_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.
224 constant_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.
242 constant_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.
261 constant_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.
277 constant_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).
301 constant_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
317 vector_scalar_operation = "vector-scalar"
318 horizontal_operation = "horizontal"
319 types_identical_operation = "identical"
320 non_assign_operation = "nonassign"
321 mixed_type_operation = "mixed"
322
323 class 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
415 ir_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("greater", 2, printable_name=">", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} > {src1}"),
606 operation("lequal", 2, printable_name="<=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} <= {src1}"),
607 operation("gequal", 2, printable_name=">=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} >= {src1}"),
608 operation("equal", 2, printable_name="==", source_types=all_types, dest_type=bool_type, c_expression="{src0} == {src1}"),
609 operation("nequal", 2, printable_name="!=", source_types=all_types, dest_type=bool_type, c_expression="{src0} != {src1}"),
610
611 # Returns single boolean for whether all components of operands[0]
612 # equal the components of operands[1].
613 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))),
614
615 # Returns single boolean for whether any component of operands[0]
616 # is not equal to the corresponding component of operands[1].
617 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))),
618
619 # Bit-wise binary operations.
620 operation("lshift", 2, printable_name="<<", source_types=integer_types, c_expression="{src0} << {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
621 operation("rshift", 2, printable_name=">>", source_types=integer_types, c_expression="{src0} >> {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
622 operation("bit_and", 2, printable_name="&", source_types=integer_types, c_expression="{src0} & {src1}", flags=vector_scalar_operation),
623 operation("bit_xor", 2, printable_name="^", source_types=integer_types, c_expression="{src0} ^ {src1}", flags=vector_scalar_operation),
624 operation("bit_or", 2, printable_name="|", source_types=integer_types, c_expression="{src0} | {src1}", flags=vector_scalar_operation),
625
626 operation("logic_and", 2, printable_name="&&", source_types=(bool_type,), c_expression="{src0} && {src1}"),
627 operation("logic_xor", 2, printable_name="^^", source_types=(bool_type,), c_expression="{src0} != {src1}"),
628 operation("logic_or", 2, printable_name="||", source_types=(bool_type,), c_expression="{src0} || {src1}"),
629
630 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),
631 operation("min", 2, source_types=numeric_types, c_expression="MIN2({src0}, {src1})", flags=vector_scalar_operation),
632 operation("max", 2, source_types=numeric_types, c_expression="MAX2({src0}, {src1})", flags=vector_scalar_operation),
633
634 operation("pow", 2, source_types=(float_type,), c_expression="powf({src0}, {src1})"),
635
636 # Load a value the size of a given GLSL type from a uniform block.
637 #
638 # operand0 is the ir_constant uniform block index in the linked shader.
639 # operand1 is a byte offset within the uniform block.
640 operation("ubo_load", 2),
641
642 # Multiplies a number by two to a power, part of ARB_gpu_shader5.
643 operation("ldexp", 2,
644 all_signatures=((float_type, (float_type, int_type)),
645 (double_type, (double_type, int_type))),
646 c_expression={'f': "ldexpf_flush_subnormal({src0}, {src1})",
647 'd': "ldexp_flush_subnormal({src0}, {src1})"}),
648
649 # Extract a scalar from a vector
650 #
651 # operand0 is the vector
652 # operand1 is the index of the field to read from operand0
653 operation("vector_extract", 2, source_types=all_types, c_expression="anything-except-None"),
654
655 # Interpolate fs input at offset
656 #
657 # operand0 is the fs input
658 # operand1 is the offset from the pixel center
659 operation("interpolate_at_offset", 2),
660
661 # Interpolate fs input at sample position
662 #
663 # operand0 is the fs input
664 # operand1 is the sample ID
665 operation("interpolate_at_sample", 2),
666
667 # Fused floating-point multiply-add, part of ARB_gpu_shader5.
668 operation("fma", 3, source_types=real_types, c_expression="{src0} * {src1} + {src2}"),
669
670 operation("lrp", 3, source_types=real_types, c_expression={'f': "{src0} * (1.0f - {src2}) + ({src1} * {src2})", 'd': "{src0} * (1.0 - {src2}) + ({src1} * {src2})"}),
671
672 # Conditional Select
673 #
674 # A vector conditional select instruction (like ?:, but operating per-
675 # component on vectors).
676 #
677 # See also lower_instructions_visitor::ldexp_to_arith
678 operation("csel", 3,
679 all_signatures=zip(all_types, zip(len(all_types) * (bool_type,), all_types, all_types)),
680 c_expression="{src0} ? {src1} : {src2}"),
681
682 operation("bitfield_extract", 3,
683 all_signatures=((int_type, (uint_type, int_type, int_type)),
684 (int_type, (int_type, int_type, int_type))),
685 c_expression={'u': "bitfield_extract_uint({src0}, {src1}, {src2})",
686 'i': "bitfield_extract_int({src0}, {src1}, {src2})"}),
687
688 # Generate a value with one field of a vector changed
689 #
690 # operand0 is the vector
691 # operand1 is the value to write into the vector result
692 # operand2 is the index in operand0 to be modified
693 operation("vector_insert", 3, source_types=all_types, c_expression="anything-except-None"),
694
695 operation("bitfield_insert", 4,
696 all_signatures=((uint_type, (uint_type, uint_type, int_type, int_type)),
697 (int_type, (int_type, int_type, int_type, int_type))),
698 c_expression="bitfield_insert({src0}, {src1}, {src2}, {src3})"),
699
700 operation("vector", 4, source_types=all_types, c_expression="anything-except-None"),
701 ]
702
703
704 if __name__ == "__main__":
705 copyright = """/*
706 * Copyright (C) 2010 Intel Corporation
707 *
708 * Permission is hereby granted, free of charge, to any person obtaining a
709 * copy of this software and associated documentation files (the "Software"),
710 * to deal in the Software without restriction, including without limitation
711 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
712 * and/or sell copies of the Software, and to permit persons to whom the
713 * Software is furnished to do so, subject to the following conditions:
714 *
715 * The above copyright notice and this permission notice (including the next
716 * paragraph) shall be included in all copies or substantial portions of the
717 * Software.
718 *
719 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
720 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
721 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
722 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
723 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
724 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
725 * DEALINGS IN THE SOFTWARE.
726 */
727 """
728 enum_template = mako.template.Template(copyright + """
729 enum ir_expression_operation {
730 % for item in values:
731 ${item.get_enum_name()},
732 % endfor
733
734 /* Sentinels marking the last of each kind of operation. */
735 % for item in lasts:
736 ir_last_${("un", "bin", "tri", "quad")[item.num_operands - 1]}op = ${item.get_enum_name()},
737 % endfor
738 ir_last_opcode = ir_quadop_${lasts[3].name}
739 };""")
740
741 strings_template = mako.template.Template(copyright + """
742 const char *const ir_expression_operation_strings[] = {
743 % for item in values:
744 "${item.printable_name}",
745 % endfor
746 };
747
748 const char *const ir_expression_operation_enum_strings[] = {
749 % for item in values:
750 "${item.name}",
751 % endfor
752 };""")
753
754 constant_template = mako.template.Template("""\
755 switch (this->operation) {
756 % for op in values:
757 % if op.c_expression is not None:
758 ${op.get_template()}
759
760 % endif
761 % endfor
762 default:
763 /* FINISHME: Should handle all expression types. */
764 return NULL;
765 }
766 """)
767
768 if sys.argv[1] == "enum":
769 lasts = [None, None, None, None]
770 for item in reversed(ir_expression_operation):
771 i = item.num_operands - 1
772 if lasts[i] is None:
773 lasts[i] = item
774
775 print(enum_template.render(values=ir_expression_operation,
776 lasts=lasts))
777 elif sys.argv[1] == "strings":
778 print(strings_template.render(values=ir_expression_operation))
779 elif sys.argv[1] == "constant":
780 print(constant_template.render(values=ir_expression_operation))