[Mesa-dev] [PATCH v2 17/24] i965: Use LZD to implement nir_op_find_lsb on Gen < 7
Ian Romanick
idr at freedesktop.org
Thu Jul 7 17:17:27 UTC 2016
From: Ian Romanick <ian.d.romanick at intel.com>
v2: Rebase on changes to previous two patches.
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 22 +++++++++++++++++++++-
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 26 ++++++++++++++++++++++++--
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 93d5e9d..fbbfd96 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -1389,7 +1389,27 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
case nir_op_find_lsb:
assert(nir_dest_bit_size(instr->dest.dest) < 64);
- bld.FBL(result, op[0]);
+
+ if (devinfo->gen < 7) {
+ fs_reg temp = vgrf(glsl_type::int_type);
+
+ /* (x & -x) generates a value that consists of only the LSB of x.
+ * For all powers of 2, findMSB(y) == findLSB(y).
+ */
+ fs_reg src = retype(op[0], BRW_REGISTER_TYPE_D);
+ fs_reg negated_src = src;
+
+ /* One must be negated, and the other must be non-negated. It
+ * doesn't matter which is which.
+ */
+ negated_src.negate = true;
+ src.negate = false;
+
+ bld.AND(temp, src, negated_src);
+ emit_find_msb_using_lzd(bld, result, temp, false);
+ } else {
+ bld.FBL(result, op[0]);
+ }
break;
case nir_op_ubitfield_extract:
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
index 85fa775..3b20508 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
@@ -1535,9 +1535,31 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
break;
}
- case nir_op_find_lsb:
- emit(FBL(dst, op[0]));
+ case nir_op_find_lsb: {
+ vec4_builder bld = vec4_builder(this).at_end();
+
+ if (devinfo->gen < 7) {
+ dst_reg temp = bld.vgrf(BRW_REGISTER_TYPE_D);
+
+ /* (x & -x) generates a value that consists of only the LSB of x.
+ * For all powers of 2, findMSB(y) == findLSB(y).
+ */
+ src_reg src = src_reg(retype(op[0], BRW_REGISTER_TYPE_D));
+ src_reg negated_src = src;
+
+ /* One must be negated, and the other must be non-negated. It
+ * doesn't matter which is which.
+ */
+ negated_src.negate = true;
+ src.negate = false;
+
+ bld.AND(temp, src, negated_src);
+ emit_find_msb_using_lzd(bld, dst, src_reg(temp), false);
+ } else {
+ bld.FBL(dst, op[0]);
+ }
break;
+ }
case nir_op_ubitfield_extract:
case nir_op_ibitfield_extract:
--
2.5.5
More information about the mesa-dev
mailing list