3 # Copyright (C) 2015 Intel Corporation
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:
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
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
28 def __init__(self
, c_type
, union_field
, glsl_type
):
30 self
.union_field
= union_field
31 self
.glsl_type
= glsl_type
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.
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.
47 self
.source_types
= source_types
48 self
.num_operands
= num_operands
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
58 self
.dest_type
= dest_type
59 self
.source_types
= source_types
60 self
.num_operands
= num_operands
67 if self
.i
< len(self
.source_types
):
71 if self
.dest_type
is None:
72 dest_type
= self
.source_types
[i
]
74 dest_type
= self
.dest_type
76 return (dest_type
, self
.num_operands
* (self
.source_types
[i
],))
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")
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
)
92 # This template is for unary operations that can only have operands of a
93 # 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)};
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)};
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
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)};
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)};
145 class operation(object):
146 def __init__(self
, name
, num_operands
, printable_name
= None, source_types
= None, dest_type
= None, c_expression
= None):
148 self
.num_operands
= num_operands
150 if printable_name
is None:
151 self
.printable_name
= name
153 self
.printable_name
= printable_name
155 self
.source_types
= source_types
156 self
.dest_type
= dest_type
158 if c_expression
is None:
159 self
.c_expression
= None
160 elif isinstance(c_expression
, str):
161 self
.c_expression
= {'default': c_expression
}
163 self
.c_expression
= c_expression
166 def get_enum_name(self
):
167 return "ir_{}op_{}".format(("un", "bin", "tri", "quad")[self
.num_operands
-1], self
.name
)
170 def get_template(self
):
171 if self
.c_expression
is None:
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
)
182 return constant_template3
.render(op
=self
)
187 def get_c_expression(self
, types
):
188 src0
= "op[0]->value.{}[c]".format(types
[0].union_field
)
190 expr
= self
.c_expression
[types
[0].union_field
] if types
[0].union_field
in self
.c_expression
else self
.c_expression
['default']
192 return expr
.format(src0
=src0
)
195 def signatures(self
):
196 return type_signature_iter(self
.dest_type
, self
.source_types
, self
.num_operands
)
199 ir_expression_operation
= [
200 operation("bit_not", 1, printable_name
="~", source_types
=integer_types
, c_expression
="~ {src0}"),
201 operation("logic_not", 1, printable_name
="!", source_types
=(bool_type
,), c_expression
="!{src0}"),
202 operation("neg", 1, source_types
=numeric_types
, c_expression
={'u': "-((int) {src0})", 'default': "-{src0}"}),
203 operation("abs", 1, source_types
=signed_numeric_types
, c_expression
={'i': "{src0} < 0 ? -{src0} : {src0}", 'f': "fabsf({src0})", 'd': "fabs({src0})"}),
204 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))"}),
205 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"}),
206 operation("rsq", 1, source_types
=real_types
, c_expression
={'f': "1.0F / sqrtf({src0})", 'd': "1.0 / sqrt({src0})"}),
207 operation("sqrt", 1, source_types
=real_types
, c_expression
={'f': "sqrtf({src0})", 'd': "sqrt({src0})"}),
208 operation("exp", 1, source_types
=(float_type
,), c_expression
="expf({src0})"), # Log base e on gentype
209 operation("log", 1, source_types
=(float_type
,), c_expression
="logf({src0})"), # Natural log on gentype
210 operation("exp2", 1, source_types
=(float_type
,), c_expression
="exp2f({src0})"),
211 operation("log2", 1, source_types
=(float_type
,), c_expression
="log2f({src0})"),
213 # Float-to-integer conversion.
214 operation("f2i", 1, source_types
=(float_type
,), dest_type
=int_type
, c_expression
="(int) {src0}"),
215 # Float-to-unsigned conversion.
216 operation("f2u", 1, source_types
=(float_type
,), dest_type
=uint_type
, c_expression
="(unsigned) {src0}"),
217 # Integer-to-float conversion.
218 operation("i2f", 1, source_types
=(int_type
,), dest_type
=float_type
, c_expression
="(float) {src0}"),
219 # Float-to-boolean conversion
220 operation("f2b", 1, source_types
=(float_type
,), dest_type
=bool_type
, c_expression
="{src0} != 0.0F ? true : false"),
221 # Boolean-to-float conversion
222 operation("b2f", 1, source_types
=(bool_type
,), dest_type
=float_type
, c_expression
="{src0} ? 1.0F : 0.0F"),
223 # int-to-boolean conversion
225 # Boolean-to-int conversion
226 operation("b2i", 1, source_types
=(bool_type
,), dest_type
=int_type
, c_expression
="{src0} ? 1 : 0"),
227 # Unsigned-to-float conversion.
228 operation("u2f", 1, source_types
=(uint_type
,), dest_type
=float_type
, c_expression
="(float) {src0}"),
229 # Integer-to-unsigned conversion.
230 operation("i2u", 1, source_types
=(int_type
,), dest_type
=uint_type
, c_expression
="{src0}"),
231 # Unsigned-to-integer conversion.
232 operation("u2i", 1, source_types
=(uint_type
,), dest_type
=int_type
, c_expression
="{src0}"),
233 # Double-to-float conversion.
234 operation("d2f", 1, source_types
=(double_type
,), dest_type
=float_type
, c_expression
="{src0}"),
235 # Float-to-double conversion.
236 operation("f2d", 1, source_types
=(float_type
,), dest_type
=double_type
, c_expression
="{src0}"),
237 # Double-to-integer conversion.
238 operation("d2i", 1, source_types
=(double_type
,), dest_type
=int_type
, c_expression
="{src0}"),
239 # Integer-to-double conversion.
240 operation("i2d", 1, source_types
=(int_type
,), dest_type
=double_type
, c_expression
="{src0}"),
241 # Double-to-unsigned conversion.
242 operation("d2u", 1, source_types
=(double_type
,), dest_type
=uint_type
, c_expression
="{src0}"),
243 # Unsigned-to-double conversion.
244 operation("u2d", 1, source_types
=(uint_type
,), dest_type
=double_type
, c_expression
="{src0}"),
245 # Double-to-boolean conversion.
246 operation("d2b", 1, source_types
=(double_type
,), dest_type
=bool_type
, c_expression
="{src0} != 0.0"),
247 # 'Bit-identical int-to-float "conversion"
248 operation("bitcast_i2f", 1, source_types
=(int_type
,), dest_type
=float_type
, c_expression
="bitcast_u2f({src0})"),
249 # 'Bit-identical float-to-int "conversion"
250 operation("bitcast_f2i", 1, source_types
=(float_type
,), dest_type
=int_type
, c_expression
="bitcast_f2u({src0})"),
251 # 'Bit-identical uint-to-float "conversion"
252 operation("bitcast_u2f", 1, source_types
=(uint_type
,), dest_type
=float_type
, c_expression
="bitcast_u2f({src0})"),
253 # 'Bit-identical float-to-uint "conversion"
254 operation("bitcast_f2u", 1, source_types
=(float_type
,), dest_type
=uint_type
, c_expression
="bitcast_f2u({src0})"),
256 # Unary floating-point rounding operations.
257 operation("trunc", 1, source_types
=real_types
, c_expression
={'f': "truncf({src0})", 'd': "trunc({src0})"}),
258 operation("ceil", 1, source_types
=real_types
, c_expression
={'f': "ceilf({src0})", 'd': "ceil({src0})"}),
259 operation("floor", 1, source_types
=real_types
, c_expression
={'f': "floorf({src0})", 'd': "floor({src0})"}),
260 operation("fract", 1, source_types
=real_types
, c_expression
={'f': "{src0} - floorf({src0})", 'd': "{src0} - floor({src0})"}),
261 operation("round_even", 1, source_types
=real_types
, c_expression
={'f': "_mesa_roundevenf({src0})", 'd': "_mesa_roundeven({src0})"}),
263 # Trigonometric operations.
264 operation("sin", 1, source_types
=(float_type
,), c_expression
="sinf({src0})"),
265 operation("cos", 1, source_types
=(float_type
,), c_expression
="cosf({src0})"),
267 # Partial derivatives.
268 operation("dFdx", 1, source_types
=(float_type
,), c_expression
="0.0f"),
269 operation("dFdx_coarse", 1, printable_name
="dFdxCoarse", source_types
=(float_type
,), c_expression
="0.0f"),
270 operation("dFdx_fine", 1, printable_name
="dFdxFine", source_types
=(float_type
,), c_expression
="0.0f"),
271 operation("dFdy", 1, source_types
=(float_type
,), c_expression
="0.0f"),
272 operation("dFdy_coarse", 1, printable_name
="dFdyCoarse", source_types
=(float_type
,), c_expression
="0.0f"),
273 operation("dFdy_fine", 1, printable_name
="dFdyFine", source_types
=(float_type
,), c_expression
="0.0f"),
275 # Floating point pack and unpack operations.
276 operation("pack_snorm_2x16", 1, printable_name
="packSnorm2x16"),
277 operation("pack_snorm_4x8", 1, printable_name
="packSnorm4x8"),
278 operation("pack_unorm_2x16", 1, printable_name
="packUnorm2x16"),
279 operation("pack_unorm_4x8", 1, printable_name
="packUnorm4x8"),
280 operation("pack_half_2x16", 1, printable_name
="packHalf2x16"),
281 operation("unpack_snorm_2x16", 1, printable_name
="unpackSnorm2x16"),
282 operation("unpack_snorm_4x8", 1, printable_name
="unpackSnorm4x8"),
283 operation("unpack_unorm_2x16", 1, printable_name
="unpackUnorm2x16"),
284 operation("unpack_unorm_4x8", 1, printable_name
="unpackUnorm4x8"),
285 operation("unpack_half_2x16", 1, printable_name
="unpackHalf2x16"),
287 # Bit operations, part of ARB_gpu_shader5.
288 operation("bitfield_reverse", 1, source_types
=integer_types
, c_expression
="bitfield_reverse({src0})"),
289 operation("bit_count", 1),
290 operation("find_msb", 1),
291 operation("find_lsb", 1),
293 operation("saturate", 1, printable_name
="sat", source_types
=(float_type
,), c_expression
="CLAMP({src0}, 0.0f, 1.0f)"),
295 # Double packing, part of ARB_gpu_shader_fp64.
296 operation("pack_double_2x32", 1, printable_name
="packDouble2x32"),
297 operation("unpack_double_2x32", 1, printable_name
="unpackDouble2x32"),
299 operation("frexp_sig", 1),
300 operation("frexp_exp", 1),
302 operation("noise", 1),
304 operation("subroutine_to_int", 1),
306 # Interpolate fs input at centroid
308 # operand0 is the fs input.
309 operation("interpolate_at_centroid", 1),
311 # Ask the driver for the total size of a buffer block.
312 # operand0 is the ir_constant buffer block index in the linked shader.
313 operation("get_buffer_size", 1),
315 # Calculate length of an unsized array inside a buffer block.
316 # This opcode is going to be replaced in a lowering pass inside
319 # operand0 is the unsized array's ir_value for the calculation
321 operation("ssbo_unsized_array_length", 1),
323 # Vote among threads on the value of the boolean argument.
324 operation("vote_any", 1),
325 operation("vote_all", 1),
326 operation("vote_eq", 1),
328 operation("add", 2, printable_name
="+"),
329 operation("sub", 2, printable_name
="-"),
330 # "Floating-point or low 32-bit integer multiply."
331 operation("mul", 2, printable_name
="*"),
332 operation("imul_high", 2), # Calculates the high 32-bits of a 64-bit multiply.
333 operation("div", 2, printable_name
="/"),
335 # Returns the carry resulting from the addition of the two arguments.
336 operation("carry", 2),
338 # Returns the borrow resulting from the subtraction of the second argument
339 # from the first argument.
340 operation("borrow", 2),
342 # Either (vector % vector) or (vector % scalar)
343 operation("mod", 2, printable_name
="%"),
345 # Binary comparison operators which return a boolean vector.
346 # The type of both operands must be equal.
347 operation("less", 2, printable_name
="<"),
348 operation("greater", 2, printable_name
=">"),
349 operation("lequal", 2, printable_name
="<="),
350 operation("gequal", 2, printable_name
=">="),
351 operation("equal", 2, printable_name
="=="),
352 operation("nequal", 2, printable_name
="!="),
354 # Returns single boolean for whether all components of operands[0]
355 # equal the components of operands[1].
356 operation("all_equal", 2),
358 # Returns single boolean for whether any component of operands[0]
359 # is not equal to the corresponding component of operands[1].
360 operation("any_nequal", 2),
362 # Bit-wise binary operations.
363 operation("lshift", 2, printable_name
="<<"),
364 operation("rshift", 2, printable_name
=">>"),
365 operation("bit_and", 2, printable_name
="&"),
366 operation("bit_xor", 2, printable_name
="^"),
367 operation("bit_or", 2, printable_name
="|"),
369 operation("logic_and", 2, printable_name
="&&"),
370 operation("logic_xor", 2, printable_name
="^^"),
371 operation("logic_or", 2, printable_name
="||"),
379 # Load a value the size of a given GLSL type from a uniform block.
381 # operand0 is the ir_constant uniform block index in the linked shader.
382 # operand1 is a byte offset within the uniform block.
383 operation("ubo_load", 2),
385 # Multiplies a number by two to a power, part of ARB_gpu_shader5.
386 operation("ldexp", 2),
388 # Extract a scalar from a vector
390 # operand0 is the vector
391 # operand1 is the index of the field to read from operand0
392 operation("vector_extract", 2),
394 # Interpolate fs input at offset
396 # operand0 is the fs input
397 # operand1 is the offset from the pixel center
398 operation("interpolate_at_offset", 2),
400 # Interpolate fs input at sample position
402 # operand0 is the fs input
403 # operand1 is the sample ID
404 operation("interpolate_at_sample", 2),
406 # Fused floating-point multiply-add, part of ARB_gpu_shader5.
413 # A vector conditional select instruction (like ?:, but operating per-
414 # component on vectors).
416 # See also lower_instructions_visitor::ldexp_to_arith
417 operation("csel", 3),
419 operation("bitfield_extract", 3),
421 # Generate a value with one field of a vector changed
423 # operand0 is the vector
424 # operand1 is the value to write into the vector result
425 # operand2 is the index in operand0 to be modified
426 operation("vector_insert", 3),
428 operation("bitfield_insert", 4),
430 operation("vector", 4),
434 if __name__
== "__main__":
436 * Copyright (C) 2010 Intel Corporation
438 * Permission is hereby granted, free of charge, to any person obtaining a
439 * copy of this software and associated documentation files (the "Software"),
440 * to deal in the Software without restriction, including without limitation
441 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
442 * and/or sell copies of the Software, and to permit persons to whom the
443 * Software is furnished to do so, subject to the following conditions:
445 * The above copyright notice and this permission notice (including the next
446 * paragraph) shall be included in all copies or substantial portions of the
449 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
450 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
451 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
452 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
453 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
454 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
455 * DEALINGS IN THE SOFTWARE.
458 enum_template
= mako
.template
.Template(copyright
+ """
459 enum ir_expression_operation {
460 % for item in values:
461 ${item.get_enum_name()},
464 /* Sentinels marking the last of each kind of operation. */
466 ir_last_${("un", "bin", "tri", "quad")[item.num_operands - 1]}op = ${item.get_enum_name()},
468 ir_last_opcode = ir_quadop_${lasts[3].name}
471 strings_template
= mako
.template
.Template(copyright
+ """
472 const char *const ir_expression_operation_strings[] = {
473 % for item in values:
474 "${item.printable_name}",
478 constant_template
= mako
.template
.Template("""\
479 switch (this->operation) {
481 % if op.c_expression is not None:
487 /* FINISHME: Should handle all expression types. */
492 if sys
.argv
[1] == "enum":
493 lasts
= [None, None, None, None]
494 for item
in reversed(ir_expression_operation
):
495 i
= item
.num_operands
- 1
499 print(enum_template
.render(values
=ir_expression_operation
,
501 elif sys
.argv
[1] == "strings":
502 print(strings_template
.render(values
=ir_expression_operation
))
503 elif sys
.argv
[1] == "constant":
504 print(constant_template
.render(values
=ir_expression_operation
))