On Thu, 2016-12-01 at 18:50 -0800, Jason Ekstrand wrote: > On Fri, Nov 25, 2016 at 12:52 AM, Juan A. Suarez Romero <jasuarez@iga > lia.com> wrote: > > From: Samuel Iglesias Gonsálvez <sigles...@igalia.com> > > > > SPIR-V does not have special opcodes for DF conversions. We need to > > identify > > them by checking the bit size of the operand and the result. > > > > Signed-off-by: Samuel Iglesias Gonsálvez <sigles...@igalia.com> > > --- > > src/compiler/spirv/spirv_to_nir.c | 29 ++++++++++++++++++++++----- > > -- > > src/compiler/spirv/vtn_alu.c | 37 > > +++++++++++++++++++++++++++---------- > > src/compiler/spirv/vtn_private.h | 3 ++- > > 3 files changed, 51 insertions(+), 18 deletions(-) > > > > diff --git a/src/compiler/spirv/spirv_to_nir.c > > b/src/compiler/spirv/spirv_to_nir.c > > index a13f72a..81c73da 100644 > > --- a/src/compiler/spirv/spirv_to_nir.c > > +++ b/src/compiler/spirv/spirv_to_nir.c > > @@ -1211,12 +1211,21 @@ vtn_handle_constant(struct vtn_builder *b, > > SpvOp opcode, > > > > default: { > > bool swap; > > - nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, > > &swap); > > - > > - unsigned num_components = glsl_get_vector_elements(val- > > >const_type); > > unsigned bit_size = > > glsl_get_bit_size(val->const_type); > > > > + bool is_double_dst = bit_size == 64; > > + bool is_double_src = is_double_dst; > > + /* We assume there is no double conversion here */ > > + assert(bit_size != 64 || > > + (opcode != SpvOpConvertFToU && opcode != > > SpvOpConvertFToS && > > + opcode != SpvOpConvertSToF && opcode != > > SpvOpConvertUToF && > > + opcode != SpvOpFConvert)); > > + nir_op op = > > + vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, > > + is_double_dst, > > is_double_src); > > + > > + unsigned num_components = glsl_get_vector_elements(val- > > >const_type); > > nir_const_value src[4]; > > assert(count <= 7); > > for (unsigned i = 0; i < count - 4; i++) { > > @@ -1224,16 +1233,22 @@ vtn_handle_constant(struct vtn_builder *b, > > SpvOp opcode, > > vtn_value(b, w[4 + i], vtn_value_type_constant)- > > >constant; > > > > unsigned j = swap ? 1 - i : i; > > - assert(bit_size == 32); > > for (unsigned k = 0; k < num_components; k++) > > - src[j].u32[k] = c->value.u[k]; > > + if (!is_double_src) > > + src[j].u32[k] = c->value.u[k]; > > + else > > + src[j].f64[k] = c->value.d[k]; > > } > > > > nir_const_value res = nir_eval_const_opcode(op, > > num_components, > > bit_size, > > src); > > > > - for (unsigned k = 0; k < num_components; k++) > > - val->constant->value.u[k] = res.u32[k]; > > + for (unsigned k = 0; k < num_components; k++) { > > + if (!is_double_dst) > > + val->constant->value.u[k] = res.u32[k]; > > + else > > + val->constant->value.d[k] = res.f64[k]; > > + } > > > > break; > > } /* default */ > > diff --git a/src/compiler/spirv/vtn_alu.c > > b/src/compiler/spirv/vtn_alu.c > > index 95ff2b1..e444d3f 100644 > > --- a/src/compiler/spirv/vtn_alu.c > > +++ b/src/compiler/spirv/vtn_alu.c > > @@ -211,7 +211,8 @@ vtn_handle_matrix_alu(struct vtn_builder *b, > > SpvOp opcode, > > } > > > > nir_op > > -vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap) > > +vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap, > > + bool is_double_dst, bool > > is_double_src) > > I think it would be better if we did this as dst_bit_size and > src_bit_size. That would make this simpler for basically every > caller. Also, it makes it more 8/16-bit ready. >
OK. > > { > > /* Indicates that the first two arguments should be swapped. > > This is > > * used for implementing greater-than and less-than-or-equal. > > @@ -284,16 +285,21 @@ vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, > > bool *swap) > > case SpvOpFUnordGreaterThanEqual: return > > nir_op_fge; > > > > /* Conversions: */ > > - case SpvOpConvertFToU: return nir_op_f2u; > > - case SpvOpConvertFToS: return nir_op_f2i; > > - case SpvOpConvertSToF: return nir_op_i2f; > > - case SpvOpConvertUToF: return nir_op_u2f; > > + case SpvOpConvertFToU: return is_double_src ? > > nir_op_d2u : nir_op_f2u; > > + case SpvOpConvertFToS: return is_double_src ? > > nir_op_d2i : nir_op_f2i; > > + case SpvOpConvertSToF: return is_double_dst ? > > nir_op_i2d : nir_op_i2f; > > + case SpvOpConvertUToF: return is_double_dst ? > > nir_op_u2d : nir_op_u2f; > > The time is soon coming (not sure if you want to do this now or not) > to add a nir helper: > > nir_op nir_type2type_op(nir_alu_type src, nir_alu_type dst); > > I'm OK open-coding it for now, but as soon as we add int64 or any 8 > or 16-bit types, we'll want it. > OK, I am going to do it now. Thanks, Sam > > case SpvOpBitcast: return nir_op_imov; > > case SpvOpUConvert: > > case SpvOpQuantizeToF16: return nir_op_fquantize2f16; > > - /* TODO: NIR is 32-bit only; these are no-ops. */ > > + /* TODO: int64 is not supported yet. This is a no-op. */ > > case SpvOpSConvert: return nir_op_imov; > > - case SpvOpFConvert: return nir_op_fmov; > > + case SpvOpFConvert: > > + if (is_double_src && !is_double_dst) > > + return nir_op_d2f; > > + if (!is_double_src && is_double_dst) > > + return nir_op_f2d; > > + return nir_op_fmov; > > > > /* Derivatives: */ > > case SpvOpDPdx: return nir_op_fddx; > > @@ -457,7 +463,10 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp > > opcode, > > case SpvOpFUnordLessThanEqual: > > case SpvOpFUnordGreaterThanEqual: { > > bool swap; > > - nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap); > > + bool is_double_src = src[0]->bit_size; > > + bool is_double_dst = glsl_get_bit_size(val->ssa->type); > > + nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, > > + is_double_dst, > > is_double_src); > > > > if (swap) { > > nir_ssa_def *tmp = src[0]; > > @@ -481,7 +490,10 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp > > opcode, > > case SpvOpFOrdLessThanEqual: > > case SpvOpFOrdGreaterThanEqual: { > > bool swap; > > - nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap); > > + bool is_double_src = src[0]->bit_size; > > + bool is_double_dst = glsl_get_bit_size(val->ssa->type); > > + nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, > > + is_double_dst, > > is_double_src); > > > > if (swap) { > > nir_ssa_def *tmp = src[0]; > > @@ -500,7 +512,12 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp > > opcode, > > > > default: { > > bool swap; > > - nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap); > > + bool is_double_src = src[0]->bit_size == 64; > > + bool is_double_dst = > > + glsl_get_bit_size(val->ssa->type) == 64; > > + > > + nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, > > + is_double_dst, > > is_double_src); > > > > if (swap) { > > nir_ssa_def *tmp = src[0]; > > diff --git a/src/compiler/spirv/vtn_private.h > > b/src/compiler/spirv/vtn_private.h > > index 47579fe..7159f8b 100644 > > --- a/src/compiler/spirv/vtn_private.h > > +++ b/src/compiler/spirv/vtn_private.h > > @@ -480,7 +480,8 @@ typedef void > > (*vtn_execution_mode_foreach_cb)(struct vtn_builder *, > > void vtn_foreach_execution_mode(struct vtn_builder *b, struct > > vtn_value *value, > > vtn_execution_mode_foreach_cb cb, > > void *data); > > > > -nir_op vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap); > > +nir_op vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap, > > + bool is_double_dst, bool > > is_double_src); > > > > void vtn_handle_alu(struct vtn_builder *b, SpvOp opcode, > > const uint32_t *w, unsigned count); > > -- > > 2.7.4 > > > > _______________________________________________ > > mesa-dev mailing list > > mesa-dev@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/mesa-dev > > > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
signature.asc
Description: This is a digitally signed message part
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev