[Mesa-dev] [PATCH 4/6] nir/lower_tex: add lowering for texture gradient on shadow samplers

Kenneth Graunke kenneth at whitecape.org
Tue Dec 6 04:39:00 UTC 2016


On Thursday, December 1, 2016 8:53:19 AM PST Iago Toral Quiroga wrote:
> This is ported from the Intel lowering pass that we use with GLSL IR.
> This takes care of lowering texture gradients on shadow samplers other
> than cube maps. Intel hardware requires this for gen < 8.
> ---
>  src/compiler/nir/nir.h           |  7 +++++++
>  src/compiler/nir/nir_lower_tex.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 47 insertions(+)
> 
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> index ed388c6..d494d5f 100644
> --- a/src/compiler/nir/nir.h
> +++ b/src/compiler/nir/nir.h
> @@ -2437,6 +2437,13 @@ typedef struct nir_lower_tex_options {
>      * If true, lower nir_texop_txd on cube maps with nir_texop_txl.
>      */
>     bool lower_txd_cube_map;
> +
> +   /**
> +    * If true, lower nir_texop_txd on shadow samplers (except cube maps)
> +    * with nir_texop_txl. Notice that cube map shadow samplers are lowered
> +    * with lower_txd_cube_map.
> +    */
> +   bool lower_txd_shadow;
>  } nir_lower_tex_options;
>  
>  bool nir_lower_tex(nir_shader *shader,
> diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
> index c7c3db2..d5ea509 100644
> --- a/src/compiler/nir/nir_lower_tex.c
> +++ b/src/compiler/nir/nir_lower_tex.c
> @@ -556,6 +556,40 @@ lower_gradient_cube_map(nir_builder *b, nir_tex_instr *tex)
>  }
>  
>  static void
> +lower_gradient_shadow(nir_builder *b, nir_tex_instr *tex)
> +{
> +   assert(tex->sampler_dim != GLSL_SAMPLER_DIM_CUBE);
> +   assert(tex->is_shadow);
> +   assert(tex->op == nir_texop_txd);
> +   assert(tex->dest.is_ssa);
> +
> +   /* Use textureSize() to get the width and height of LOD 0 */
> +   nir_ssa_def *size = get_texture_size(b, tex);
> +
> +   /* Scale the gradients by width and height.  Effectively, the incoming
> +    * gradients are s'(x,y), t'(x,y), and r'(x,y) from equation 3.19 in the
> +    * GL 3.0 spec; we want u'(x,y), which is w_t * s'(x,y).
> +    */
> +   nir_ssa_def *dPdx = nir_fmul(b, tex->src[2].src.ssa, size);
> +   nir_ssa_def *dPdy = nir_fmul(b, tex->src[3].src.ssa, size);

NIR texture sources aren't guaranteed to be in any particular order
(it's kind of annoying)...you should instead do:

    nir_ssa_def *dPdx;
    nir_ssa_def *dPdy;

    for (unsigned i = 0; i < tex->num_srcs; i++) {
       switch (tex->src[i].src_type) {
       case nir_tex_src_ddx:
          dPdx = nir_fmul(b, tex->src[i].src.ssa, size);
          break;
       case nir_tex_src_ddy:
          dPdy = nir_fmul(b, tex->src[i].src.ssa, size);
          break;
       default:
          break;
       }
    }

Same comment on patch two.  Maybe make a get_ddx_ddy() helper?

> +
> +   nir_ssa_def *rho;
> +   if (dPdx->num_components == 1) {
> +      rho = nir_fmax(b, nir_fabs(b, dPdx), nir_fabs(b, dPdy));
> +   } else {
> +      rho = nir_fmax(b,
> +                     nir_fsqrt(b, nir_fdot(b, dPdx, dPdx)),
> +                     nir_fsqrt(b, nir_fdot(b, dPdy, dPdy)));
> +   }
> +
> +   /* lod = log2(rho).  We're ignoring GL state biases for now. */
> +   nir_ssa_def *lod = nir_flog2(b, rho);
> +
> +   /* Replace the gradient instruction with an equivalent lod instruction */
> +   replace_gradient_with_lod(b, lod, tex);
> +}
> +
> +static void
>  saturate_src(nir_builder *b, nir_tex_instr *tex, unsigned sat_mask)
>  {
>     b->cursor = nir_before_instr(&tex->instr);
> @@ -786,6 +820,12 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
>           lower_gradient_cube_map(b, tex);
>           progress = true;
>        }
> +
> +      if (tex->op == nir_texop_txd && options->lower_txd_shadow &&
> +          tex->is_shadow && tex->sampler_dim != GLSL_SAMPLER_DIM_CUBE) {
> +         lower_gradient_shadow(b, tex);
> +         progress = true;
> +      }

This seems a bit odd to me - if a driver sets options->lower_txd_shadow
but not options->lower_txd_cube_map, then textureGrad(samplerCubeShadow, ...)
would not be lowered.  I would sort of expect that case to be lowered if
either option is set.

I suppose it's not a problem in practice, as we set both, but it might
be nice to fix this anyway.

With the ddx/ddy source finding fixed in both patches, the series is:
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

>     }
>  
>     return progress;
> 

-------------- 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/20161205/90ce1e1d/attachment.sig>


More information about the mesa-dev mailing list