[Mesa-dev] [PATCH 07/16] nir/lower_tex: Add support for lowering coordinate offsets

Jason Ekstrand jason at jlekstrand.net
Fri Jul 22 14:57:29 UTC 2016


On Fri, Jul 22, 2016 at 1:11 AM, Pohjolainen, Topi <
topi.pohjolainen at intel.com> wrote:

> On Thu, Jul 21, 2016 at 09:21:53PM -0700, Jason Ekstrand wrote:
> > On i965, we can't support coordinate offsets for texelFetch or rectangle
> > textures.  Previously, we were doing this with a GLSL pass but we need to
> > do it in NIR if we want those workarounds for SPIR-V.
> >
> > Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> > Cc: "12.0" <mesa-dev at lists.freedesktop.org>
> > ---
> >  src/compiler/nir/nir.h           | 10 ++++++++
> >  src/compiler/nir/nir_lower_tex.c | 54
> ++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 64 insertions(+)
> >
> > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> > index d0f52b0..45f758c 100644
> > --- a/src/compiler/nir/nir.h
> > +++ b/src/compiler/nir/nir.h
> > @@ -2405,6 +2405,16 @@ typedef struct nir_lower_tex_options {
> >     unsigned lower_txp;
> >
> >     /**
> > +    * If true, lower away nir_tex_src_offset for all texelfetch
> instructions.
> > +    */
> > +   bool lower_txf_offset;
> > +
> > +   /**
> > +    * If true, lower away nir_tex_src_offset for all rect textures.
> > +    */
> > +   bool lower_rect_offset;
> > +
> > +   /**
> >      * If true, lower rect textures to 2D, using txs to fetch the
> >      * texture dimensions and dividing the texture coords by the
> >      * texture dims to normalize.
> > diff --git a/src/compiler/nir/nir_lower_tex.c
> b/src/compiler/nir/nir_lower_tex.c
> > index 0cf1071..a1280e1 100644
> > --- a/src/compiler/nir/nir_lower_tex.c
> > +++ b/src/compiler/nir/nir_lower_tex.c
> > @@ -128,6 +128,54 @@ project_src(nir_builder *b, nir_tex_instr *tex)
> >     tex_instr_remove_src(tex, proj_index);
> >  }
> >
> > +static bool
> > +lower_offset(nir_builder *b, nir_tex_instr *tex)
> > +{
> > +   int offset_index = tex_instr_find_src(tex, nir_tex_src_offset);
>
> Could be 'const'.
>
> > +   if (offset_index < 0)
> > +      return false;
> > +
> > +   int coord_index = tex_instr_find_src(tex, nir_tex_src_coord);
>
> Same here.
>
> > +   assert(coord_index >= 0);
> > +
> > +   assert(tex->src[offset_index].src.is_ssa);
> > +   assert(tex->src[coord_index].src.is_ssa);
> > +   nir_ssa_def *offset = tex->src[offset_index].src.ssa;
> > +   nir_ssa_def *coord = tex->src[coord_index].src.ssa;
>
> In principle, it looks these could be declared constants as well:
>
>       const nir_ssa_def * const offset = tex->src[offset_index].src.ssa;
>       const nir_ssa_def * const coord = tex->src[coord_index].src.ssa;
>
> But further digging tells me that they can be only:
>
>       nir_ssa_def * const offset = tex->src[offset_index].src.ssa;
>       nir_ssa_def * const coord = tex->src[coord_index].src.ssa;
>
>
> Quite a few of the helpers in nir declare their inputs as read-write even
> though they only read the contents...
>

I have tried on multiple occasions to make NIR more const-safe.
Unfortunately, every attempt only seems to lead to frustration.  Some of
this is due to limitations in C (which are fixed in C11 which we can't use)
that make it very hard to make constructs that can handle either const or
non-const.  This, in turn, makes it very hard to constify things.  There is
also the fact that we use a lot of embedded linked lists which make a bunch
of things that look like they should be const non-const.  I've given up.
It's better to not claim any sort of constness than to try and claim it and
have it all be lies.


>
> > +
> > +   b->cursor = nir_before_instr(&tex->instr);
> > +
> > +   nir_ssa_def *offset_coord;
> > +   if (nir_tex_instr_src_type(tex, coord_index) == nir_type_float) {
> > +      assert(tex->sampler_dim == GLSL_SAMPLER_DIM_RECT);
> > +      offset_coord = nir_fadd(b, coord, nir_i2f(b, offset));
> > +   } else {
> > +      offset_coord = nir_iadd(b, coord, offset);
> > +   }
> > +
> > +   if (tex->is_array) {
> > +      /* The offset is not applied to the array index */
> > +      if (tex->coord_components == 2) {
> > +         offset_coord = nir_vec2(b, nir_channel(b, offset_coord, 0),
> > +                                    nir_channel(b, coord, 1));
> > +      } else if (tex->coord_components == 3) {
> > +         offset_coord = nir_vec3(b, nir_channel(b, offset_coord, 0),
> > +                                    nir_channel(b, offset_coord, 1),
> > +                                    nir_channel(b, coord, 2));
> > +      } else {
> > +         unreachable("Invalid number of components");
> > +      }
> > +   }
> > +
> > +   nir_instr_rewrite_src(&tex->instr, &tex->src[coord_index].src,
> > +                         nir_src_for_ssa(offset_coord));
> > +
> > +   tex_instr_remove_src(tex, offset_index);
> > +
> > +   return true;
> > +}
> > +
> > +
> >  static nir_ssa_def *
> >  get_texture_size(nir_builder *b, nir_tex_instr *tex)
> >  {
> > @@ -458,6 +506,12 @@ nir_lower_tex_block(nir_block *block, nir_builder
> *b,
> >           progress = true;
> >        }
> >
> > +      if ((tex->op == nir_texop_txf && options->lower_txf_offset) ||
> > +          (tex->sampler_dim == GLSL_SAMPLER_DIM_RECT &&
> > +           options->lower_rect_offset)) {
> > +         progress = lower_offset(b, tex) || progress;
> > +      }
> > +
> >        if ((tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) &&
> options->lower_rect) {
> >           lower_rect(b, tex);
> >           progress = true;
> > --
> > 2.5.0.400.gff86faf
> >
> > _______________________________________________
> > mesa-dev mailing list
> > mesa-dev at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160722/96c47f75/attachment-0001.html>


More information about the mesa-dev mailing list