<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Apr 30, 2018 at 7:18 AM, Iago Toral Quiroga <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">Not all bit-sizes may be supported natively in hardware for all operations.<br>
This pass allows drivers to lower such operations to a bit-size that is<br>
actually supported and then converts the result back to the original<br>
bit-size.<br>
<br>
Compiler backends control which operations and wich bit-sizes require<br>
the lowering through a callback function.<br>
<br>
v2: generalize this pass and make it available in NIR core (Rob, Jason)<br>
---<br>
src/compiler/Makefile.sources | 1 +<br>
src/compiler/nir/meson.build | 1 +<br>
src/compiler/nir/nir.h | 6 ++<br>
src/compiler/nir/nir_lower_<wbr>bit_size.c | 127 ++++++++++++++++++++++++++++++<wbr>++++<br>
4 files changed, 135 insertions(+)<br>
create mode 100644 src/compiler/nir/nir_lower_<wbr>bit_size.c<br>
<br>
diff --git a/src/compiler/Makefile.<wbr>sources b/src/compiler/Makefile.<wbr>sources<br>
index aca9dab476..b5321588be 100644<br>
--- a/src/compiler/Makefile.<wbr>sources<br>
+++ b/src/compiler/Makefile.<wbr>sources<br>
@@ -237,6 +237,7 @@ NIR_FILES = \<br>
nir/nir_lower_phis_to_scalar.c \<br>
nir/nir_lower_regs_to_ssa.c \<br>
nir/nir_lower_returns.c \<br>
+ nir/nir_lower_bit_size.c \<br>
nir/nir_lower_samplers.c \<br>
nir/nir_lower_samplers_as_<wbr>deref.c \<br>
nir/nir_lower_subgroups.c \<br>
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build<br>
index b28a565d0c..62fe5167d3 100644<br>
--- a/src/compiler/nir/meson.build<br>
+++ b/src/compiler/nir/meson.build<br>
@@ -144,6 +144,7 @@ files_libnir = files(<br>
'nir_lower_vec_to_movs.c',<br>
'nir_lower_wpos_center.c',<br>
'nir_lower_wpos_ytransform.c',<br>
+ 'nir_lower_bit_size.c',<br>
'nir_metadata.c',<br>
'nir_move_vec_src_uses_to_<wbr>dest.c',<br>
'nir_normalize_cubemap_coords.<wbr>c',<br>
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
index f3326e6df9..e7f2b145b3 100644<br>
--- a/src/compiler/nir/nir.h<br>
+++ b/src/compiler/nir/nir.h<br>
@@ -2763,6 +2763,12 @@ bool nir_lower_to_source_mods(nir_<wbr>shader *shader);<br>
<br>
bool nir_lower_gs_intrinsics(nir_<wbr>shader *shader);<br>
<br>
+typedef unsigned (*nir_lower_bit_size_callback)<wbr>(const nir_alu_instr *, void *);<br>
+<br>
+bool nir_lower_bit_size(nir_shader *shader,<br>
+ nir_lower_bit_size_callback callback,<br>
+ void *callback_data);<br>
+<br>
typedef enum {<br>
nir_lower_imul64 = (1 << 0),<br>
nir_lower_isign64 = (1 << 1),<br>
diff --git a/src/compiler/nir/nir_lower_<wbr>bit_size.c b/src/compiler/nir/nir_lower_<wbr>bit_size.c<br>
new file mode 100644<br>
index 0000000000..8e0fd663a1<br>
--- /dev/null<br>
+++ b/src/compiler/nir/nir_lower_<wbr>bit_size.c<br>
@@ -0,0 +1,127 @@<br>
+/*<br>
+ * Copyright © 2018 Intel Corporation<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
+ * IN THE SOFTWARE.<br>
+ */<br>
+<br>
+#include "nir_builder.h"<br>
+<br>
+/**<br>
+ * Some ALU operations may not be supported in hardware in specific bit-sizes.<br>
+ * This pass allows implementations to selectively lower such operations to<br>
+ * a bit-size that is supported natively and the converts the result back to<br>
+ * the original bit-size.<br>
+ */<br>
+static nir_ssa_def *<br>
+convert_to_bit_size(nir_<wbr>builder *bld,<br>
+ nir_ssa_def *src,<br>
+ nir_alu_type type,<br>
+ unsigned bit_size)<br>
+{<br>
+ nir_alu_type base_type = nir_alu_type_get_base_type(<wbr>type);<br>
+ nir_alu_type lowered_type = bit_size | base_type;<br>
+<br>
+ nir_op opcode =<br>
+ nir_type_conversion_op(type, lowered_type, nir_rounding_mode_undef);<br>
+<br>
+ return nir_build_alu(bld, opcode, src, NULL, NULL, NULL);<br>
+}<br>
+<br>
+static void<br>
+lower_instr(nir_builder *bld, nir_alu_instr *alu, unsigned bit_size)<br>
+{<br>
+ const nir_op op = alu->op;<br>
+<br>
+ bld->cursor = nir_before_instr(&alu->instr);<br>
+<br>
+ /* Convert each source to the requested bit-size */<br>
+ nir_ssa_def *srcs[4] = { NULL, NULL, NULL, NULL };<br>
+ const unsigned num_inputs = nir_op_infos[op].num_inputs;'<br></blockquote><div><br></div><div>I don't know that we need the num_inputs temporary<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
+ for (unsigned i = 0; i < num_inputs; i++) {<br>
+ nir_ssa_def *src = nir_ssa_for_alu_src(bld, alu, i);<br></div>
+<br><div>
+ nir_alu_type type = nir_op_infos[op].input_types[<wbr>i];<br>
+ unsigned type_size = nir_alu_type_get_type_size(<wbr>type);<br></div></blockquote><div><br></div><div>Again, I don't think this temporary is needed.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ if (type_size == 0)<br>
+ srcs[i] = convert_to_bit_size(bld, src, type, bit_size);<br>
+ else<br>
+ srcs[i] = src;<br>
+ }<br>
+<br>
+ /* Emit the lowered ALU instruction */<br>
+ nir_ssa_def *lowered_dst =<br>
+ nir_build_alu(bld, op, srcs[0], srcs[1], srcs[2], srcs[3]);<br>
+<br>
+ /* Convert result back to the original bit-size */<br>
+ unsigned dst_bit_size = alu->dest.dest.ssa.bit_size;<br>
+ nir_alu_type type = nir_op_infos[op].output_type;<br>
+ nir_ssa_def *dst = convert_to_bit_size(bld, lowered_dst, type, dst_bit_size);<br>
+ nir_ssa_def_rewrite_uses(&alu-<wbr>>dest.dest.ssa, nir_src_for_ssa(dst));<br>
+}<br>
+<br>
+static bool<br>
+lower_impl(nir_function_impl *impl,<br>
+ nir_lower_bit_size_callback callback,<br>
+ void *callback_data)<br>
+{<br>
+ nir_builder b;<br>
+ nir_builder_init(&b, impl);<br>
+ bool progress = false;<br>
+<br>
+ nir_foreach_block(block, impl) {<br>
+ nir_foreach_instr_safe(instr, block) {<br>
+ if (instr->type == nir_instr_type_alu) {<br></blockquote><div><br></div><div>I'd make this "if (!= alu) continue;" so we can keep the nesting depth down.<br><br></div><div>All my comments are fairly trivial so<br><br>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ nir_alu_instr *alu = nir_instr_as_alu(instr);<br>
+ assert(alu->dest.dest.is_ssa);<br>
+<br>
+ unsigned lower_bit_size = callback(alu, callback_data);<br>
+ if (lower_bit_size == 0)<br>
+ continue;<br>
+<br>
+ assert(lower_bit_size != alu->dest.dest.ssa.bit_size);<br>
+<br>
+ lower_instr(&b, alu, lower_bit_size);<br>
+ progress = true;<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+ if (progress) {<br>
+ nir_metadata_preserve(impl, nir_metadata_block_index |<br>
+ nir_metadata_dominance);<br>
+ }<br>
+<br>
+ return progress;<br>
+}<br>
+<br>
+bool<br>
+nir_lower_bit_size(nir_shader *shader,<br>
+ nir_lower_bit_size_callback callback,<br>
+ void *callback_data)<br>
+{<br>
+ bool progress = false;<br>
+<br>
+ nir_foreach_function(function, shader) {<br>
+ if (function->impl)<br>
+ progress |= lower_impl(function->impl, callback, callback_data);<br>
+ }<br>
+<br>
+ return progress;<br>
+}<br>
<span class="HOEnZb"><font color="#888888">-- <br>
2.14.1<br>
<br>
</font></span></blockquote></div><br></div></div>