[Mesa-dev] [PATCH 12/22] spirv/nir: implement DF conversions
Samuel Iglesias Gonsálvez
siglesias at igalia.com
Fri Dec 2 08:22:36 UTC 2016
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 at iga
> lia.com> wrote:
> > From: Samuel Iglesias Gonsálvez <siglesias at 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 <siglesias at 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 at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> >
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20161202/3e339650/attachment.sig>
More information about the mesa-dev
mailing list