On Fri, Nov 25, 2016 at 12:52 AM, Juan A. Suarez Romero <jasua...@igalia.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. > { > /* 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. > 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