From: Ian Romanick <ian.d.roman...@intel.com> Signed-off-by: Ian Romanick <ian.d.roman...@intel.com> --- src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 22 +++++++++++++++++++++- src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 21 ++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index f8db28a..562b06d 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -1385,7 +1385,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); + nir_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 2fc2cf2..a25ccba 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -1530,7 +1530,26 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr) } case nir_op_find_lsb: - emit(FBL(dst, op[0])); + if (devinfo->gen < 7) { + src_reg temp = src_reg(this, glsl_type::ivec4_type); + + /* (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; + + emit(AND(dst_reg(temp), src, negated_src)); + nir_emit_find_msb_using_lzd(dst, temp, false); + } else { + emit(FBL(dst, op[0])); + } break; case nir_op_ubitfield_extract: -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev