summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Iglesias Gonsálvez <[email protected]>2016-12-07 08:34:42 +0100
committerSamuel Iglesias Gonsálvez <[email protected]>2017-01-09 09:10:13 +0100
commit27cf6a369fcec15a9f65837507f57dbd8bdfaaaa (patch)
treeb77a86495b85fe83f02bb7a9e9dd504f90738637
parent3a571fcc43e70731417f0b81cbce4b0a0c1be71d (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.c81
-rw-r--r--src/compiler/nir/nir.h2
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),