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