<div dir="ltr">Sorry I haven't gotten back on this.  It got lost somehow.<br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 10, 2017 at 1:56 AM, Iago Toral <span dir="ltr"><<a href="mailto:itoral@igalia.com" target="_blank">itoral@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Thu, 2017-03-09 at 14:05 -0800, Jason Ekstrand wrote:<br>
> ---<br>
>  src/compiler/nir/nir.h       <wbr>                |  4 ++++<br>
>  src/compiler/nir/nir_<wbr>constant_expressions.py | 16 +++++++++++++++-<br>
>  src/compiler/nir/nir_opcodes.<wbr>py              |  6 +++++-<br>
>  3 files changed, 24 insertions(+), 2 deletions(-)<br>
><br>
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
> index 57b8be3..eaa103d 100644<br>
> --- a/src/compiler/nir/nir.h<br>
> +++ b/src/compiler/nir/nir.h<br>
> @@ -105,6 +105,10 @@ typedef enum {<br>
>  typedef union {<br>
>     float f32[4];<br>
>     double f64[4];<br>
> +   int8_t i8[4];<br>
> +   uint8_t u8[4];<br>
> +   int16_t i16[4];<br>
> +   uint16_t u16[4];<br>
>     int32_t i32[4];<br>
>     uint32_t u32[4];<br>
>     int64_t i64[4];<br>
> <br>
> diff --git a/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> b/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> index aecca8b..cbda4b1 100644<br>
> --- a/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> +++ b/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> @@ -14,8 +14,10 @@ def type_size(type_):<br>
>  def type_sizes(type_):<br>
>      if type_has_size(type_):<br>
>          return [type_size(type_)]<br>
> +    elif type_ == 'float':<br>
> +        return [16, 32, 64]<br>
>      else:<br>
> -        return [32, 64]<br>
> +        return [8, 16, 32, 64]<br>
>  <br>
>  def type_add_size(type_, size):<br>
>      if type_has_size(type_):<br>
> @@ -34,6 +36,8 @@ def op_bit_sizes(op):<br>
>  def get_const_field(type_):<br>
>      if type_ == "bool32":<br>
>          return "u32"<br>
> +    elif type_ == "float16":<br>
> +        return "u16"<br>
<br>
</div></div>I was wondering why not have a f16 field with type float16_t<br>
in nir_const_value instead,  but reading the rest of the patch it seems<br>
we really want to work with 32-bit floats and then encode results back to 16-bit values? Is it because there are some operations that we can't implement directly with half-floats?<span class="HOEnZb"><font color="#888888"><br></font></span></blockquote><div><br></div><div>Yes.  CPUs cannot, in general, work with 16-bit floats so there is no actual float16_t type in C.  We typedef float to float16_t below just because it makes the codegen easier.  In reality, all 16-bit operations have to be done in 32-bit with a manual conversion to/from 16-bit float on both sides.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888">
Iago<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
>      else:<br>
>          m = type_split_re.match(type_)<br>
>          if not m:<br>
> @@ -246,6 +250,7 @@ unpack_half_1x16(uint16_t u)<br>
>  }<br>
>  <br>
>  /* Some typed vector structures to make things like src0.y work */<br>
> +typedef float float16_t;<br>
>  typedef float float32_t;<br>
>  typedef double float64_t;<br>
>  typedef bool bool32_t;<br>
> @@ -297,6 +302,8 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
>           % for k in range(op.input_sizes[j]):<br>
>              % if input_types[j] == "bool32":<br>
>                 _src[${j}].<wbr>u32[${k}] != 0,<br>
> +            % elif input_types[j] == "float16":<br>
> +               _mesa_half_to_<wbr>float(_src[${j}].u16[${k}]),<br>
>              % else:<br>
>                 _src[${j}].${<wbr>get_const_field(input_types[j]<wbr>)}[${k}],<br>
>              % endif<br>
> @@ -322,6 +329,9 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
>                    <% continue %><br>
>                 % elif input_types[j] == "bool32":<br>
>                    const bool src${j} = _src[${j}].u32[_i] != 0;<br>
> +               % elif input_types[j] == "float16":<br>
> +                  const float src${j} =<br>
> +                     _mesa_<wbr>half_to_float(_src[${j}].u16[_<wbr>i]);<br>
>                 % else:<br>
>                    const ${input_types[j]}_t src${j} =<br>
>                       _src[${<wbr>j}].${get_const_field(input_<wbr>types[j])}[_<br>
> i];<br>
> @@ -344,6 +354,8 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
>              % if output_type == "bool32":<br>
>                 ## Sanitize the C value to a proper NIR bool<br>
>                 _dst_val.u32[_<wbr>i] = dst ? NIR_TRUE : NIR_FALSE;<br>
> +            % elif output_type == "float16":<br>
> +               _dst_val.u16[_<wbr>i] = _mesa_float_to_half(dst);<br>
>              % else:<br>
>                 _dst_val.${<wbr>get_const_field(output_type)}[<wbr>_i] = dst;<br>
>              % endif<br>
> @@ -371,6 +383,8 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
>              % if output_type == "bool32":<br>
>                 ## Sanitize the C value to a proper NIR bool<br>
>                 _dst_val.u32[$<wbr>{k}] = dst.${"xyzw"[k]} ? NIR_TRUE :<br>
> NIR_FALSE;<br>
> +            % elif output_type == "float16":<br>
> +               _dst_val.u16[$<wbr>{k}] =<br>
> _mesa_float_to_half(dst.${"<wbr>xyzw"[k]});<br>
>              % else:<br>
>                 _dst_val.${<wbr>get_const_field(output_type)}[<wbr>${k}] =<br>
> dst.${"xyzw"[k]};<br>
>              % endif<br>
> diff --git a/src/compiler/nir/nir_<wbr>opcodes.py<br>
> b/src/compiler/nir/nir_<wbr>opcodes.py<br>
> index 53e9aff..37c655b 100644<br>
> --- a/src/compiler/nir/nir_<wbr>opcodes.py<br>
> +++ b/src/compiler/nir/nir_<wbr>opcodes.py<br>
> @@ -175,7 +175,11 @@ for src_t in [tint, tuint, tfloat]:<br>
>        dst_types = [tint, tuint, tfloat]<br>
>  <br>
>     for dst_t in dst_types:<br>
> -      for bit_size in [32, 64]:<br>
> +      if dst_t == tfloat:<br>
> +         bit_sizes = [16, 32, 64]<br>
> +      else:<br>
> +         bit_sizes = [8, 16, 32, 64]<br>
> +      for bit_size in bit_sizes:<br>
>           unop_convert("{}2{}{<wbr>}".format(src_t[0], dst_t[0],<br>
> bit_size),<br>
>                        dst_t + str(bit_size), src_t, "src0")<br>
>  </div></div></blockquote></div><br></div></div>