From 85faf5082f06ed5828c6d97bb11dd2292ad0f86a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 9 Jun 2016 09:58:40 +1000 Subject: [PATCH] glsl: Add 64-bit integer support for constant expressions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This just adds the new operations and add 64-bit integer support to all the existing cases where it is needed. v2: fix some issues found in testing. v2.1: add unreachable (Ian), add missing int/uint pack/unpack (Dave). v3 (idr): Rebase on top of idr's series to generate ir_expression_operation_constant.h. In addition, this version: Adds missing support for ir_unop_bit_not, ir_binop_all_equal, ir_binop_any_nequal, ir_binop_vector_extract, ir_triop_vector_insert, and ir_quadop_vector. Removes support for uint64_t from ir_unop_abs and ir_unop_sign. v4 (idr): "cut them down later" => Remove ir_unop_b2u64 and ir_unop_u642b. Handle these with extra i2u or u2i casts just like uint(bool) and bool(uint) conversion is done. Signed-off-by: Dave Airlie Signed-off-by: Ian Romanick Reviewed-by: Ian Romanick [v2] Reviewed-by: Matt Turner [v3] Reviewed-by: Nicolai Hähnle --- src/compiler/glsl/ir_constant_expression.cpp | 36 +++++++++ src/compiler/glsl/ir_expression_operation.py | 82 ++++++++++---------- 2 files changed, 77 insertions(+), 41 deletions(-) diff --git a/src/compiler/glsl/ir_constant_expression.cpp b/src/compiler/glsl/ir_constant_expression.cpp index 54b203aeec8..cd3cd1bb592 100644 --- a/src/compiler/glsl/ir_constant_expression.cpp +++ b/src/compiler/glsl/ir_constant_expression.cpp @@ -88,6 +88,42 @@ bitcast_f2u(float f) return u; } +static double +bitcast_u642d(uint64_t u) +{ + assert(sizeof(double) == sizeof(uint64_t)); + double d; + memcpy(&d, &u, sizeof(d)); + return d; +} + +static double +bitcast_i642d(int64_t i) +{ + assert(sizeof(double) == sizeof(int64_t)); + double d; + memcpy(&d, &i, sizeof(d)); + return d; +} + +static double +bitcast_d2u64(double d) +{ + assert(sizeof(double) == sizeof(uint64_t)); + uint64_t u; + memcpy(&u, &d, sizeof(d)); + return u; +} + +static double +bitcast_d2i64(double d) +{ + assert(sizeof(double) == sizeof(int64_t)); + int64_t i; + memcpy(&i, &d, sizeof(d)); + return i; +} + /** * Evaluate one component of a floating-point 4x8 unpacking function. */ diff --git a/src/compiler/glsl/ir_expression_operation.py b/src/compiler/glsl/ir_expression_operation.py index fbd8de8edaa..f91ac9b8226 100644 --- a/src/compiler/glsl/ir_expression_operation.py +++ b/src/compiler/glsl/ir_expression_operation.py @@ -86,10 +86,10 @@ float_type = type("float", "f", "GLSL_TYPE_FLOAT") double_type = type("double", "d", "GLSL_TYPE_DOUBLE") bool_type = type("bool", "b", "GLSL_TYPE_BOOL") -all_types = (uint_type, int_type, float_type, double_type, bool_type) -numeric_types = (uint_type, int_type, float_type, double_type) -signed_numeric_types = (int_type, float_type, double_type) -integer_types = (uint_type, int_type) +all_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type, bool_type) +numeric_types = (uint_type, int_type, float_type, double_type, uint64_type, int64_type) +signed_numeric_types = (int_type, float_type, double_type, int64_type) +integer_types = (uint_type, int_type, uint64_type, int64_type) real_types = (float_type, double_type) # This template is for operations that can have operands of a several @@ -420,8 +420,8 @@ ir_expression_operation = [ operation("bit_not", 1, printable_name="~", source_types=integer_types, c_expression="~ {src0}"), operation("logic_not", 1, printable_name="!", source_types=(bool_type,), c_expression="!{src0}"), operation("neg", 1, source_types=numeric_types, c_expression={'u': "-((int) {src0})", 'default': "-{src0}"}), - operation("abs", 1, source_types=signed_numeric_types, c_expression={'i': "{src0} < 0 ? -{src0} : {src0}", 'f': "fabsf({src0})", 'd': "fabs({src0})"}), - 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))"}), + operation("abs", 1, source_types=signed_numeric_types, c_expression={'i': "{src0} < 0 ? -{src0} : {src0}", 'f': "fabsf({src0})", 'd': "fabs({src0})", 'i64': "{src0} < 0 ? -{src0} : {src0}"}), + operation("sign", 1, source_types=signed_numeric_types, c_expression={'i': "({src0} > 0) - ({src0} < 0)", 'f': "float(({src0} > 0.0F) - ({src0} < 0.0F))", 'd': "double(({src0} > 0.0) - ({src0} < 0.0))", 'i64': "({src0} > 0) - ({src0} < 0)"}), 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"}), operation("rsq", 1, source_types=real_types, c_expression={'f': "1.0F / sqrtf({src0})", 'd': "1.0 / sqrt({src0})"}), operation("sqrt", 1, source_types=real_types, c_expression={'f': "sqrtf({src0})", 'd': "sqrt({src0})"}), @@ -441,7 +441,7 @@ ir_expression_operation = [ # Boolean-to-float conversion operation("b2f", 1, source_types=(bool_type,), dest_type=float_type, c_expression="{src0} ? 1.0F : 0.0F"), # int-to-boolean conversion - operation("i2b", 1, source_types=integer_types, dest_type=bool_type, c_expression="{src0} ? true : false"), + operation("i2b", 1, source_types=(uint_type, int_type), dest_type=bool_type, c_expression="{src0} ? true : false"), # Boolean-to-int conversion operation("b2i", 1, source_types=(bool_type,), dest_type=int_type, c_expression="{src0} ? 1 : 0"), # Unsigned-to-float conversion. @@ -473,35 +473,35 @@ ir_expression_operation = [ # 'Bit-identical float-to-uint "conversion" operation("bitcast_f2u", 1, source_types=(float_type,), dest_type=uint_type, c_expression="bitcast_f2u({src0})"), # Bit-identical u64-to-double "conversion" - operation("bitcast_u642d", 1, source_types=(uint64_type,), dest_type=double_type), + operation("bitcast_u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="bitcast_u642d({src0})"), # Bit-identical i64-to-double "conversion" - operation("bitcast_i642d", 1, source_types=(int64_type,), dest_type=double_type), + operation("bitcast_i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="bitcast_i642d({src0})"), # Bit-identical double-to_u64 "conversion" - operation("bitcast_d2u64", 1, source_types=(double_type,), dest_type=uint64_type), + operation("bitcast_d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="bitcast_d2u64({src0})"), # Bit-identical double-to-i64 "conversion" - operation("bitcast_d2i64", 1, source_types=(double_type,), dest_type=int64_type), + operation("bitcast_d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="bitcast_d2i64({src0})"), # i64-to-i32 conversion - operation("i642i", 1, source_types=(int64_type,), dest_type=int_type), + operation("i642i", 1, source_types=(int64_type,), dest_type=int_type, c_expression="{src0}"), # ui64-to-i32 conversion - operation("u642i", 1, source_types=(uint64_type,), dest_type=int_type), - operation("i642u", 1, source_types=(int64_type,), dest_type=uint_type), - operation("u642u", 1, source_types=(uint64_type,), dest_type=uint_type), - operation("i642b", 1, source_types=(int64_type,), dest_type=bool_type), - operation("i642f", 1, source_types=(int64_type,), dest_type=float_type), - operation("u642f", 1, source_types=(uint64_type,), dest_type=float_type), - operation("i642d", 1, source_types=(int64_type,), dest_type=double_type), - operation("u642d", 1, source_types=(uint64_type,), dest_type=double_type), - operation("i2i64", 1, source_types=(int_type,), dest_type=int64_type), - operation("u2i64", 1, source_types=(uint_type,), dest_type=int64_type), - operation("b2i64", 1, source_types=(bool_type,), dest_type=int64_type), - operation("f2i64", 1, source_types=(float_type,), dest_type=int64_type), - operation("d2i64", 1, source_types=(double_type,), dest_type=int64_type), - operation("i2u64", 1, source_types=(int_type,), dest_type=uint64_type), - operation("u2u64", 1, source_types=(uint_type,), dest_type=uint64_type), - operation("f2u64", 1, source_types=(float_type,), dest_type=uint64_type), - operation("d2u64", 1, source_types=(double_type,), dest_type=uint64_type), - operation("u642i64", 1, source_types=(uint_type,), dest_type=int64_type), - operation("i642u64", 1, source_types=(int_type,), dest_type=uint64_type), + operation("u642i", 1, source_types=(uint64_type,), dest_type=int_type, c_expression="{src0}"), + operation("i642u", 1, source_types=(int64_type,), dest_type=uint_type, c_expression="{src0}"), + operation("u642u", 1, source_types=(uint64_type,), dest_type=uint_type, c_expression="{src0}"), + operation("i642b", 1, source_types=(int64_type,), dest_type=bool_type, c_expression="{src0} != 0"), + operation("i642f", 1, source_types=(int64_type,), dest_type=float_type, c_expression="{src0}"), + operation("u642f", 1, source_types=(uint64_type,), dest_type=float_type, c_expression="{src0}"), + operation("i642d", 1, source_types=(int64_type,), dest_type=double_type, c_expression="{src0}"), + operation("u642d", 1, source_types=(uint64_type,), dest_type=double_type, c_expression="{src0}"), + operation("i2i64", 1, source_types=(int_type,), dest_type=int64_type, c_expression="{src0}"), + operation("u2i64", 1, source_types=(uint_type,), dest_type=int64_type, c_expression="{src0}"), + operation("b2i64", 1, source_types=(bool_type,), dest_type=int64_type, c_expression="{src0}"), + operation("f2i64", 1, source_types=(float_type,), dest_type=int64_type, c_expression="{src0}"), + operation("d2i64", 1, source_types=(double_type,), dest_type=int64_type, c_expression="{src0}"), + operation("i2u64", 1, source_types=(int_type,), dest_type=uint64_type, c_expression="{src0}"), + operation("u2u64", 1, source_types=(uint_type,), dest_type=uint64_type, c_expression="{src0}"), + operation("f2u64", 1, source_types=(float_type,), dest_type=uint64_type, c_expression="{src0}"), + operation("d2u64", 1, source_types=(double_type,), dest_type=uint64_type, c_expression="{src0}"), + operation("u642i64", 1, source_types=(uint64_type,), dest_type=int64_type, c_expression="{src0}"), + operation("i642u64", 1, source_types=(int64_type,), dest_type=uint64_type, c_expression="{src0}"), # Unary floating-point rounding operations. @@ -536,10 +536,10 @@ ir_expression_operation = [ 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))), # Bit operations, part of ARB_gpu_shader5. - operation("bitfield_reverse", 1, source_types=integer_types, c_expression="bitfield_reverse({src0})"), - operation("bit_count", 1, source_types=integer_types, dest_type=int_type, c_expression="_mesa_bitcount({src0})"), - operation("find_msb", 1, source_types=integer_types, dest_type=int_type, c_expression={'u': "find_msb_uint({src0})", 'i': "find_msb_int({src0})"}), - operation("find_lsb", 1, source_types=integer_types, dest_type=int_type, c_expression="find_msb_uint({src0} & -{src0})"), + operation("bitfield_reverse", 1, source_types=(uint_type, int_type), c_expression="bitfield_reverse({src0})"), + operation("bit_count", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="_mesa_bitcount({src0})"), + operation("find_msb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression={'u': "find_msb_uint({src0})", 'i': "find_msb_int({src0})"}), + operation("find_lsb", 1, source_types=(uint_type, int_type), dest_type=int_type, c_expression="find_msb_uint({src0} & -{src0})"), operation("saturate", 1, printable_name="sat", source_types=(float_type,), c_expression="CLAMP({src0}, 0.0f, 1.0f)"), @@ -577,17 +577,17 @@ ir_expression_operation = [ operation("vote_eq", 1), # 64-bit integer packing ops. - operation("pack_int_2x32", 1, printable_name="packInt2x32", source_types=(int_type,), dest_type=int64_type, flags=frozenset((horizontal_operation, non_assign_operation))), - operation("pack_uint_2x32", 1, printable_name="packUint2x32", source_types=(uint_type,), dest_type=uint64_type, flags=frozenset((horizontal_operation, non_assign_operation))), - operation("unpack_int_2x32", 1, printable_name="unpackInt2x32", source_types=(int64_type,), dest_type=int_type, flags=frozenset((horizontal_operation, non_assign_operation))), - operation("unpack_uint_2x32", 1, printable_name="unpackUint2x32", source_types=(uint64_type,), dest_type=uint_type, flags=frozenset((horizontal_operation, non_assign_operation))), + operation("pack_int_2x32", 1, printable_name="packInt2x32", source_types=(int_type,), dest_type=int64_type, c_expression="memcpy(&data.i64[0], &op[0]->value.i[0], sizeof(int64_t))", flags=frozenset((horizontal_operation, non_assign_operation))), + operation("pack_uint_2x32", 1, printable_name="packUint2x32", source_types=(uint_type,), dest_type=uint64_type, c_expression="memcpy(&data.u64[0], &op[0]->value.u[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))), + operation("unpack_int_2x32", 1, printable_name="unpackInt2x32", source_types=(int64_type,), dest_type=int_type, c_expression="memcpy(&data.i[0], &op[0]->value.i64[0], sizeof(int64_t))", flags=frozenset((horizontal_operation, non_assign_operation))), + operation("unpack_uint_2x32", 1, printable_name="unpackUint2x32", source_types=(uint64_type,), dest_type=uint_type, c_expression="memcpy(&data.u[0], &op[0]->value.u64[0], sizeof(uint64_t))", flags=frozenset((horizontal_operation, non_assign_operation))), operation("add", 2, printable_name="+", source_types=numeric_types, c_expression="{src0} + {src1}", flags=vector_scalar_operation), operation("sub", 2, printable_name="-", source_types=numeric_types, c_expression="{src0} - {src1}", flags=vector_scalar_operation), # "Floating-point or low 32-bit integer multiply." operation("mul", 2, printable_name="*", source_types=numeric_types, c_expression="{src0} * {src1}"), operation("imul_high", 2), # Calculates the high 32-bits of a 64-bit multiply. - 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), + operation("div", 2, printable_name="/", source_types=numeric_types, c_expression={'u': "{src1} == 0 ? 0 : {src0} / {src1}", 'i': "{src1} == 0 ? 0 : {src0} / {src1}", 'u64': "{src1} == 0 ? 0 : {src0} / {src1}", 'i64': "{src1} == 0 ? 0 : {src0} / {src1}", 'default': "{src0} / {src1}"}, flags=vector_scalar_operation), # Returns the carry resulting from the addition of the two arguments. operation("carry", 2), @@ -600,7 +600,7 @@ ir_expression_operation = [ # # We don't use fmod because it rounds toward zero; GLSL specifies the use # of floor. - 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), + operation("mod", 2, printable_name="%", source_types=numeric_types, c_expression={'u': "{src1} == 0 ? 0 : {src0} % {src1}", 'i': "{src1} == 0 ? 0 : {src0} % {src1}", 'f': "{src0} - {src1} * floorf({src0} / {src1})", 'd': "{src0} - {src1} * floor({src0} / {src1})", 'u64': "{src1} == 0 ? 0 : {src0} % {src1}", 'i64': "{src1} == 0 ? 0 : {src0} % {src1}"}, flags=vector_scalar_operation), # Binary comparison operators which return a boolean vector. # The type of both operands must be equal.