diff options
author | Samuel Iglesias Gonsálvez <[email protected]> | 2016-12-07 08:34:42 +0100 |
---|---|---|
committer | Samuel Iglesias Gonsálvez <[email protected]> | 2017-01-09 09:10:13 +0100 |
commit | 27cf6a369fcec15a9f65837507f57dbd8bdfaaaa (patch) | |
tree | b77a86495b85fe83f02bb7a9e9dd504f90738637 | |
parent | 3a571fcc43e70731417f0b81cbce4b0a0c1be71d (diff) |
nir: add nir_type_conversion_op()
This function returns the nir_op corresponding to the conversion between
the given nir_alu_type arguments.
This function lacks support for integer-based types with bit_size != 32
and for float16 conversion ops.
v2:
- Improve readiness of the code and delete cases that don't happen now (Jason)
Signed-off-by: Samuel Iglesias Gonsálvez <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r-- | src/compiler/nir/nir.c | 81 | ||||
-rw-r--r-- | src/compiler/nir/nir.h | 2 |
2 files changed, 83 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 1f6837a88dd..a2af3909464 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -1956,3 +1956,84 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin) unreachable("intrinsic doesn't produce a system value"); } } + +nir_op +nir_type_conversion_op(nir_alu_type src, nir_alu_type dst) +{ + nir_alu_type src_base_type = (nir_alu_type) nir_alu_type_get_base_type(src); + nir_alu_type dst_base_type = (nir_alu_type) nir_alu_type_get_base_type(dst); + unsigned src_bitsize = nir_alu_type_get_type_size(src); + unsigned dst_bitsize = nir_alu_type_get_type_size(dst); + + if (src_base_type == dst_base_type) { + if (src_bitsize == dst_bitsize) + return (src_base_type == nir_type_float) ? nir_op_fmov : nir_op_imov; + + assert (src_base_type == nir_type_float); + /* TODO: implement support for float16 */ + assert(src_bitsize == 64 || dst_bitsize == 64); + return (src_bitsize == 64) ? nir_op_d2f : nir_op_f2d; + } + + /* Different base type but same bit_size */ + if (src_bitsize == dst_bitsize) { + /* TODO: This does not include specific conversions between + * signed or unsigned integer types of bit size different than 32 yet. + */ + assert(src_bitsize == 32); + switch (src_base_type) { + case nir_type_uint: + return (dst_base_type == nir_type_float) ? nir_op_u2f : nir_op_imov; + case nir_type_int: + return (dst_base_type == nir_type_float) ? nir_op_i2f : nir_op_imov; + case nir_type_bool: + return (dst_base_type == nir_type_float) ? nir_op_b2f : nir_op_b2i; + case nir_type_float: + switch (dst_base_type) { + case nir_type_uint: + return nir_op_f2u; + case nir_type_bool: + return nir_op_f2b; + default: + return nir_op_f2i; + }; + default: + assert(!"Invalid conversion"); + }; + } + + /* Different bit_size and different base type */ + /* TODO: Implement integer support for types with bit_size != 32 */ + switch (src_base_type) { + case nir_type_uint: + assert(dst == nir_type_float64); + return nir_op_u2d; + case nir_type_int: + assert(dst == nir_type_float64); + return nir_op_i2d; + case nir_type_bool: + assert(dst == nir_type_float64); + return nir_op_u2d; + case nir_type_float: + assert(src_bitsize == 32 || src_bitsize == 64); + if (src_bitsize != 64) { + assert(dst == nir_type_float64); + return nir_op_f2d; + } + assert(dst_bitsize == 32); + switch (dst_base_type) { + case nir_type_uint: + return nir_op_d2u; + case nir_type_int: + return nir_op_d2i; + case nir_type_bool: + return nir_op_d2b; + case nir_type_float: + return nir_op_d2f; + default: + assert(!"Invalid conversion"); + }; + default: + assert(!"Invalid conversion"); + }; +} diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 654a26728ac..c9226e94dd2 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -699,6 +699,8 @@ nir_get_nir_type_for_glsl_type(const struct glsl_type *type) } } +nir_op nir_type_conversion_op(nir_alu_type src, nir_alu_type dst); + typedef enum { NIR_OP_IS_COMMUTATIVE = (1 << 0), NIR_OP_IS_ASSOCIATIVE = (1 << 1), |