glsl: Generate code for constant binary expressions that have one operand type
[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 numeric_types = (uint_type, int_type, float_type, double_type)
88 signed_numeric_types = (int_type, float_type, double_type)
89 integer_types = (uint_type, int_type)
90 real_types = (float_type, double_type)
91
92 # This template is for unary and binary operations that can only have operands
93 # of a single type. ir_unop_logic_not is an example.
94 constant_template0 = mako.template.Template("""\
95 case ${op.get_enum_name()}:
96 assert(op[0]->type->base_type == ${op.source_types[0].glsl_type});
97 for (unsigned c = 0; c < op[0]->type->components(); c++)
98 data.${op.source_types[0].union_field}[c] = ${op.get_c_expression(op.source_types)};
99 break;""")
100
101 # This template is for unary operations that can have operands of a several
102 # different types. ir_unop_bit_not is an example.
103 constant_template1 = mako.template.Template("""\
104 case ${op.get_enum_name()}:
105 switch (op[0]->type->base_type) {
106 % for dst_type, src_types in op.signatures():
107 case ${src_types[0].glsl_type}:
108 for (unsigned c = 0; c < op[0]->type->components(); c++)
109 data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)};
110 break;
111 % endfor
112 default:
113 assert(0);
114 }
115 break;""")
116
117 # This template is for unary operations that can have operands of a several
118 # different types, and each type has a different C expression. ir_unop_neg is
119 # an example.
120 constant_template3 = mako.template.Template("""\
121 case ${op.get_enum_name()}:
122 for (unsigned c = 0; c < op[0]->type->components(); c++) {
123 switch (this->type->base_type) {
124 % for dst_type, src_types in op.signatures():
125 case ${src_types[0].glsl_type}:
126 data.${dst_type.union_field}[c] = ${op.get_c_expression(src_types)};
127 break;
128 % endfor
129 default:
130 assert(0);
131 }
132 }
133 break;""")
134
135 # This template is for unary operations that map an operand of one type to an
136 # operand of another type. ir_unop_f2b is an example.
137 constant_template2 = mako.template.Template("""\
138 case ${op.get_enum_name()}:
139 assert(op[0]->type->base_type == ${op.source_types[0].glsl_type});
140 for (unsigned c = 0; c < op[0]->type->components(); c++)
141 data.${op.dest_type.union_field}[c] = ${op.get_c_expression(op.source_types)};
142 break;""")
143
144
145 class operation(object):
146 def __init__(self, name, num_operands, printable_name = None, source_types = None, dest_type = None, c_expression = None):
147 self.name = name
148 self.num_operands = num_operands
149
150 if printable_name is None:
151 self.printable_name = name
152 else:
153 self.printable_name = printable_name
154
155 self.source_types = source_types
156 self.dest_type = dest_type
157
158 if c_expression is None:
159 self.c_expression = None
160 elif isinstance(c_expression, str):
161 self.c_expression = {'default': c_expression}
162 else:
163 self.c_expression = c_expression
164
165
166 def get_enum_name(self):
167 return "ir_{}op_{}".format(("un", "bin", "tri", "quad")[self.num_operands-1], self.name)
168
169
170 def get_template(self):
171 if self.c_expression is None:
172 return None
173
174 if self.num_operands == 1:
175 if self.dest_type is not None:
176 return constant_template2.render(op=self)
177 elif len(self.source_types) == 1:
178 return constant_template0.render(op=self)
179 elif len(self.c_expression) == 1 and 'default' in self.c_expression:
180 return constant_template1.render(op=self)
181 else:
182 return constant_template3.render(op=self)
183 elif self.num_operands == 2:
184 if len(self.source_types) == 1:
185 return constant_template0.render(op=self)
186
187 return None
188
189
190 def get_c_expression(self, types):
191 src0 = "op[0]->value.{}[c]".format(types[0].union_field)
192 src1 = "op[1]->value.{}[c]".format(types[1].union_field) if len(types) >= 2 else "ERROR"
193
194 expr = self.c_expression[types[0].union_field] if types[0].union_field in self.c_expression else self.c_expression['default']
195
196 return expr.format(src0=src0)
197
198
199 def signatures(self):
200 return type_signature_iter(self.dest_type, self.source_types, self.num_operands)
201
202
203 ir_expression_operation = [
204 operation("bit_not", 1, printable_name="~", source_types=integer_types, c_expression="~ {src0}"),
205 operation("logic_not", 1, printable_name="!", source_types=(bool_type,), c_expression="!{src0}"),
206 operation("neg", 1, source_types=numeric_types, c_expression={'u': "-((int) {src0})", 'default': "-{src0}"}),
207 operation("abs", 1, source_types=signed_numeric_types, c_expression={'i': "{src0} < 0 ? -{src0} : {src0}", 'f': "fabsf({src0})", 'd': "fabs({src0})"}),
208 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))"}),
209 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"}),
210 operation("rsq", 1, source_types=real_types, c_expression={'f': "1.0F / sqrtf({src0})", 'd': "1.0 / sqrt({src0})"}),
211 operation("sqrt", 1, source_types=real_types, c_expression={'f': "sqrtf({src0})", 'd': "sqrt({src0})"}),
212 operation("exp", 1, source_types=(float_type,), c_expression="expf({src0})"), # Log base e on gentype
213 operation("log", 1, source_types=(float_type,), c_expression="logf({src0})"), # Natural log on gentype
214 operation("exp2", 1, source_types=(float_type,), c_expression="exp2f({src0})"),
215 operation("log2", 1, source_types=(float_type,), c_expression="log2f({src0})"),
216
217 # Float-to-integer conversion.
218 operation("f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="(int) {src0}"),
219 # Float-to-unsigned conversion.
220 operation("f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="(unsigned) {src0}"),
221 # Integer-to-float conversion.
222 operation("i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="(float) {src0}"),
223 # Float-to-boolean conversion
224 operation("f2b", 1, source_types=(float_type,), dest_type=bool_type, c_expression="{src0} != 0.0F ? true : false"),
225 # Boolean-to-float conversion
226 operation("b2f", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"),
227 # int-to-boolean conversion
228 operation("i2b", 1),
229 # Boolean-to-int conversion
230 operation("b2i", 1, source_types=(bool_type,), dest_type=int_type, c_expression="{src0} ? 1 : 0"),
231 # Unsigned-to-float conversion.
232 operation("u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="(float) {src0}"),
233 # Integer-to-unsigned conversion.
234 operation("i2u", 1, source_types=(int_type,), dest_type=uint_type, c_expression="{src0}"),
235 # Unsigned-to-integer conversion.
236 operation("u2i", 1, source_types=(uint_type,), dest_type=int_type, c_expression="{src0}"),
237 # Double-to-float conversion.
238 operation("d2f", 1, source_types=(double_type,), dest_type=float_type, c_expression="{src0}"),
239 # Float-to-double conversion.
240 operation("f2d", 1, source_types=(float_type,), dest_type=double_type, c_expression="{src0}"),
241 # Double-to-integer conversion.
242 operation("d2i", 1, source_types=(double_type,), dest_type=int_type, c_expression="{src0}"),
243 # Integer-to-double conversion.
244 operation("i2d", 1, source_types=(int_type,), dest_type=double_type, c_expression="{src0}"),
245 # Double-to-unsigned conversion.
246 operation("d2u", 1, source_types=(double_type,), dest_type=uint_type, c_expression="{src0}"),
247 # Unsigned-to-double conversion.
248 operation("u2d", 1, source_types=(uint_type,), dest_type=double_type, c_expression="{src0}"),
249 # Double-to-boolean conversion.
250 operation("d2b", 1, source_types=(double_type,), dest_type=bool_type, c_expression="{src0} != 0.0"),
251 # 'Bit-identical int-to-float "conversion"
252 operation("bitcast_i2f", 1, source_types=(int_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
253 # 'Bit-identical float-to-int "conversion"
254 operation("bitcast_f2i", 1, source_types=(float_type,), dest_type=int_type, c_expression="bitcast_f2u({src0})"),
255 # 'Bit-identical uint-to-float "conversion"
256 operation("bitcast_u2f", 1, source_types=(uint_type,), dest_type=float_type, c_expression="bitcast_u2f({src0})"),
257 # 'Bit-identical float-to-uint "conversion"
258 operation("bitcast_f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="bitcast_f2u({src0})"),
259
260 # Unary floating-point rounding operations.
261 operation("trunc", 1, source_types=real_types, c_expression={'f': "truncf({src0})", 'd': "trunc({src0})"}),
262 operation("ceil", 1, source_types=real_types, c_expression={'f': "ceilf({src0})", 'd': "ceil({src0})"}),
263 operation("floor", 1, source_types=real_types, c_expression={'f': "floorf({src0})", 'd': "floor({src0})"}),
264 operation("fract", 1, source_types=real_types, c_expression={'f': "{src0} - floorf({src0})", 'd': "{src0} - floor({src0})"}),
265 operation("round_even", 1, source_types=real_types, c_expression={'f': "_mesa_roundevenf({src0})", 'd': "_mesa_roundeven({src0})"}),
266
267 # Trigonometric operations.
268 operation("sin", 1, source_types=(float_type,), c_expression="sinf({src0})"),
269 operation("cos", 1, source_types=(float_type,), c_expression="cosf({src0})"),
270
271 # Partial derivatives.
272 operation("dFdx", 1, source_types=(float_type,), c_expression="0.0f"),
273 operation("dFdx_coarse", 1, printable_name="dFdxCoarse", source_types=(float_type,), c_expression="0.0f"),
274 operation("dFdx_fine", 1, printable_name="dFdxFine", source_types=(float_type,), c_expression="0.0f"),
275 operation("dFdy", 1, source_types=(float_type,), c_expression="0.0f"),
276 operation("dFdy_coarse", 1, printable_name="dFdyCoarse", source_types=(float_type,), c_expression="0.0f"),
277 operation("dFdy_fine", 1, printable_name="dFdyFine", source_types=(float_type,), c_expression="0.0f"),
278
279 # Floating point pack and unpack operations.
280 operation("pack_snorm_2x16", 1, printable_name="packSnorm2x16"),
281 operation("pack_snorm_4x8", 1, printable_name="packSnorm4x8"),
282 operation("pack_unorm_2x16", 1, printable_name="packUnorm2x16"),
283 operation("pack_unorm_4x8", 1, printable_name="packUnorm4x8"),
284 operation("pack_half_2x16", 1, printable_name="packHalf2x16"),
285 operation("unpack_snorm_2x16", 1, printable_name="unpackSnorm2x16"),
286 operation("unpack_snorm_4x8", 1, printable_name="unpackSnorm4x8"),
287 operation("unpack_unorm_2x16", 1, printable_name="unpackUnorm2x16"),
288 operation("unpack_unorm_4x8", 1, printable_name="unpackUnorm4x8"),
289 operation("unpack_half_2x16", 1, printable_name="unpackHalf2x16"),
290
291 # Bit operations, part of ARB_gpu_shader5.
292 operation("bitfield_reverse", 1, source_types=integer_types, c_expression="bitfield_reverse({src0})"),
293 operation("bit_count", 1),
294 operation("find_msb", 1),
295 operation("find_lsb", 1),
296
297 operation("saturate", 1, printable_name="sat", source_types=(float_type,), c_expression="CLAMP({src0}, 0.0f, 1.0f)"),
298
299 # Double packing, part of ARB_gpu_shader_fp64.
300 operation("pack_double_2x32", 1, printable_name="packDouble2x32"),
301 operation("unpack_double_2x32", 1, printable_name="unpackDouble2x32"),
302
303 operation("frexp_sig", 1),
304 operation("frexp_exp", 1),
305
306 operation("noise", 1),
307
308 operation("subroutine_to_int", 1),
309
310 # Interpolate fs input at centroid
311 #
312 # operand0 is the fs input.
313 operation("interpolate_at_centroid", 1),
314
315 # Ask the driver for the total size of a buffer block.
316 # operand0 is the ir_constant buffer block index in the linked shader.
317 operation("get_buffer_size", 1),
318
319 # Calculate length of an unsized array inside a buffer block.
320 # This opcode is going to be replaced in a lowering pass inside
321 # the linker.
322 #
323 # operand0 is the unsized array's ir_value for the calculation
324 # of its length.
325 operation("ssbo_unsized_array_length", 1),
326
327 # Vote among threads on the value of the boolean argument.
328 operation("vote_any", 1),
329 operation("vote_all", 1),
330 operation("vote_eq", 1),
331
332 operation("add", 2, printable_name="+"),
333 operation("sub", 2, printable_name="-"),
334 # "Floating-point or low 32-bit integer multiply."
335 operation("mul", 2, printable_name="*"),
336 operation("imul_high", 2), # Calculates the high 32-bits of a 64-bit multiply.
337 operation("div", 2, printable_name="/"),
338
339 # Returns the carry resulting from the addition of the two arguments.
340 operation("carry", 2),
341
342 # Returns the borrow resulting from the subtraction of the second argument
343 # from the first argument.
344 operation("borrow", 2),
345
346 # Either (vector % vector) or (vector % scalar)
347 operation("mod", 2, printable_name="%"),
348
349 # Binary comparison operators which return a boolean vector.
350 # The type of both operands must be equal.
351 operation("less", 2, printable_name="<"),
352 operation("greater", 2, printable_name=">"),
353 operation("lequal", 2, printable_name="<="),
354 operation("gequal", 2, printable_name=">="),
355 operation("equal", 2, printable_name="=="),
356 operation("nequal", 2, printable_name="!="),
357
358 # Returns single boolean for whether all components of operands[0]
359 # equal the components of operands[1].
360 operation("all_equal", 2),
361
362 # Returns single boolean for whether any component of operands[0]
363 # is not equal to the corresponding component of operands[1].
364 operation("any_nequal", 2),
365
366 # Bit-wise binary operations.
367 operation("lshift", 2, printable_name="<<"),
368 operation("rshift", 2, printable_name=">>"),
369 operation("bit_and", 2, printable_name="&"),
370 operation("bit_xor", 2, printable_name="^"),
371 operation("bit_or", 2, printable_name="|"),
372
373 operation("logic_and", 2, printable_name="&&", source_types=(bool_type,), c_expression="{src0} && {src1}"),
374 operation("logic_xor", 2, printable_name="^^", source_types=(bool_type,), c_expression="{src0} != {src1}"),
375 operation("logic_or", 2, printable_name="||", source_types=(bool_type,), c_expression="{src0} || {src1}"),
376
377 operation("dot", 2),
378 operation("min", 2),
379 operation("max", 2),
380
381 operation("pow", 2, source_types=(float_type,), c_expression="powf({src0}, {src1})"),
382
383 # Load a value the size of a given GLSL type from a uniform block.
384 #
385 # operand0 is the ir_constant uniform block index in the linked shader.
386 # operand1 is a byte offset within the uniform block.
387 operation("ubo_load", 2),
388
389 # Multiplies a number by two to a power, part of ARB_gpu_shader5.
390 operation("ldexp", 2),
391
392 # Extract a scalar from a vector
393 #
394 # operand0 is the vector
395 # operand1 is the index of the field to read from operand0
396 operation("vector_extract", 2),
397
398 # Interpolate fs input at offset
399 #
400 # operand0 is the fs input
401 # operand1 is the offset from the pixel center
402 operation("interpolate_at_offset", 2),
403
404 # Interpolate fs input at sample position
405 #
406 # operand0 is the fs input
407 # operand1 is the sample ID
408 operation("interpolate_at_sample", 2),
409
410 # Fused floating-point multiply-add, part of ARB_gpu_shader5.
411 operation("fma", 3),
412
413 operation("lrp", 3),
414
415 # Conditional Select
416 #
417 # A vector conditional select instruction (like ?:, but operating per-
418 # component on vectors).
419 #
420 # See also lower_instructions_visitor::ldexp_to_arith
421 operation("csel", 3),
422
423 operation("bitfield_extract", 3),
424
425 # Generate a value with one field of a vector changed
426 #
427 # operand0 is the vector
428 # operand1 is the value to write into the vector result
429 # operand2 is the index in operand0 to be modified
430 operation("vector_insert", 3),
431
432 operation("bitfield_insert", 4),
433
434 operation("vector", 4),
435 ]
436
437
438 if __name__ == "__main__":
439 copyright = """/*
440 * Copyright (C) 2010 Intel Corporation
441 *
442 * Permission is hereby granted, free of charge, to any person obtaining a
443 * copy of this software and associated documentation files (the "Software"),
444 * to deal in the Software without restriction, including without limitation
445 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
446 * and/or sell copies of the Software, and to permit persons to whom the
447 * Software is furnished to do so, subject to the following conditions:
448 *
449 * The above copyright notice and this permission notice (including the next
450 * paragraph) shall be included in all copies or substantial portions of the
451 * Software.
452 *
453 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
454 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
455 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
456 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
457 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
458 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
459 * DEALINGS IN THE SOFTWARE.
460 */
461 """
462 enum_template = mako.template.Template(copyright + """
463 enum ir_expression_operation {
464 % for item in values:
465 ${item.get_enum_name()},
466 % endfor
467
468 /* Sentinels marking the last of each kind of operation. */
469 % for item in lasts:
470 ir_last_${("un", "bin", "tri", "quad")[item.num_operands - 1]}op = ${item.get_enum_name()},
471 % endfor
472 ir_last_opcode = ir_quadop_${lasts[3].name}
473 };""")
474
475 strings_template = mako.template.Template(copyright + """
476 const char *const ir_expression_operation_strings[] = {
477 % for item in values:
478 "${item.printable_name}",
479 % endfor
480 };""")
481
482 constant_template = mako.template.Template("""\
483 switch (this->operation) {
484 % for op in values:
485 % if op.c_expression is not None:
486 ${op.get_template()}
487
488 % endif
489 % endfor
490 default:
491 /* FINISHME: Should handle all expression types. */
492 return NULL;
493 }
494 """)
495
496 if sys.argv[1] == "enum":
497 lasts = [None, None, None, None]
498 for item in reversed(ir_expression_operation):
499 i = item.num_operands - 1
500 if lasts[i] is None:
501 lasts[i] = item
502
503 print(enum_template.render(values=ir_expression_operation,
504 lasts=lasts))
505 elif sys.argv[1] == "strings":
506 print(strings_template.render(values=ir_expression_operation))
507 elif sys.argv[1] == "constant":
508 print(constant_template.render(values=ir_expression_operation))