From 10adf8fc858c21cd95b3e02a8d6abee563ca1046 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 7 Nov 2014 10:59:16 -0800 Subject: [PATCH] nir: Differentiate between signed and unsigned versions of find_msb We also make the return types match GLSL. The GLSL spec specifies that findMSB and findLSB return a signed integer. Previously, nir had them return unsigned. This updates nir's behavior to match what GLSL expects. We also update the nir-to-fs generator to take the new instructions. While we're at it, we fix the case where the input to findMSB is zero. Reviewed-by: Connor Abbott --- src/glsl/nir/glsl_to_nir.cpp | 22 +++++++++++++++++++--- src/glsl/nir/nir_opcodes.h | 5 +++-- src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 14 ++++++++------ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp index 40cb2448cf8..58721913f74 100644 --- a/src/glsl/nir/glsl_to_nir.cpp +++ b/src/glsl/nir/glsl_to_nir.cpp @@ -1123,9 +1123,25 @@ nir_visitor::visit(ir_expression *ir) case ir_unop_bitfield_reverse: emit(nir_op_bitfield_reverse, dest_size, srcs); break; - case ir_unop_bit_count: emit(nir_op_bit_count, dest_size, srcs); break; - case ir_unop_find_msb: emit(nir_op_find_msb, dest_size, srcs); break; - case ir_unop_find_lsb: emit(nir_op_find_lsb, dest_size, srcs); break; + case ir_unop_bit_count: + emit(nir_op_bit_count, dest_size, srcs); + break; + case ir_unop_find_msb: + switch (types[0]) { + case GLSL_TYPE_UINT: + emit(nir_op_ufind_msb, dest_size, srcs); + break; + case GLSL_TYPE_INT: + emit(nir_op_ifind_msb, dest_size, srcs); + break; + default: + unreachable("Invalid type for findMSB()"); + } + break; + case ir_unop_find_lsb: + emit(nir_op_find_lsb, dest_size, srcs); + break; + case ir_unop_noise: switch (ir->type->vector_elements) { case 1: diff --git a/src/glsl/nir/nir_opcodes.h b/src/glsl/nir/nir_opcodes.h index 9a7a2ab5c30..988f691f8d4 100644 --- a/src/glsl/nir/nir_opcodes.h +++ b/src/glsl/nir/nir_opcodes.h @@ -147,8 +147,9 @@ UNOP_HORIZ(unpack_half_2x16_split_y, 1, nir_type_float, 1, nir_type_unsigned) /*@{*/ UNOP(bitfield_reverse, nir_type_unsigned) UNOP(bit_count, nir_type_unsigned) -UNOP(find_msb, nir_type_unsigned) -UNOP(find_lsb, nir_type_unsigned) +UNOP_CONVERT(ufind_msb, nir_type_unsigned, nir_type_int) +UNOP(ifind_msb, nir_type_int) +UNOP(find_lsb, nir_type_int) /*@}*/ UNOP_HORIZ(fnoise1_1, 1, nir_type_float, 1, nir_type_float) diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index 8c6a5738f84..4dafe771aba 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -876,19 +876,21 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr) emit_percomp(CBIT(result, op[0]), instr->dest.write_mask); break; - case nir_op_find_msb: { - fs_reg temp = fs_reg(this, glsl_type::uvec4_type); - emit_percomp(FBH(temp, op[0]), instr->dest.write_mask); + case nir_op_ufind_msb: + case nir_op_ifind_msb: { + emit_percomp(FBH(retype(result, BRW_REGISTER_TYPE_UD), op[0]), + instr->dest.write_mask); /* FBH counts from the MSB side, while GLSL's findMSB() wants the count * from the LSB side. If FBH didn't return an error (0xFFFFFFFF), then * subtract the result from 31 to convert the MSB count into an LSB count. */ - emit_percomp(CMP(reg_null_d, temp, fs_reg(~0), BRW_CONDITIONAL_NZ), + emit_percomp(CMP(reg_null_d, result, fs_reg(-1), BRW_CONDITIONAL_NZ), instr->dest.write_mask); - temp.negate = true; - fs_inst *inst = ADD(result, temp, fs_reg(31)); + fs_reg neg_result(result); + neg_result.negate = true; + fs_inst *inst = ADD(result, neg_result, fs_reg(31)); inst->predicate = BRW_PREDICATE_NORMAL; emit_percomp(inst, instr->dest.write_mask); break; -- 2.30.2