<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Mar 30, 2017 at 4:23 AM, Eduardo Lima Mitev <span dir="ltr"><<a href="mailto:elima@igalia.com" target="_blank">elima@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Looks good and clearer. Series is:<br>
<br>
Reviewed-by: Eduardo Lima Mitev <<a href="mailto:elima@igalia.com">elima@igalia.com</a>><br><div class="HOEnZb"><div class="h5"></div></div></blockquote><div><br></div><div>Thanks! I've pushed these two and the one for float16 support.<br></div><div> </div><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 03/14/2017 10:08 PM, Jason Ekstrand wrote:<br>
> ---<br>
> src/compiler/nir/nir_constant_<wbr>expressions.py | 199 ++++++++++++++-------------<br>
> 1 file changed, 101 insertions(+), 98 deletions(-)<br>
><br>
> diff --git a/src/compiler/nir/nir_<wbr>constant_expressions.py b/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> index c6745f1..ad841e3 100644<br>
> --- a/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> +++ b/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> @@ -266,116 +266,119 @@ struct bool32_vec {<br>
> bool w;<br>
> };<br>
><br>
> -% for name, op in sorted(opcodes.iteritems()):<br>
> -static nir_const_value<br>
> -evaluate_${name}(MAYBE_UNUSED unsigned num_components, unsigned bit_size,<br>
> - MAYBE_UNUSED nir_const_value *_src)<br>
> -{<br>
> - nir_const_value _dst_val = { {0, } };<br>
> -<br>
> - switch (bit_size) {<br>
> - % for bit_size in op_bit_sizes(op):<br>
> - case ${bit_size}: {<br>
> - <%<br>
> - output_type = type_add_size(op.output_type, bit_size)<br>
> - input_types = [type_add_size(type_, bit_size) for type_ in op.input_types]<br>
> - %><br>
> -<br>
> - ## For each non-per-component input, create a variable srcN that<br>
> - ## contains x, y, z, and w elements which are filled in with the<br>
> - ## appropriately-typed values.<br>
> - % for j in range(op.num_inputs):<br>
> - % if op.input_sizes[j] == 0:<br>
> - <% continue %><br>
> - % elif "src" + str(j) not in op.const_expr:<br>
> - ## Avoid unused variable warnings<br>
> - <% continue %><br>
> - %endif<br>
> -<br>
> - const struct ${input_types[j]}_vec src${j} = {<br>
> - % for k in range(op.input_sizes[j]):<br>
> - % if input_types[j] == "bool32":<br>
> - _src[${j}].u32[${k}] != 0,<br>
> - % else:<br>
> - _src[${j}].${get_const_field(<wbr>input_types[j])}[${k}],<br>
> - % endif<br>
> - % endfor<br>
> - % for k in range(op.input_sizes[j], 4):<br>
> - 0,<br>
> - % endfor<br>
> - };<br>
> +<%def name="evaluate_op(op, bit_size)"><br>
> + <%<br>
> + output_type = type_add_size(op.output_type, bit_size)<br>
> + input_types = [type_add_size(type_, bit_size) for type_ in op.input_types]<br>
> + %><br>
> +<br>
> + ## For each non-per-component input, create a variable srcN that<br>
> + ## contains x, y, z, and w elements which are filled in with the<br>
> + ## appropriately-typed values.<br>
> + % for j in range(op.num_inputs):<br>
> + % if op.input_sizes[j] == 0:<br>
> + <% continue %><br>
> + % elif "src" + str(j) not in op.const_expr:<br>
> + ## Avoid unused variable warnings<br>
> + <% continue %><br>
> + %endif<br>
> +<br>
> + const struct ${input_types[j]}_vec src${j} = {<br>
> + % for k in range(op.input_sizes[j]):<br>
> + % if input_types[j] == "bool32":<br>
> + _src[${j}].u32[${k}] != 0,<br>
> + % else:<br>
> + _src[${j}].${get_const_field(<wbr>input_types[j])}[${k}],<br>
> + % endif<br>
> % endfor<br>
> + % for k in range(op.input_sizes[j], 4):<br>
> + 0,<br>
> + % endfor<br>
> + };<br>
> + % endfor<br>
><br>
> - % if op.output_size == 0:<br>
> - ## For per-component instructions, we need to iterate over the<br>
> - ## components and apply the constant expression one component<br>
> - ## at a time.<br>
> - for (unsigned _i = 0; _i < num_components; _i++) {<br>
> - ## For each per-component input, create a variable srcN that<br>
> - ## contains the value of the current (_i'th) component.<br>
> - % for j in range(op.num_inputs):<br>
> - % if op.input_sizes[j] != 0:<br>
> - <% continue %><br>
> - % elif "src" + str(j) not in op.const_expr:<br>
> - ## Avoid unused variable warnings<br>
> - <% continue %><br>
> - % elif input_types[j] == "bool32":<br>
> - const bool src${j} = _src[${j}].u32[_i] != 0;<br>
> - % else:<br>
> - const ${input_types[j]}_t src${j} =<br>
> - _src[${j}].${get_const_field(<wbr>input_types[j])}[_i];<br>
> - % endif<br>
> - % endfor<br>
> -<br>
> - ## Create an appropriately-typed variable dst and assign the<br>
> - ## result of the const_expr to it. If const_expr already contains<br>
> - ## writes to dst, just include const_expr directly.<br>
> - % if "dst" in op.const_expr:<br>
> - ${output_type}_t dst;<br>
> -<br>
> - ${op.const_expr}<br>
> - % else:<br>
> - ${output_type}_t dst = ${op.const_expr};<br>
> - % endif<br>
> -<br>
> - ## Store the current component of the actual destination to the<br>
> - ## value of dst.<br>
> - % if output_type == "bool32":<br>
> - ## Sanitize the C value to a proper NIR bool<br>
> - _dst_val.u32[_i] = dst ? NIR_TRUE : NIR_FALSE;<br>
> + % if op.output_size == 0:<br>
> + ## For per-component instructions, we need to iterate over the<br>
> + ## components and apply the constant expression one component<br>
> + ## at a time.<br>
> + for (unsigned _i = 0; _i < num_components; _i++) {<br>
> + ## For each per-component input, create a variable srcN that<br>
> + ## contains the value of the current (_i'th) component.<br>
> + % for j in range(op.num_inputs):<br>
> + % if op.input_sizes[j] != 0:<br>
> + <% continue %><br>
> + % elif "src" + str(j) not in op.const_expr:<br>
> + ## Avoid unused variable warnings<br>
> + <% continue %><br>
> + % elif input_types[j] == "bool32":<br>
> + const bool src${j} = _src[${j}].u32[_i] != 0;<br>
> % else:<br>
> - _dst_val.${get_const_field(<wbr>output_type)}[_i] = dst;<br>
> + const ${input_types[j]}_t src${j} =<br>
> + _src[${j}].${get_const_field(<wbr>input_types[j])}[_i];<br>
> % endif<br>
> - }<br>
> - % else:<br>
> - ## In the non-per-component case, create a struct dst with<br>
> - ## appropriately-typed elements x, y, z, and w and assign the result<br>
> - ## of the const_expr to all components of dst, or include the<br>
> - ## const_expr directly if it writes to dst already.<br>
> - struct ${output_type}_vec dst;<br>
> + % endfor<br>
><br>
> + ## Create an appropriately-typed variable dst and assign the<br>
> + ## result of the const_expr to it. If const_expr already contains<br>
> + ## writes to dst, just include const_expr directly.<br>
> % if "dst" in op.const_expr:<br>
> + ${output_type}_t dst;<br>
> +<br>
> ${op.const_expr}<br>
> % else:<br>
> - ## Splat the value to all components. This way expressions which<br>
> - ## write the same value to all components don't need to explicitly<br>
> - ## write to dest. One such example is fnoise which has a<br>
> - ## const_expr of 0.0f.<br>
> - dst.x = dst.y = dst.z = dst.w = ${op.const_expr};<br>
> + ${output_type}_t dst = ${op.const_expr};<br>
> % endif<br>
><br>
> - ## For each component in the destination, copy the value of dst to<br>
> - ## the actual destination.<br>
> - % for k in range(op.output_size):<br>
> - % if output_type == "bool32":<br>
> - ## Sanitize the C value to a proper NIR bool<br>
> - _dst_val.u32[${k}] = dst.${"xyzw"[k]} ? NIR_TRUE : NIR_FALSE;<br>
> - % else:<br>
> - _dst_val.${get_const_field(<wbr>output_type)}[${k}] = dst.${"xyzw"[k]};<br>
> - % endif<br>
> - % endfor<br>
> + ## Store the current component of the actual destination to the<br>
> + ## value of dst.<br>
> + % if output_type == "bool32":<br>
> + ## Sanitize the C value to a proper NIR bool<br>
> + _dst_val.u32[_i] = dst ? NIR_TRUE : NIR_FALSE;<br>
> + % else:<br>
> + _dst_val.${get_const_field(<wbr>output_type)}[_i] = dst;<br>
> + % endif<br>
> + }<br>
> + % else:<br>
> + ## In the non-per-component case, create a struct dst with<br>
> + ## appropriately-typed elements x, y, z, and w and assign the result<br>
> + ## of the const_expr to all components of dst, or include the<br>
> + ## const_expr directly if it writes to dst already.<br>
> + struct ${output_type}_vec dst;<br>
> +<br>
> + % if "dst" in op.const_expr:<br>
> + ${op.const_expr}<br>
> + % else:<br>
> + ## Splat the value to all components. This way expressions which<br>
> + ## write the same value to all components don't need to explicitly<br>
> + ## write to dest. One such example is fnoise which has a<br>
> + ## const_expr of 0.0f.<br>
> + dst.x = dst.y = dst.z = dst.w = ${op.const_expr};<br>
> % endif<br>
><br>
> + ## For each component in the destination, copy the value of dst to<br>
> + ## the actual destination.<br>
> + % for k in range(op.output_size):<br>
> + % if output_type == "bool32":<br>
> + ## Sanitize the C value to a proper NIR bool<br>
> + _dst_val.u32[${k}] = dst.${"xyzw"[k]} ? NIR_TRUE : NIR_FALSE;<br>
> + % else:<br>
> + _dst_val.${get_const_field(<wbr>output_type)}[${k}] = dst.${"xyzw"[k]};<br>
> + % endif<br>
> + % endfor<br>
> + % endif<br>
> +</%def><br>
> +<br>
> +% for name, op in sorted(opcodes.iteritems()):<br>
> +static nir_const_value<br>
> +evaluate_${name}(MAYBE_UNUSED unsigned num_components, unsigned bit_size,<br>
> + MAYBE_UNUSED nir_const_value *_src)<br>
> +{<br>
> + nir_const_value _dst_val = { {0, } };<br>
> +<br>
> + switch (bit_size) {<br>
> + % for bit_size in op_bit_sizes(op):<br>
> + case ${bit_size}: {<br>
> + ${evaluate_op(op, bit_size)}<br>
> break;<br>
> }<br>
> % endfor<br>
><br>
<br>
</div></div></blockquote></div><br></div></div>