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 <siglesias@igalia.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Samuel Iglesias Gonsálvez
2016-12-07 08:34:42 +01:00
parent 3a571fcc43
commit 27cf6a369f
2 changed files with 83 additions and 0 deletions

View File

@@ -1956,3 +1956,84 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin)
unreachable("intrinsic doesn't produce a system value"); 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");
};
}

View File

@@ -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 { typedef enum {
NIR_OP_IS_COMMUTATIVE = (1 << 0), NIR_OP_IS_COMMUTATIVE = (1 << 0),
NIR_OP_IS_ASSOCIATIVE = (1 << 1), NIR_OP_IS_ASSOCIATIVE = (1 << 1),