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