--- src/compiler/nir/nir_constant_expressions.h | 3 +- src/compiler/nir/nir_constant_expressions.py | 34 ++++++++++++++++---- src/compiler/nir/nir_loop_analyze.c | 7 ++-- src/compiler/nir/nir_opt_constant_folding.c | 5 +-- src/compiler/spirv/spirv_to_nir.c | 3 +- 5 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/src/compiler/nir/nir_constant_expressions.h b/src/compiler/nir/nir_constant_expressions.h index 1d6bbbc25d3..36e9869d5a8 100644 --- a/src/compiler/nir/nir_constant_expressions.h +++ b/src/compiler/nir/nir_constant_expressions.h @@ -31,6 +31,7 @@ #include "nir.h" nir_const_value nir_eval_const_opcode(nir_op op, unsigned num_components, - unsigned bit_size, nir_const_value *src); + unsigned bit_size, unsigned dest_bit_size, + nir_const_value *src); #endif /* NIR_CONSTANT_EXPRESSIONS_H */ diff --git a/src/compiler/nir/nir_constant_expressions.py b/src/compiler/nir/nir_constant_expressions.py index 0cd4ffcf558..ab1428ec1b7 100644 --- a/src/compiler/nir/nir_constant_expressions.py +++ b/src/compiler/nir/nir_constant_expressions.py @@ -10,6 +10,11 @@ def type_add_size(type_, size): return type_ + str(size) def op_bit_sizes(op): + if op.is_unsized_conversion: + assert len(op.input_types) == 1 + assert not type_has_size(op.input_types[0]) + return type_sizes(op.input_types[0]) + sizes = None if not type_has_size(op.output_type): sizes = set(type_sizes(op.output_type)) @@ -258,9 +263,9 @@ struct bool32_vec { bool w; }; -<%def name="evaluate_op(op, bit_size)"> +<%def name="evaluate_op(op, bit_size, dest_bit_size)"> <% - output_type = type_add_size(op.output_type, bit_size) + output_type = type_add_size(op.output_type, dest_bit_size) input_types = [type_add_size(type_, bit_size) for type_ in op.input_types] %> @@ -372,7 +377,8 @@ struct bool32_vec { % for name, op in sorted(opcodes.items()): static nir_const_value evaluate_${name}(MAYBE_UNUSED unsigned num_components, - ${"UNUSED" if op_bit_sizes(op) is None else ""} unsigned bit_size, + MAYBE_UNUSED unsigned bit_size, + MAYBE_UNUSED unsigned dest_bit_size, MAYBE_UNUSED nir_const_value *_src) { nir_const_value _dst_val = { {0, } }; @@ -381,7 +387,20 @@ evaluate_${name}(MAYBE_UNUSED unsigned num_components, switch (bit_size) { % for bit_size in op_bit_sizes(op): case ${bit_size}: { - ${evaluate_op(op, bit_size)} + % if op.is_unsized_conversion: + switch (dest_bit_size) { + % for dest_bit_size in type_sizes(op.output_type): + case ${dest_bit_size}: + ${evaluate_op(op, bit_size, dest_bit_size)} + break; + % endfor + + default: + unreachable("unknown bit width"); + } + % else: + ${evaluate_op(op, bit_size, bit_size)} + % endif break; } % endfor @@ -390,7 +409,7 @@ evaluate_${name}(MAYBE_UNUSED unsigned num_components, unreachable("unknown bit width"); } % else: - ${evaluate_op(op, 0)} + ${evaluate_op(op, 0, 0)} % endif return _dst_val; @@ -399,12 +418,13 @@ evaluate_${name}(MAYBE_UNUSED unsigned num_components, nir_const_value nir_eval_const_opcode(nir_op op, unsigned num_components, - unsigned bit_width, nir_const_value *src) + unsigned bit_size, unsigned dest_bit_size, + nir_const_value *src) { switch (op) { % for name in sorted(opcodes.keys()): case nir_op_${name}: - return evaluate_${name}(num_components, bit_width, src); + return evaluate_${name}(num_components, bit_size, dest_bit_size, src); % endfor default: unreachable("shouldn't get here"); diff --git a/src/compiler/nir/nir_loop_analyze.c b/src/compiler/nir/nir_loop_analyze.c index 9c3fd2f286f..7d9ad1b98ad 100644 --- a/src/compiler/nir/nir_loop_analyze.c +++ b/src/compiler/nir/nir_loop_analyze.c @@ -421,19 +421,20 @@ test_iterations(int32_t iter_int, nir_const_value *step, */ nir_const_value mul_src[2] = { iter_src, *step }; nir_const_value mul_result = - nir_eval_const_opcode(mul_op, 1, bit_size, mul_src); + nir_eval_const_opcode(mul_op, 1, bit_size, bit_size, mul_src); /* Add the initial value to the accumulated induction variable total */ nir_const_value add_src[2] = { mul_result, *initial }; nir_const_value add_result = - nir_eval_const_opcode(add_op, 1, bit_size, add_src); + nir_eval_const_opcode(add_op, 1, bit_size, bit_size, add_src); nir_const_value src[2] = { { {0, } }, { {0, } } }; src[limit_rhs ? 0 : 1] = add_result; src[limit_rhs ? 1 : 0] = *limit; /* Evaluate the loop exit condition */ - nir_const_value result = nir_eval_const_opcode(cond_op, 1, bit_size, src); + nir_const_value result = + nir_eval_const_opcode(cond_op, 1, bit_size, bit_size, src); return invert_cond ? (result.u32[0] == 0) : (result.u32[0] != 0); } diff --git a/src/compiler/nir/nir_opt_constant_folding.c b/src/compiler/nir/nir_opt_constant_folding.c index 5929a60aee8..d7e4140b44e 100644 --- a/src/compiler/nir/nir_opt_constant_folding.c +++ b/src/compiler/nir/nir_opt_constant_folding.c @@ -56,7 +56,8 @@ constant_fold_alu_instr(nir_alu_instr *instr, void *mem_ctx) * (although it still requires to receive a valid bit-size). */ unsigned bit_size = 0; - if (!nir_alu_type_get_type_size(nir_op_infos[instr->op].output_type)) + if (!nir_op_infos[instr->op].is_unsized_conversion && + !nir_alu_type_get_type_size(nir_op_infos[instr->op].output_type)) bit_size = instr->dest.dest.ssa.bit_size; for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) { @@ -106,7 +107,7 @@ constant_fold_alu_instr(nir_alu_instr *instr, void *mem_ctx) nir_const_value dest = nir_eval_const_opcode(instr->op, instr->dest.dest.ssa.num_components, - bit_size, src); + bit_size, instr->dest.dest.ssa.bit_size, src); nir_load_const_instr *new_instr = nir_load_const_instr_create(mem_ctx, diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 96ff09c3659..f682a19c8a8 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -1812,7 +1812,8 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode, } val->constant->values[0] = - nir_eval_const_opcode(op, num_components, bit_size, src); + nir_eval_const_opcode(op, num_components, bit_size, + glsl_get_bit_size(val->type->type), src); break; } /* default */ } -- 2.19.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev