[Mesa-dev] [PATCH] tgsi: add texel offsets and derivatives to sampler interface

Brian Paul brianp at vmware.com
Fri Mar 1 10:54:18 PST 2013


Looks good, just minor things below.

Reviewed-by: Brian Paul <brianp at vmware.com>

On 03/01/2013 11:41 AM, sroland at vmware.com wrote:
> From: Roland Scheidegger<sroland at vmware.com>
>
> Something I never got around to implement, but this is the tgsi execution
> side for implementing texel offsets (for ordinary texturing) and explicit
> derivatives for sampling (though I guess the ordering of the components
> for the derivs parameters is debatable).
> There is certainly a runtime cost associated with this.
> Unless there are different interfaces used depending on the "complexity"
> of the texture instructions, this is impossible to avoid.
> Offsets are always active (I think checking if they are active or not is
> probably not worth it since it should mostly be an add), whereas the
> sampler_control is extended for explicit derivatives.
> For now softpipe (the only user of this) just drops all those new values
> on the floor (which is the part I never implemented...).
>
> Additionally this also fixes (discovered by accident) inconsistent
> projective divide for the comparison coord - the code did do the
> projection for shadow2d targets, but not shadow1d ones. This also
> drops checking for projection modifier on array targets, since they
> aren't possible in any extension I know of (hence we don't actually
> know if the array layer should also be divided or not).
> ---
>   src/gallium/auxiliary/tgsi/tgsi_exec.c       |  255 ++++++++++++++++++++------
>   src/gallium/auxiliary/tgsi/tgsi_exec.h       |   10 +-
>   src/gallium/drivers/softpipe/sp_tex_sample.c |   10 +-
>   3 files changed, 210 insertions(+), 65 deletions(-)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> index 6277c3e..feb5928 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> @@ -1720,6 +1720,8 @@ fetch_texel( struct tgsi_sampler *sampler,
>                const union tgsi_exec_channel *p,
>                const union tgsi_exec_channel *c0,
>                const union tgsi_exec_channel *c1,
> +             float derivs[3][2][TGSI_QUAD_SIZE],
> +             const int8_t offset[3],
>                enum tgsi_sampler_control control,
>                union tgsi_exec_channel *r,
>                union tgsi_exec_channel *g,
> @@ -1731,7 +1733,7 @@ fetch_texel( struct tgsi_sampler *sampler,
>
>      /* FIXME: handle explicit derivs, offsets */
>      sampler->get_samples(sampler, sview_idx, sampler_idx,
> -                        s->f, t->f, p->f, c0->f, c1->f, control, rgba);
> +                        s->f, t->f, p->f, c0->f, c1->f, derivs, offset, control, rgba);
>
>      for (j = 0; j<  4; j++) {
>         r->f[j] = rgba[0][j];
> @@ -1765,6 +1767,23 @@ exec_tex(struct tgsi_exec_machine *mach,
>      const union tgsi_exec_channel *lod =&ZeroVec;
>      enum tgsi_sampler_control control =  tgsi_sampler_lod_none;
>      uint chan;
> +   int8_t offsets[3];
> +
> +   if (inst->Texture.NumOffsets == 1) {
> +      union tgsi_exec_channel index;
> +      union tgsi_exec_channel offset[3];
> +      index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> +     offsets[0] = offset[0].i[0];
> +     offsets[1] = offset[1].i[0];
> +     offsets[2] = offset[2].i[0];
> +   } else

assert(inst->Texture.NumOffsets == 0) here just to be safe?


> +     offsets[0] = offsets[1] = offsets[2] = 0;
>
>      assert(modifier != TEX_MODIFIER_LEVEL_ZERO);
>
> @@ -1791,25 +1810,41 @@ exec_tex(struct tgsi_exec_machine *mach,
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&ZeroVec,&ZeroVec,&ZeroVec, lod, /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);     /* R, G, B, A */
>         break;
> +
>      case TGSI_TEXTURE_SHADOW1D:
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>         FETCH(&r[2], 0, TGSI_CHAN_Z);
>
>         if (modifier == TEX_MODIFIER_PROJECTED) {
>            micro_div(&r[0],&r[0],&r[3]);
> +         micro_div(&r[2],&r[2],&r[3]);
>         }
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&ZeroVec,&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);     /* R, G, B, A */
>         break;
>
>      case TGSI_TEXTURE_2D:
>      case TGSI_TEXTURE_RECT:
> +      FETCH(&r[0], 0, TGSI_CHAN_X);
> +      FETCH(&r[1], 0, TGSI_CHAN_Y);
> +
> +      if (modifier == TEX_MODIFIER_PROJECTED) {
> +         micro_div(&r[0],&r[0],&r[3]);
> +         micro_div(&r[1],&r[1],&r[3]);
> +      }
> +
> +      fetch_texel(mach->Sampler, unit, unit,
> +&r[0],&r[1],&ZeroVec,&ZeroVec, lod,    /* S, T, P, C, LOD */
> +                  NULL, offsets, control,
> +&r[0],&r[1],&r[2],&r[3]);  /* outputs */
> +      break;
> +
>      case TGSI_TEXTURE_SHADOW2D:
>      case TGSI_TEXTURE_SHADOWRECT:
>         FETCH(&r[0], 0, TGSI_CHAN_X);
> @@ -1824,7 +1859,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&r[2],&ZeroVec, lod,    /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         break;
>
> @@ -1832,13 +1867,11 @@ exec_tex(struct tgsi_exec_machine *mach,
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
>
> -      if (modifier == TEX_MODIFIER_PROJECTED) {
> -         micro_div(&r[0],&r[0],&r[3]);
> -      }
> +      assert(modifier != TEX_MODIFIER_PROJECTED);
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&ZeroVec,&ZeroVec, lod,   /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         break;
>      case TGSI_TEXTURE_SHADOW1D_ARRAY:
> @@ -1846,13 +1879,11 @@ exec_tex(struct tgsi_exec_machine *mach,
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
>         FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> -      if (modifier == TEX_MODIFIER_PROJECTED) {
> -         micro_div(&r[0],&r[0],&r[3]);
> -      }
> +      assert(modifier != TEX_MODIFIER_PROJECTED);
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&r[2],&ZeroVec, lod,   /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         break;
>
> @@ -1861,14 +1892,11 @@ exec_tex(struct tgsi_exec_machine *mach,
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
>         FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> -      if (modifier == TEX_MODIFIER_PROJECTED) {
> -         micro_div(&r[0],&r[0],&r[3]);
> -         micro_div(&r[1],&r[1],&r[3]);
> -      }
> +      assert(modifier != TEX_MODIFIER_PROJECTED);
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&r[2],&ZeroVec, lod,   /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         break;
>      case TGSI_TEXTURE_SHADOW2D_ARRAY:
> @@ -1880,7 +1908,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&r[2],&r[3],&ZeroVec,    /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         break;
>      case TGSI_TEXTURE_CUBE_ARRAY:
> @@ -1897,7 +1925,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&r[2],&r[3],&cubelod,    /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         break;
>      case TGSI_TEXTURE_3D:
> @@ -1914,7 +1942,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&r[2],&ZeroVec, lod,
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);
>         break;
>
> @@ -1928,7 +1956,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&r[1],&r[2],&r[3],&cubearraycomp, /* S, T, P, C, LOD */
> -                  control,
> +                  NULL, offsets, control,
>                     &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         break;
>      default:
> @@ -1953,72 +1981,132 @@ exec_tex(struct tgsi_exec_machine *mach,
>      }
>   }
>
> +

Maybe put a comment on this function to explain it:

> +static void
> +fetch_assign_deriv_channel(struct tgsi_exec_machine *mach,
> +                           const struct tgsi_full_instruction *inst,
> +                           unsigned regdsrcx,
> +                           unsigned chan,
> +                           float derivs[2][TGSI_QUAD_SIZE])
> +{
> +   union tgsi_exec_channel d;
> +   FETCH(&d, regdsrcx, chan);
> +   derivs[0][0] = d.f[0];
> +   derivs[0][1] = d.f[1];
> +   derivs[0][2] = d.f[2];
> +   derivs[0][3] = d.f[3];
> +   FETCH(&d, regdsrcx + 1, chan);
> +   derivs[1][0] = d.f[0];
> +   derivs[1][1] = d.f[1];
> +   derivs[1][2] = d.f[2];
> +   derivs[1][3] = d.f[3];
> +}
> +
>   static void
>   exec_txd(struct tgsi_exec_machine *mach,
>            const struct tgsi_full_instruction *inst)
>   {
>      const uint unit = inst->Src[3].Register.Index;
>      union tgsi_exec_channel r[4];
> +   float derivs[3][2][TGSI_QUAD_SIZE];
>      uint chan;
> +   int8_t offsets[3];
>
> -   /*
> -    * XXX: This is fake TXD -- the derivatives are not taken into account, yet.
> -    */
> +   if (inst->Texture.NumOffsets == 1) {
> +      union tgsi_exec_channel index;
> +      union tgsi_exec_channel offset[3];
> +      index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> +     offsets[0] = offset[0].i[0];
> +     offsets[1] = offset[1].i[0];
> +     offsets[2] = offset[2].i[0];
> +   } else
> +     offsets[0] = offsets[1] = offsets[2] = 0;
>
>      switch (inst->Texture.Texture) {
>      case TGSI_TEXTURE_1D:
> -   case TGSI_TEXTURE_SHADOW1D:
> -
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> +
>         fetch_texel(mach->Sampler, unit, unit,
>                     &r[0],&ZeroVec,&ZeroVec,&ZeroVec,&ZeroVec,   /* S, T, P, C, LOD */
> -                  tgsi_sampler_lod_none,
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
>                     &r[0],&r[1],&r[2],&r[3]);           /* R, G, B, A */
>         break;
>
> +   case TGSI_TEXTURE_SHADOW1D:
>      case TGSI_TEXTURE_1D_ARRAY:
> -   case TGSI_TEXTURE_2D:
> -   case TGSI_TEXTURE_RECT:
>      case TGSI_TEXTURE_SHADOW1D_ARRAY:
> -   case TGSI_TEXTURE_SHADOW2D:
> -   case TGSI_TEXTURE_SHADOWRECT:
> -
> +      /* SHADOW1D/1D_ARRAY would not need Y/Z respectively, but don't bother */
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
>         FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> +
>         fetch_texel(mach->Sampler, unit, unit,
> -&r[0],&r[1],&r[2],&ZeroVec,&ZeroVec,   /* inputs */
> -                  tgsi_sampler_lod_none,
> -&r[0],&r[1],&r[2],&r[3]);     /* outputs */
> +&r[0],&r[1],&r[2],&ZeroVec,&ZeroVec,   /* S, T, P, C, LOD */
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]);           /* R, G, B, A */
>         break;
>
> -   case TGSI_TEXTURE_2D_ARRAY:
> -   case TGSI_TEXTURE_3D:
> -   case TGSI_TEXTURE_CUBE:
> -   case TGSI_TEXTURE_CUBE_ARRAY:
> +   case TGSI_TEXTURE_2D:
> +   case TGSI_TEXTURE_RECT:
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
> -      FETCH(&r[2], 0, TGSI_CHAN_Z);
> +
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
>
>         fetch_texel(mach->Sampler, unit, unit,
> -&r[0],&r[1],&r[2],&ZeroVec,&ZeroVec,
> -                  tgsi_sampler_lod_none,
> -&r[0],&r[1],&r[2],&r[3]);
> +&r[0],&r[1],&ZeroVec,&ZeroVec,&ZeroVec,   /* S, T, P, C, LOD */
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]);           /* R, G, B, A */
>         break;
>
> +
> +   case TGSI_TEXTURE_SHADOW2D:
> +   case TGSI_TEXTURE_SHADOWRECT:
> +   case TGSI_TEXTURE_2D_ARRAY:
>      case TGSI_TEXTURE_SHADOW2D_ARRAY:
> +      /* only SHADOW2D_ARRAY actually needs W */
> +      FETCH(&r[0], 0, TGSI_CHAN_X);
> +      FETCH(&r[1], 0, TGSI_CHAN_Y);
> +      FETCH(&r[2], 0, TGSI_CHAN_Z);
> +      FETCH(&r[3], 0, TGSI_CHAN_W);
>
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
> +
> +      fetch_texel(mach->Sampler, unit, unit,
> +&r[0],&r[1],&r[2],&r[3],&ZeroVec,   /* inputs */
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]);     /* outputs */
> +      break;
> +
> +   case TGSI_TEXTURE_3D:
> +   case TGSI_TEXTURE_CUBE:
> +   case TGSI_TEXTURE_CUBE_ARRAY:
> +      /* only TEXTURE_CUBE_ARRAY actually needs W */
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
>         FETCH(&r[2], 0, TGSI_CHAN_Z);
>         FETCH(&r[3], 0, TGSI_CHAN_W);
>
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
> +      fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Z, derivs[2]);
> +
>         fetch_texel(mach->Sampler, unit, unit,
> -&r[0],&r[1],&r[2],&r[3],&ZeroVec,
> -                  tgsi_sampler_lod_none,
> -&r[0],&r[1],&r[2],&r[3]);
> +&r[0],&r[1],&r[2],&r[3],&ZeroVec,   /* inputs */
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]);     /* outputs */
>         break;
>
>      default:
> @@ -2142,6 +2230,23 @@ exec_sample(struct tgsi_exec_machine *mach,
>      const union tgsi_exec_channel *lod =&ZeroVec;
>      enum tgsi_sampler_control control = tgsi_sampler_lod_none;
>      uint chan;
> +   int8_t offsets[3];
> +
> +   if (inst->Texture.NumOffsets == 1) {
> +      union tgsi_exec_channel index;
> +      union tgsi_exec_channel offset[3];
> +      index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> +     offsets[0] = offset[0].i[0];
> +     offsets[1] = offset[1].i[0];
> +     offsets[2] = offset[2].i[0];
> +   } else
> +     offsets[0] = offsets[1] = offsets[2] = 0;
>
>      assert(modifier != TEX_MODIFIER_PROJECTED);
>
> @@ -2170,13 +2275,13 @@ exec_sample(struct tgsi_exec_machine *mach,
>            FETCH(&r[2], 3, TGSI_CHAN_X);
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&ZeroVec,&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);     /* R, G, B, A */
>         }
>         else {
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&ZeroVec,&ZeroVec,&ZeroVec, lod, /* S, T, P, C, LOD */
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);     /* R, G, B, A */
>         }
>         break;
> @@ -2189,13 +2294,13 @@ exec_sample(struct tgsi_exec_machine *mach,
>            FETCH(&r[2], 3, TGSI_CHAN_X);
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&r[1],&r[2],&ZeroVec, lod,    /* S, T, P, C, LOD */
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         }
>         else {
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&r[1],&ZeroVec,&ZeroVec, lod,    /* S, T, P, C, LOD */
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);  /* outputs */
>         }
>         break;
> @@ -2209,13 +2314,13 @@ exec_sample(struct tgsi_exec_machine *mach,
>            FETCH(&r[3], 3, TGSI_CHAN_X);
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&r[1],&r[2],&r[3], lod,
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);
>         }
>         else {
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&r[1],&r[2],&ZeroVec, lod,
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);
>         }
>         break;
> @@ -2228,13 +2333,13 @@ exec_sample(struct tgsi_exec_machine *mach,
>            FETCH(&r[4], 3, TGSI_CHAN_X);
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&r[1],&r[2],&r[3],&r[4],
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);
>         }
>         else {
>            fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                        &r[0],&r[1],&r[2],&r[3], lod,
> -                     control,
> +                     NULL, offsets, control,
>                        &r[0],&r[1],&r[2],&r[3]);
>         }
>         break;
> @@ -2258,18 +2363,35 @@ exec_sample_d(struct tgsi_exec_machine *mach,
>      const uint resource_unit = inst->Src[1].Register.Index;
>      const uint sampler_unit = inst->Src[2].Register.Index;
>      union tgsi_exec_channel r[4];
> +   float derivs[3][2][TGSI_QUAD_SIZE];
>      uint chan;
> -   /*
> -    * XXX: This is fake SAMPLE_D -- the derivatives are not taken into account, yet.
> -    */
> +   int8_t offsets[3];
> +
> +   if (inst->Texture.NumOffsets == 1) {
> +      union tgsi_exec_channel index;
> +      union tgsi_exec_channel offset[3];
> +      index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> +      fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> +     offsets[0] = offset[0].i[0];
> +     offsets[1] = offset[1].i[0];
> +     offsets[2] = offset[2].i[0];
> +   } else
> +     offsets[0] = offsets[1] = offsets[2] = 0;

This block of code seems to be repeated several times.  Can it be put 
into a helper function like get_texel_offsets()?

>
>      switch (mach->SamplerViews[resource_unit].Resource) {
>      case TGSI_TEXTURE_1D:
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> +
>         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                     &r[0],&ZeroVec,&ZeroVec,&ZeroVec,&ZeroVec,   /* S, T, P, C, LOD */
> -                  tgsi_sampler_lod_none,
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
>                     &r[0],&r[1],&r[2],&r[3]);           /* R, G, B, A */
>         break;
>
> @@ -2278,9 +2400,12 @@ exec_sample_d(struct tgsi_exec_machine *mach,
>         FETCH(&r[0], 0, TGSI_CHAN_X);
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
>
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
> +
>         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                     &r[0],&r[1],&ZeroVec,&ZeroVec,&ZeroVec,   /* inputs */
> -                  tgsi_sampler_lod_none,
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
>                     &r[0],&r[1],&r[2],&r[3]);     /* outputs */
>         break;
>
> @@ -2290,9 +2415,13 @@ exec_sample_d(struct tgsi_exec_machine *mach,
>         FETCH(&r[1], 0, TGSI_CHAN_Y);
>         FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Z, derivs[2]);
> +
>         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                     &r[0],&r[1],&r[2],&ZeroVec,&ZeroVec,
> -                  tgsi_sampler_lod_none,
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
>                     &r[0],&r[1],&r[2],&r[3]);
>         break;
>
> @@ -2302,9 +2431,13 @@ exec_sample_d(struct tgsi_exec_machine *mach,
>         FETCH(&r[2], 0, TGSI_CHAN_Z);
>         FETCH(&r[3], 0, TGSI_CHAN_W);
>
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
> +      fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Z, derivs[2]);
> +
>         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
>                     &r[0],&r[1],&r[2],&r[3],&ZeroVec,
> -                  tgsi_sampler_lod_none,
> +                  derivs, offsets, tgsi_sampler_derivs_explicit,
>                     &r[0],&r[1],&r[2],&r[3]);
>         break;
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> index c009a97c..ef1fa82 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> @@ -92,8 +92,8 @@ enum tgsi_sampler_control {
>      tgsi_sampler_lod_none,
>      tgsi_sampler_lod_bias,
>      tgsi_sampler_lod_explicit,
> -   tgsi_sampler_lod_zero
> -   /* FIXME: tgsi_sampler_derivs_explicit */
> +   tgsi_sampler_lod_zero,
> +   tgsi_sampler_derivs_explicit
>   };
>
>   /**
> @@ -108,10 +108,12 @@ struct tgsi_sampler
>       * s - the first texture coordinate for sampling.
>       * t - the second texture coordinate for sampling - unused for 1D,
>             layer for 1D arrays.
> -    * p - the third coordinate for sampling for 3D, cube, cube arrays,
> +    * r - the third coordinate for sampling for 3D, cube, cube arrays,
>       *     layer for 2D arrays. Compare value for 1D/2D shadows.
>       * c0 - Compare value for shadow cube and shadow 2d arrays,
>       *      layer for cube arrays.
> +    * derivs - explicit derivatives.
> +    * offset - texel offsets
>       * lod - lod value, except for shadow cube arrays (compare value there).
>       */
>      void (*get_samples)(struct tgsi_sampler *sampler,
> @@ -122,6 +124,8 @@ struct tgsi_sampler
>                          const float r[TGSI_QUAD_SIZE],
>                          const float c0[TGSI_QUAD_SIZE],
>                          const float c1[TGSI_QUAD_SIZE],
> +                       float derivs[3][2][TGSI_QUAD_SIZE],
> +                       const int8_t offset[3],
>                          enum tgsi_sampler_control control,
>                          float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
>      void (*get_dims)(struct tgsi_sampler *sampler,
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index 30ecc6f..8e16ff9 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -1645,6 +1645,8 @@ compute_lod(const struct pipe_sampler_state *sampler,
>      switch (control) {
>      case tgsi_sampler_lod_none:
>      case tgsi_sampler_lod_zero:
> +   /* XXX FIXME */
> +   case tgsi_sampler_derivs_explicit:
>         lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(biased_lambda, min_lod, max_lod);
>         break;
>      case tgsi_sampler_lod_bias:
> @@ -1687,6 +1689,8 @@ compute_lambda_lod(struct sp_sampler_variant *samp,
>
>      switch (control) {
>      case tgsi_sampler_lod_none:
> +      /* XXX FIXME */
> +   case tgsi_sampler_derivs_explicit:
>         lambda = samp->compute_lambda(samp, s, t, p) + lod_bias;
>         lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lambda, min_lod, max_lod);
>         break;
> @@ -2085,7 +2089,9 @@ mip_filter_linear_aniso(struct sp_sampler_variant *samp,
>      float dvdy = (t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]) * t_to_v;
>
>      if (control == tgsi_sampler_lod_bias ||
> -       control == tgsi_sampler_lod_none) {
> +       control == tgsi_sampler_lod_none ||
> +       /* XXX FIXME */
> +       control == tgsi_sampler_derivs_explicit) {
>         /* note: instead of working with Px and Py, we will use the
>          * squared length instead, to avoid sqrt.
>          */
> @@ -3051,6 +3057,8 @@ sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
>                       const float p[TGSI_QUAD_SIZE],
>                       const float c0[TGSI_QUAD_SIZE],
>                       const float lod[TGSI_QUAD_SIZE],
> +                    float derivs[3][2][TGSI_QUAD_SIZE],
> +                    const int8_t offset[3],
>                       enum tgsi_sampler_control control,
>                       float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
>   {



More information about the mesa-dev mailing list