nir/constant_expressions: Rework Boolean handling
This commit contains three related changes. First, we define boolN_t for N = 8, 16, and 64 and move the definition of boolN_vec to the loop with the other vec definitions. Second, there's no reason why we need the != 0 on the source because that happens implicitly when it's converted to bool. Third, for destinations, we use a signed integer type and just do -(int)bool_val which will give us the 0/-1 behavior we want and neatly scales to all bit widths. Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Tested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:

committed by
Jason Ekstrand

parent
80e8dfe9de
commit
2fe8708ffd
@@ -24,8 +24,8 @@ def op_bit_sizes(op):
|
|||||||
return sorted(list(sizes)) if sizes is not None else None
|
return sorted(list(sizes)) if sizes is not None else None
|
||||||
|
|
||||||
def get_const_field(type_):
|
def get_const_field(type_):
|
||||||
if type_ == "bool32":
|
if type_base_type(type_) == 'bool':
|
||||||
return "u32"
|
return 'i' + str(type_size(type_))
|
||||||
elif type_ == "float16":
|
elif type_ == "float16":
|
||||||
return "u16"
|
return "u16"
|
||||||
else:
|
else:
|
||||||
@@ -240,8 +240,11 @@ unpack_half_1x16(uint16_t u)
|
|||||||
typedef float float16_t;
|
typedef float float16_t;
|
||||||
typedef float float32_t;
|
typedef float float32_t;
|
||||||
typedef double float64_t;
|
typedef double float64_t;
|
||||||
|
typedef bool bool8_t;
|
||||||
|
typedef bool bool16_t;
|
||||||
typedef bool bool32_t;
|
typedef bool bool32_t;
|
||||||
% for type in ["float", "int", "uint"]:
|
typedef bool bool64_t;
|
||||||
|
% for type in ["float", "int", "uint", "bool"]:
|
||||||
% for width in type_sizes(type):
|
% for width in type_sizes(type):
|
||||||
struct ${type}${width}_vec {
|
struct ${type}${width}_vec {
|
||||||
${type}${width}_t x;
|
${type}${width}_t x;
|
||||||
@@ -252,13 +255,6 @@ struct ${type}${width}_vec {
|
|||||||
% endfor
|
% endfor
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
struct bool32_vec {
|
|
||||||
bool x;
|
|
||||||
bool y;
|
|
||||||
bool z;
|
|
||||||
bool w;
|
|
||||||
};
|
|
||||||
|
|
||||||
<%def name="evaluate_op(op, bit_size)">
|
<%def name="evaluate_op(op, bit_size)">
|
||||||
<%
|
<%
|
||||||
output_type = type_add_size(op.output_type, bit_size)
|
output_type = type_add_size(op.output_type, bit_size)
|
||||||
@@ -278,9 +274,7 @@ struct bool32_vec {
|
|||||||
|
|
||||||
const struct ${input_types[j]}_vec src${j} = {
|
const struct ${input_types[j]}_vec src${j} = {
|
||||||
% for k in range(op.input_sizes[j]):
|
% for k in range(op.input_sizes[j]):
|
||||||
% if input_types[j] == "bool32":
|
% if input_types[j] == "float16":
|
||||||
_src[${j}].u32[${k}] != 0,
|
|
||||||
% elif input_types[j] == "float16":
|
|
||||||
_mesa_half_to_float(_src[${j}].u16[${k}]),
|
_mesa_half_to_float(_src[${j}].u16[${k}]),
|
||||||
% else:
|
% else:
|
||||||
_src[${j}].${get_const_field(input_types[j])}[${k}],
|
_src[${j}].${get_const_field(input_types[j])}[${k}],
|
||||||
@@ -305,8 +299,6 @@ struct bool32_vec {
|
|||||||
% elif "src" + str(j) not in op.const_expr:
|
% elif "src" + str(j) not in op.const_expr:
|
||||||
## Avoid unused variable warnings
|
## Avoid unused variable warnings
|
||||||
<% continue %>
|
<% continue %>
|
||||||
% elif input_types[j] == "bool32":
|
|
||||||
const bool src${j} = _src[${j}].u32[_i] != 0;
|
|
||||||
% elif input_types[j] == "float16":
|
% elif input_types[j] == "float16":
|
||||||
const float src${j} =
|
const float src${j} =
|
||||||
_mesa_half_to_float(_src[${j}].u16[_i]);
|
_mesa_half_to_float(_src[${j}].u16[_i]);
|
||||||
@@ -329,9 +321,9 @@ struct bool32_vec {
|
|||||||
|
|
||||||
## Store the current component of the actual destination to the
|
## Store the current component of the actual destination to the
|
||||||
## value of dst.
|
## value of dst.
|
||||||
% if output_type == "bool32":
|
% if output_type.startswith("bool"):
|
||||||
## Sanitize the C value to a proper NIR bool
|
## Sanitize the C value to a proper NIR 0/-1 bool
|
||||||
_dst_val.u32[_i] = dst ? NIR_TRUE : NIR_FALSE;
|
_dst_val.${get_const_field(output_type)}[_i] = -(int)dst;
|
||||||
% elif output_type == "float16":
|
% elif output_type == "float16":
|
||||||
_dst_val.u16[_i] = _mesa_float_to_half(dst);
|
_dst_val.u16[_i] = _mesa_float_to_half(dst);
|
||||||
% else:
|
% else:
|
||||||
@@ -359,8 +351,8 @@ struct bool32_vec {
|
|||||||
## the actual destination.
|
## the actual destination.
|
||||||
% for k in range(op.output_size):
|
% for k in range(op.output_size):
|
||||||
% if output_type == "bool32":
|
% if output_type == "bool32":
|
||||||
## Sanitize the C value to a proper NIR bool
|
## Sanitize the C value to a proper NIR 0/-1 bool
|
||||||
_dst_val.u32[${k}] = dst.${"xyzw"[k]} ? NIR_TRUE : NIR_FALSE;
|
_dst_val.${get_const_field(output_type)}[${k}] = -(int)dst.${"xyzw"[k]};
|
||||||
% elif output_type == "float16":
|
% elif output_type == "float16":
|
||||||
_dst_val.u16[${k}] = _mesa_float_to_half(dst.${"xyzw"[k]});
|
_dst_val.u16[${k}] = _mesa_float_to_half(dst.${"xyzw"[k]});
|
||||||
% else:
|
% else:
|
||||||
|
Reference in New Issue
Block a user