[Mesa-dev] [PATCH 7/7] nir: add nir_ssa_for_alu_src()

Jason Ekstrand jason at jlekstrand.net
Fri Nov 6 15:20:55 PST 2015


On Fri, Nov 6, 2015 at 8:35 AM, Rob Clark <robdclark at gmail.com> wrote:
> From: Rob Clark <robclark at freedesktop.org>
>
> Using something like:
>
>    numer = nir_ssa_for_src(bld, alu->src[0].src,
>                            nir_ssa_alu_instr_src_components(alu, 0));
>
> for alu src's with swizzle, like:
>
>    vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
>    vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
>    vec2 ssa_2 = udiv ssa_10.xx, ssa_11
>
> ends up turning into something like:
>
>    vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
>    vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
>    vec2 ssa_13 = imov ssa_10
>    ...
>
> because nir_ssa_for_src() ignore's the original nir_alu_src's swizzle.
> Instead for alu instructions, nir_src_for_alu_src() should be used to
> ensure the original alu src's swizzle doesn't get lost in translation:
>
>    vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
>    vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
>    vec2 ssa_13 = imov ssa_10.xx
>    ...
>
> Signed-off-by: Rob Clark <robclark at freedesktop.org>
> ---
>  src/glsl/nir/nir_builder.h    | 25 +++++++++++++++++++++++++
>  src/glsl/nir/nir_lower_idiv.c |  6 ++----
>  2 files changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/src/glsl/nir/nir_builder.h b/src/glsl/nir/nir_builder.h
> index 624329d..8e57231 100644
> --- a/src/glsl/nir/nir_builder.h
> +++ b/src/glsl/nir/nir_builder.h
> @@ -259,6 +259,8 @@ nir_channel(nir_builder *b, nir_ssa_def *def, unsigned c)
>  /**
>   * Turns a nir_src into a nir_ssa_def * so it can be passed to
>   * nir_build_alu()-based builder calls.
> + *
> + * See nir_ssa_for_alu_src() for alu instructions.
>   */
>  static inline nir_ssa_def *
>  nir_ssa_for_src(nir_builder *build, nir_src src, int num_components)
> @@ -274,6 +276,29 @@ nir_ssa_for_src(nir_builder *build, nir_src src, int num_components)
>     return nir_imov_alu(build, alu, num_components);
>  }
>
> +/**
> + * Similar to nir_ssa_for_src(), but for alu src's, respecting the
> + * nir_alu_src's swizzle.
> + */
> +static inline nir_ssa_def *
> +nir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn)
> +{
> +   static uint8_t trivial_swizzle[4] = { 0, 1, 2, 3 };
> +   nir_alu_src *src = &instr->src[srcn];
> +   unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn);
> +
> +   if (src->src.is_ssa && (src->src.ssa->num_components == num_components) &&
> +       (memcmp(src->swizzle, trivial_swizzle, num_components) == 0))
> +      return src->src.ssa;

You should probably also check that abs and negate are false.

> +
> +   nir_alu_src alu = { NIR_SRC_INIT };
> +   alu.src = src->src;
> +   for (int j = 0; j < 4; j++)
> +      alu.swizzle[j] = src->swizzle[j];

I think you should be able to pass src directly into nir_imov_alu.

> +
> +   return nir_imov_alu(build, alu, num_components);
> +}
> +
>  static inline nir_ssa_def *
>  nir_load_var(nir_builder *build, nir_variable *var)
>  {
> diff --git a/src/glsl/nir/nir_lower_idiv.c b/src/glsl/nir/nir_lower_idiv.c
> index c961178..3b8af2c 100644
> --- a/src/glsl/nir/nir_lower_idiv.c
> +++ b/src/glsl/nir/nir_lower_idiv.c
> @@ -52,10 +52,8 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu)
>
>     bld->cursor = nir_before_instr(&alu->instr);
>
> -   numer = nir_ssa_for_src(bld, alu->src[0].src,
> -                           nir_ssa_alu_instr_src_components(alu, 0));
> -   denom = nir_ssa_for_src(bld, alu->src[1].src,
> -                           nir_ssa_alu_instr_src_components(alu, 1));
> +   numer = nir_ssa_for_alu_src(bld, alu, 0);
> +   denom = nir_ssa_for_alu_src(bld, alu, 1);
>
>     if (is_signed) {
>        af = nir_i2f(bld, numer);
> --
> 2.5.0
>


More information about the mesa-dev mailing list