glsl: make use of glsl_type::is_double()
[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->base_type == GLSL_TYPE_FLOAT ||
280 op[0]->type->is_double());
281 assert(op[1]->type->base_type == GLSL_TYPE_FLOAT ||
282 op[1]->type->is_double());
283 assert(op[2]->type->base_type == GLSL_TYPE_FLOAT ||
284 op[2]->type->is_double());
285
286 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
287 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
288 switch (this->type->base_type) {
289 % for dst_type, src_types in op.signatures():
290 case ${src_types[0].glsl_type}:
291 data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types, ("c", "c", "c2"))};
292 break;
293 % endfor
294 default:
295 unreachable("invalid type");
296 }
297 }
298 break;
299 }""")
300
301 # This template is for ir_triop_csel. This expression is really unique
302 # because not all of the operands are the same type, and the second operand
303 # determines the type of the expression (instead of the first).
304 constant_template_csel = mako.template.Template("""\
305 case ${op.get_enum_name()}:
306 for (unsigned c = 0; c < components; c++) {
307 switch (this->type->base_type) {
308 % for dst_type, src_types in op.signatures():
309 case ${src_types[1].glsl_type}:
310 data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)};
311 break;
312 % endfor
313 default:
314 unreachable("invalid type");
315 }
316 }
317 break;""")
318
319
320 vector_scalar_operation = "vector-scalar"
321 horizontal_operation = "horizontal"
322 types_identical_operation = "identical"
323 non_assign_operation = "nonassign"
324 mixed_type_operation = "mixed"
325
326 class operation(object):
327 def __init__(self, name, num_operands, printable_name = None, source_types = None, dest_type = None, c_expression = None, flags = None, all_signatures = None):
328 self.name = name
329 self.num_operands = num_operands
330
331 if printable_name is None:
332 self.printable_name = name
333 else:
334 self.printable_name = printable_name
335
336 self.all_signatures = all_signatures
337
338 if source_types is None:
339 self.source_types = tuple()
340 else:
341 self.source_types = source_types
342
343 self.dest_type = dest_type
344
345 if c_expression is None:
346 self.c_expression = None
347 elif isinstance(c_expression, str):
348 self.c_expression = {'default': c_expression}
349 else:
350 self.c_expression = c_expression
351
352 if flags is None:
353 self.flags = frozenset()
354 elif isinstance(flags, str):
355 self.flags = frozenset([flags])
356 else:
357 self.flags = frozenset(flags)
358
359
360 def get_enum_name(self):
361 return "ir_{0}op_{1}".format(("un", "bin", "tri", "quad")[self.num_operands-1], self.name)
362
363
364 def get_template(self):
365 if self.c_expression is None:
366 return None
367
368 if horizontal_operation in self.flags:
369 if non_assign_operation in self.flags:
370 return constant_template_horizontal_nonassignment.render(op=self)
371 elif types_identical_operation in self.flags:
372 return constant_template_horizontal_single_implementation.render(op=self)
373 else:
374 return constant_template_horizontal.render(op=self)
375
376 if self.num_operands == 2:
377 if self.name == "mul":
378 return constant_template_mul.render(op=self)
379 elif self.name == "vector_extract":
380 return constant_template_vector_extract.render(op=self)
381 elif vector_scalar_operation in self.flags:
382 return constant_template_vector_scalar.render(op=self)
383 elif self.num_operands == 3:
384 if self.name == "vector_insert":
385 return constant_template_vector_insert.render(op=self)
386 elif self.name == "lrp":
387 return constant_template_lrp.render(op=self)
388 elif self.name == "csel":
389 return constant_template_csel.render(op=self)
390 elif self.num_operands == 4:
391 if self.name == "vector":
392 return constant_template_vector.render(op=self)
393
394 return constant_template_common.render(op=self)
395
396
397 def get_c_expression(self, types, indices=("c", "c", "c")):
398 src0 = "op[0]->value.{0}[{1}]".format(types[0].union_field, indices[0])
399 src1 = "op[1]->value.{0}[{1}]".format(types[1].union_field, indices[1]) if len(types) >= 2 else "ERROR"
400 src2 = "op[2]->value.{0}[{1}]".format(types[2].union_field, indices[2]) if len(types) >= 3 else "ERROR"
401 src3 = "op[3]->value.{0}[c]".format(types[3].union_field) if len(types) >= 4 else "ERROR"
402
403 expr = self.c_expression[types[0].union_field] if types[0].union_field in self.c_expression else self.c_expression['default']
404
405 return expr.format(src0=src0,
406 src1=src1,
407 src2=src2,
408 src3=src3)
409
410
411 def signatures(self):
412 if self.all_signatures is not None:
413 return self.all_signatures
414 else:
415 return type_signature_iter(self.dest_type, self.source_types, self.num_operands)
416
417
418 ir_expression_operation = [
419 operation("bit_not", 1, printable_name="~", source_types=integer_types, c_expression="~ {src0}"),
420 operation("logic_not", 1, printable_name="!", source_types=(bool_type,), c_expression="!{src0}"),
421 operation("neg", 1, source_types=numeric_types, c_expression={'u': "-((int) {src0})", 'default': "-{src0}"}),
422 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}"}),
423 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)"}),
424 operation("rcp", 1, source_types=real_types, c_expression={'f': "1.0F / {src0}", 'd': "1.0 / {src0}"}),
425 operation("rsq", 1, source_types=real_types, c_expression={'f': "1.0F / sqrtf({src0})", 'd': "1.0 / sqrt({src0})"}),
426 operation("sqrt", 1, source_types=real_types, c_expression={'f': "sqrtf({src0})", 'd': "sqrt({src0})"}),
427 operation("exp", 1, source_types=(float_type,), c_expression="expf({src0})"), # Log base e on gentype
428 operation("log", 1, source_types=(float_type,), c_expression="logf({src0})"), # Natural log on gentype
429 operation("exp2", 1, source_types=(float_type,), c_expression="exp2f({src0})"),
430 operation("log2", 1, source_types=(float_type,), c_expression="log2f({src0})"),
431
432 # Float-to-integer conversion.
433 operation("f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="(int) {src0}"),
434 # Float-to-unsigned conversion.
435 operation("f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="(unsigned) {src0}"),
436 # Integer-to-float conversion.
437 operation("i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="(float) {src0}"),
438 # Float-to-boolean conversion
439 operation("f2b", 1, source_types=(float_type,), dest_type=bool_type, c_expression="{src0} != 0.0F ? true : false"),
440 # Boolean-to-float conversion
441 operation("b2f", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"),
442 # int-to-boolean conversion
443 operation("i2b", 1, source_types=(uint_type, int_type), dest_type=bool_type, c_expression="{src0} ? true : false"),
444 # Boolean-to-int conversion
445 operation("b2i", 1, source_types=(bool_type,), dest_type=int_type, c_expression="{src0} ? 1 : 0"),
446 # Unsigned-to-float conversion.
447 operation("u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="(float) {src0}"),
448 # Integer-to-unsigned conversion.
449 operation("i2u", 1, source_types=(int_type,), dest_type=uint_type, c_expression="{src0}"),
450 # Unsigned-to-integer conversion.
451 operation("u2i", 1, source_types=(uint_type,), dest_type=int_type, c_expression="{src0}"),
452 # Double-to-float conversion.
453 operation("d2f", 1, source_types=(double_type,), dest_type=float_type, c_expression="{src0}"),
454 # Float-to-double conversion.
455 operation("f2d", 1, source_types=(float_type,), dest_type=double_type, c_expression="{src0}"),
456 # Double-to-integer conversion.
457 operation("d2i", 1, source_types=(double_type,), dest_type=int_type, c_expression="{src0}"),
458 # Integer-to-double conversion.
459 operation("i2d", 1, source_types=(int_type,), dest_type=double_type, c_expression="{src0}"),
460 # Double-to-unsigned conversion.
461 operation("d2u", 1, source_types=(double_type,), dest_type=uint_type, c_expression="{src0}"),
462 # Unsigned-to-double conversion.
463 operation("u2d", 1, source_types=(uint_type,), dest_type=double_type, c_expression="{src0}"),
464 # Double-to-boolean conversion.
465 operation("d2b", 1, source_types=(double_type,), dest_type=bool_type, c_expression="{src0} != 0.0"),
466 # 'Bit-identical int-to-float "conversion"
467 operation("bitcast_i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
468 # 'Bit-identical float-to-int "conversion"
469 operation("bitcast_f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="bitcast_f2u({src0})"),
470 # 'Bit-identical uint-to-float "conversion"
471 operation("bitcast_u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
472 # 'Bit-identical float-to-uint "conversion"
473 operation("bitcast_f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="bitcast_f2u({src0})"),
474 # Bit-identical u64-to-double "conversion"
475 operation("bitcast_u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="bitcast_u642d({src0})"),
476 # Bit-identical i64-to-double "conversion"
477 operation("bitcast_i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="bitcast_i642d({src0})"),
478 # Bit-identical double-to_u64 "conversion"
479 operation("bitcast_d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="bitcast_d2u64({src0})"),
480 # Bit-identical double-to-i64 "conversion"
481 operation("bitcast_d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="bitcast_d2i64({src0})"),
482 # i64-to-i32 conversion
483 operation("i642i", 1, source_types=(int64_type,), dest_type=int_type, c_expression="{src0}"),
484 # ui64-to-i32 conversion
485 operation("u642i", 1, source_types=(uint64_type,), dest_type=int_type, c_expression="{src0}"),
486 operation("i642u", 1, source_types=(int64_type,), dest_type=uint_type, c_expression="{src0}"),
487 operation("u642u", 1, source_types=(uint64_type,), dest_type=uint_type, c_expression="{src0}"),
488 operation("i642b", 1, source_types=(int64_type,), dest_type=bool_type, c_expression="{src0} != 0"),
489 operation("i642f", 1, source_types=(int64_type,), dest_type=float_type, c_expression="{src0}"),
490 operation("u642f", 1, source_types=(uint64_type,), dest_type=float_type, c_expression="{src0}"),
491 operation("i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="{src0}"),
492 operation("u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="{src0}"),
493 operation("i2i64", 1, source_types=(int_type,), dest_type=int64_type, c_expression="{src0}"),
494 operation("u2i64", 1, source_types=(uint_type,), dest_type=int64_type, c_expression="{src0}"),
495 operation("b2i64", 1, source_types=(bool_type,), dest_type=int64_type, c_expression="{src0}"),
496 operation("f2i64", 1, source_types=(float_type,), dest_type=int64_type, c_expression="{src0}"),
497 operation("d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="{src0}"),
498 operation("i2u64", 1, source_types=(int_type,), dest_type=uint64_type, c_expression="{src0}"),
499 operation("u2u64", 1, source_types=(uint_type,), dest_type=uint64_type, c_expression="{src0}"),
500 operation("f2u64", 1, source_types=(float_type,), dest_type=uint64_type, c_expression="{src0}"),
501 operation("d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="{src0}"),
502 operation("u642i64", 1, source_types=(uint64_type,), dest_type=int64_type, c_expression="{src0}"),
503 operation("i642u64", 1, source_types=(int64_type,), dest_type=uint64_type, c_expression="{src0}"),
504
505
506 # Unary floating-point rounding operations.
507 operation("trunc", 1, source_types=real_types, c_expression={'f': "truncf({src0})", 'd': "trunc({src0})"}),
508 operation("ceil", 1, source_types=real_types, c_expression={'f': "ceilf({src0})", 'd': "ceil({src0})"}),
509 operation("floor", 1, source_types=real_types, c_expression={'f': "floorf({src0})", 'd': "floor({src0})"}),
510 operation("fract", 1, source_types=real_types, c_expression={'f': "{src0} - floorf({src0})", 'd': "{src0} - floor({src0})"}),
511 operation("round_even", 1, source_types=real_types, c_expression={'f': "_mesa_roundevenf({src0})", 'd': "_mesa_roundeven({src0})"}),
512
513 # Trigonometric operations.
514 operation("sin", 1, source_types=(float_type,), c_expression="sinf({src0})"),
515 operation("cos", 1, source_types=(float_type,), c_expression="cosf({src0})"),
516
517 # Partial derivatives.
518 operation("dFdx", 1, source_types=(float_type,), c_expression="0.0f"),
519 operation("dFdx_coarse", 1, printable_name="dFdxCoarse", source_types=(float_type,), c_expression="0.0f"),
520 operation("dFdx_fine", 1, printable_name="dFdxFine", source_types=(float_type,), c_expression="0.0f"),
521 operation("dFdy", 1, source_types=(float_type,), c_expression="0.0f"),
522 operation("dFdy_coarse", 1, printable_name="dFdyCoarse", source_types=(float_type,), c_expression="0.0f"),
523 operation("dFdy_fine", 1, printable_name="dFdyFine", source_types=(float_type,), c_expression="0.0f"),
524
525 # Floating point pack and unpack operations.
526 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),
527 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),
528 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),
529 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),
530 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),
531 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))),
532 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))),
533 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))),
534 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))),
535 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))),
536
537 # Bit operations, part of ARB_gpu_shader5.
538 operation("bitfield_reverse", 1, source_types=(uint_type, int_type), c_expression="bitfield_reverse({src0})"),
539 operation("bit_count", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="_mesa_bitcount({src0})"),
540 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})"}),
541 operation("find_lsb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="find_msb_uint({src0} & -{src0})"),
542
543 operation("saturate", 1, printable_name="sat", source_types=(float_type,), c_expression="CLAMP({src0}, 0.0f, 1.0f)"),
544
545 # Double packing, part of ARB_gpu_shader_fp64.
546 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))),
547 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))),
548
549 operation("frexp_sig", 1),
550 operation("frexp_exp", 1),
551
552 operation("noise", 1),
553
554 operation("subroutine_to_int", 1),
555
556 # Interpolate fs input at centroid
557 #
558 # operand0 is the fs input.
559 operation("interpolate_at_centroid", 1),
560
561 # Ask the driver for the total size of a buffer block.
562 # operand0 is the ir_constant buffer block index in the linked shader.
563 operation("get_buffer_size", 1),
564
565 # Calculate length of an unsized array inside a buffer block.
566 # This opcode is going to be replaced in a lowering pass inside
567 # the linker.
568 #
569 # operand0 is the unsized array's ir_value for the calculation
570 # of its length.
571 operation("ssbo_unsized_array_length", 1),
572
573 # ARB_shader_ballot operations
574 operation("ballot", 1, source_types=(bool_type,), dest_type=uint64_type),
575 operation("read_first_invocation", 1),
576
577 # Vote among threads on the value of the boolean argument.
578 operation("vote_any", 1),
579 operation("vote_all", 1),
580 operation("vote_eq", 1),
581
582 # 64-bit integer packing ops.
583 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))),
584 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))),
585 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))),
586 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))),
587
588 operation("add", 2, printable_name="+", source_types=numeric_types, c_expression="{src0} + {src1}", flags=vector_scalar_operation),
589 operation("sub", 2, printable_name="-", source_types=numeric_types, c_expression="{src0} - {src1}", flags=vector_scalar_operation),
590 # "Floating-point or low 32-bit integer multiply."
591 operation("mul", 2, printable_name="*", source_types=numeric_types, c_expression="{src0} * {src1}"),
592 operation("imul_high", 2), # Calculates the high 32-bits of a 64-bit multiply.
593 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),
594
595 # Returns the carry resulting from the addition of the two arguments.
596 operation("carry", 2),
597
598 # Returns the borrow resulting from the subtraction of the second argument
599 # from the first argument.
600 operation("borrow", 2),
601
602 # Either (vector % vector) or (vector % scalar)
603 #
604 # We don't use fmod because it rounds toward zero; GLSL specifies the use
605 # of floor.
606 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),
607
608 # Binary comparison operators which return a boolean vector.
609 # The type of both operands must be equal.
610 operation("less", 2, printable_name="<", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} < {src1}"),
611 operation("greater", 2, printable_name=">", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} > {src1}"),
612 operation("lequal", 2, printable_name="<=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} <= {src1}"),
613 operation("gequal", 2, printable_name=">=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} >= {src1}"),
614 operation("equal", 2, printable_name="==", source_types=all_types, dest_type=bool_type, c_expression="{src0} == {src1}"),
615 operation("nequal", 2, printable_name="!=", source_types=all_types, dest_type=bool_type, c_expression="{src0} != {src1}"),
616
617 # Returns single boolean for whether all components of operands[0]
618 # equal the components of operands[1].
619 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))),
620
621 # Returns single boolean for whether any component of operands[0]
622 # is not equal to the corresponding component of operands[1].
623 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))),
624
625 # Bit-wise binary operations.
626 operation("lshift", 2, printable_name="<<", source_types=integer_types, c_expression="{src0} << {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
627 operation("rshift", 2, printable_name=">>", source_types=integer_types, c_expression="{src0} >> {src1}", flags=frozenset((vector_scalar_operation, mixed_type_operation))),
628 operation("bit_and", 2, printable_name="&", source_types=integer_types, c_expression="{src0} & {src1}", flags=vector_scalar_operation),
629 operation("bit_xor", 2, printable_name="^", source_types=integer_types, c_expression="{src0} ^ {src1}", flags=vector_scalar_operation),
630 operation("bit_or", 2, printable_name="|", source_types=integer_types, c_expression="{src0} | {src1}", flags=vector_scalar_operation),
631
632 operation("logic_and", 2, printable_name="&&", source_types=(bool_type,), c_expression="{src0} && {src1}"),
633 operation("logic_xor", 2, printable_name="^^", source_types=(bool_type,), c_expression="{src0} != {src1}"),
634 operation("logic_or", 2, printable_name="||", source_types=(bool_type,), c_expression="{src0} || {src1}"),
635
636 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),
637 operation("min", 2, source_types=numeric_types, c_expression="MIN2({src0}, {src1})", flags=vector_scalar_operation),
638 operation("max", 2, source_types=numeric_types, c_expression="MAX2({src0}, {src1})", flags=vector_scalar_operation),
639
640 operation("pow", 2, source_types=(float_type,), c_expression="powf({src0}, {src1})"),
641
642 # Load a value the size of a given GLSL type from a uniform block.
643 #
644 # operand0 is the ir_constant uniform block index in the linked shader.
645 # operand1 is a byte offset within the uniform block.
646 operation("ubo_load", 2),
647
648 # Multiplies a number by two to a power, part of ARB_gpu_shader5.
649 operation("ldexp", 2,
650 all_signatures=((float_type, (float_type, int_type)),
651 (double_type, (double_type, int_type))),
652 c_expression={'f': "ldexpf_flush_subnormal({src0}, {src1})",
653 'd': "ldexp_flush_subnormal({src0}, {src1})"}),
654
655 # Extract a scalar from a vector
656 #
657 # operand0 is the vector
658 # operand1 is the index of the field to read from operand0
659 operation("vector_extract", 2, source_types=all_types, c_expression="anything-except-None"),
660
661 # Interpolate fs input at offset
662 #
663 # operand0 is the fs input
664 # operand1 is the offset from the pixel center
665 operation("interpolate_at_offset", 2),
666
667 # Interpolate fs input at sample position
668 #
669 # operand0 is the fs input
670 # operand1 is the sample ID
671 operation("interpolate_at_sample", 2),
672
673 # ARB_shader_ballot operation
674 operation("read_invocation", 2),
675
676 # Fused floating-point multiply-add, part of ARB_gpu_shader5.
677 operation("fma", 3, source_types=real_types, c_expression="{src0} * {src1} + {src2}"),
678
679 operation("lrp", 3, source_types=real_types, c_expression={'f': "{src0} * (1.0f - {src2}) + ({src1} * {src2})", 'd': "{src0} * (1.0 - {src2}) + ({src1} * {src2})"}),
680
681 # Conditional Select
682 #
683 # A vector conditional select instruction (like ?:, but operating per-
684 # component on vectors).
685 #
686 # See also lower_instructions_visitor::ldexp_to_arith
687 operation("csel", 3,
688 all_signatures=zip(all_types, zip(len(all_types) * (bool_type,), all_types, all_types)),
689 c_expression="{src0} ? {src1} : {src2}"),
690
691 operation("bitfield_extract", 3,
692 all_signatures=((int_type, (uint_type, int_type, int_type)),
693 (int_type, (int_type, int_type, int_type))),
694 c_expression={'u': "bitfield_extract_uint({src0}, {src1}, {src2})",
695 'i': "bitfield_extract_int({src0}, {src1}, {src2})"}),
696
697 # Generate a value with one field of a vector changed
698 #
699 # operand0 is the vector
700 # operand1 is the value to write into the vector result
701 # operand2 is the index in operand0 to be modified
702 operation("vector_insert", 3, source_types=all_types, c_expression="anything-except-None"),
703
704 operation("bitfield_insert", 4,
705 all_signatures=((uint_type, (uint_type, uint_type, int_type, int_type)),
706 (int_type, (int_type, int_type, int_type, int_type))),
707 c_expression="bitfield_insert({src0}, {src1}, {src2}, {src3})"),
708
709 operation("vector", 4, source_types=all_types, c_expression="anything-except-None"),
710 ]
711
712
713 if __name__ == "__main__":
714 copyright = """/*
715 * Copyright (C) 2010 Intel Corporation
716 *
717 * Permission is hereby granted, free of charge, to any person obtaining a
718 * copy of this software and associated documentation files (the "Software"),
719 * to deal in the Software without restriction, including without limitation
720 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
721 * and/or sell copies of the Software, and to permit persons to whom the
722 * Software is furnished to do so, subject to the following conditions:
723 *
724 * The above copyright notice and this permission notice (including the next
725 * paragraph) shall be included in all copies or substantial portions of the
726 * Software.
727 *
728 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
729 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
730 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
731 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
732 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
733 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
734 * DEALINGS IN THE SOFTWARE.
735 */
736 """
737 enum_template = mako.template.Template(copyright + """
738 enum ir_expression_operation {
739 % for item in values:
740 ${item.get_enum_name()},
741 % endfor
742
743 /* Sentinels marking the last of each kind of operation. */
744 % for item in lasts:
745 ir_last_${("un", "bin", "tri", "quad")[item.num_operands - 1]}op = ${item.get_enum_name()},
746 % endfor
747 ir_last_opcode = ir_quadop_${lasts[3].name}
748 };""")
749
750 strings_template = mako.template.Template(copyright + """
751 const char *const ir_expression_operation_strings[] = {
752 % for item in values:
753 "${item.printable_name}",
754 % endfor
755 };
756
757 const char *const ir_expression_operation_enum_strings[] = {
758 % for item in values:
759 "${item.name}",
760 % endfor
761 };""")
762
763 constant_template = mako.template.Template("""\
764 switch (this->operation) {
765 % for op in values:
766 % if op.c_expression is not None:
767 ${op.get_template()}
768
769 % endif
770 % endfor
771 default:
772 /* FINISHME: Should handle all expression types. */
773 return NULL;
774 }
775 """)
776
777 if sys.argv[1] == "enum":
778 lasts = [None, None, None, None]
779 for item in reversed(ir_expression_operation):
780 i = item.num_operands - 1
781 if lasts[i] is None:
782 lasts[i] = item
783
784 print(enum_template.render(values=ir_expression_operation,
785 lasts=lasts))
786 elif sys.argv[1] == "strings":
787 print(strings_template.render(values=ir_expression_operation))
788 elif sys.argv[1] == "constant":
789 print(constant_template.render(values=ir_expression_operation))