Mesa (master): softpipe: clean up lod computation

Roland Scheidegger sroland at kemper.freedesktop.org
Sat Feb 9 02:55:28 UTC 2013


Module: Mesa
Branch: master
Commit: 75d99673a8f47f62458034b0566d6c0221fae5d1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=75d99673a8f47f62458034b0566d6c0221fae5d1

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Fri Feb  8 18:42:17 2013 -0800

softpipe: clean up lod computation

This should handle the new lod_zero modifier more correctly.
The runtime-conditional is a bit more complex however we now also do
scalar lod computation when appropriate which should more than make up for it.
The refactoring should also fix an issue with explicit lods
(lod clamp wasn't applied to them).
Also, always pass lod as the 5th element from tgsi executor, which simplifies
things (get rid of annoying conditionals later).

v2: based on Brian's feedback, use switch in a couple of places, fix up
some function parameter names, fix up comments.

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

---

 src/gallium/auxiliary/tgsi/tgsi_exec.c       |   90 +++++++--------
 src/gallium/auxiliary/tgsi/tgsi_exec.h       |   14 ++-
 src/gallium/drivers/softpipe/sp_tex_sample.c |  161 +++++++++++++++-----------
 src/gallium/drivers/softpipe/sp_tex_sample.h |    2 +-
 4 files changed, 143 insertions(+), 124 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index d50bdc6..6da7d42 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1728,6 +1728,7 @@ fetch_texel( struct tgsi_sampler *sampler,
    uint j;
    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
 
+   /* FIXME: handle explicit derivs, offsets */
    sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, c1->f, control, rgba);
 
    for (j = 0; j < 4; j++) {
@@ -1760,9 +1761,11 @@ exec_tex(struct tgsi_exec_machine *mach,
    const uint unit = inst->Src[sampler].Register.Index;
    union tgsi_exec_channel r[4], cubearraycomp, cubelod;
    const union tgsi_exec_channel *lod = &ZeroVec;
-   enum tgsi_sampler_control control;
+   enum tgsi_sampler_control control =  tgsi_sampler_lod_none;
    uint chan;
 
+   assert(modifier != TEX_MODIFIER_LEVEL_ZERO);
+
    if (modifier != TEX_MODIFIER_NONE && (sampler == 1)) {
       FETCH(&r[3], 0, TGSI_CHAN_W);
       if (modifier != TEX_MODIFIER_PROJECTED) {
@@ -1772,7 +1775,7 @@ exec_tex(struct tgsi_exec_machine *mach,
 
    if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
       control = tgsi_sampler_lod_explicit;
-   } else {
+   } else if (modifier == TEX_MODIFIER_LOD_BIAS){
       control = tgsi_sampler_lod_bias;
    }
 
@@ -1785,7 +1788,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &ZeroVec, &ZeroVec, lod, &ZeroVec, /* S, T, P, LOD */
+                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
       break;
@@ -1798,7 +1801,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &ZeroVec, &r[2], lod, &ZeroVec, /* S, T, P, LOD */
+                  &r[0], &ZeroVec, &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
       break;
@@ -1818,7 +1821,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod, &ZeroVec,    /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], &ZeroVec, lod,    /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1832,7 +1835,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &ZeroVec, lod, &ZeroVec,    /* S, T, P, LOD */
+                  &r[0], &r[1], &ZeroVec, &ZeroVec, lod,   /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1846,7 +1849,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod, &ZeroVec,    /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1862,7 +1865,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod, &ZeroVec,    /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1874,7 +1877,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       FETCH(&r[3], 0, TGSI_CHAN_W);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], &r[3], &ZeroVec,    /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], &r[3], &ZeroVec,    /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1891,7 +1894,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          cubelod = ZeroVec;
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], &r[3], &cubelod,    /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], &r[3], &cubelod,    /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1908,7 +1911,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod, &ZeroVec,
+                  &r[0], &r[1], &r[2], &ZeroVec, lod,
                   control,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
@@ -1922,7 +1925,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       FETCH(&cubearraycomp, 1, TGSI_CHAN_X);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1967,8 +1970,8 @@ exec_txd(struct tgsi_exec_machine *mach,
       FETCH(&r[0], 0, TGSI_CHAN_X);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
-                  tgsi_sampler_lod_bias,
+                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, C, LOD */
+                  tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
       break;
 
@@ -1985,7 +1988,7 @@ exec_txd(struct tgsi_exec_machine *mach,
 
       fetch_texel(mach->Samplers[unit],
                   &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,   /* inputs */
-                  tgsi_sampler_lod_bias,
+                  tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
       break;
 
@@ -1999,7 +2002,7 @@ exec_txd(struct tgsi_exec_machine *mach,
 
       fetch_texel(mach->Samplers[unit],
                   &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,
-                  tgsi_sampler_lod_bias,
+                  tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
 
@@ -2012,7 +2015,7 @@ exec_txd(struct tgsi_exec_machine *mach,
 
       fetch_texel(mach->Samplers[unit],
                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,
-                  tgsi_sampler_lod_bias,
+                  tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
 
@@ -2137,31 +2140,28 @@ exec_sample(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];
+   union tgsi_exec_channel r[4], c1;
    const union tgsi_exec_channel *lod = &ZeroVec;
-   enum tgsi_sampler_control control;
+   enum tgsi_sampler_control control = tgsi_sampler_lod_none;
    uint chan;
 
    assert(modifier != TEX_MODIFIER_PROJECTED);
 
    if (modifier != TEX_MODIFIER_NONE) {
       if (modifier == TEX_MODIFIER_LOD_BIAS) {
-         FETCH(&r[3], 3, TGSI_CHAN_X);
-         lod = &r[3];
+         FETCH(&c1, 3, TGSI_CHAN_X);
+         lod = &c1;
+         control = tgsi_sampler_lod_bias;
       }
       else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
-         FETCH(&r[3], 0, TGSI_CHAN_W);
-         lod = &r[3];
+         FETCH(&c1, 0, TGSI_CHAN_W);
+         lod = &c1;
+         control = tgsi_sampler_lod_explicit;
       }
-      else
+      else {
          assert(modifier == TEX_MODIFIER_LEVEL_ZERO);
-   }
-
-   if (modifier == TEX_MODIFIER_EXPLICIT_LOD ||
-       modifier == TEX_MODIFIER_LEVEL_ZERO) {
-      control = tgsi_sampler_lod_explicit;
-   } else {
-      control = tgsi_sampler_lod_bias;
+         control = tgsi_sampler_lod_zero;
+      }
    }
 
    FETCH(&r[0], 0, TGSI_CHAN_X);
@@ -2171,13 +2171,13 @@ exec_sample(struct tgsi_exec_machine *mach,
       if (compare) {
          FETCH(&r[2], 3, TGSI_CHAN_X);
          fetch_texel(mach->Samplers[sampler_unit],
-                     &r[0], &ZeroVec, &r[2], lod, &ZeroVec,  /* S, T, P, LOD */
+                     &r[0], &ZeroVec, &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
                      control,
                      &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
       }
       else {
          fetch_texel(mach->Samplers[sampler_unit],
-                     &r[0], &ZeroVec, &ZeroVec, lod, &ZeroVec,  /* S, T, P, LOD */
+                     &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
                      control,
                      &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
       }
@@ -2190,13 +2190,13 @@ exec_sample(struct tgsi_exec_machine *mach,
       if (compare) {
          FETCH(&r[2], 3, TGSI_CHAN_X);
          fetch_texel(mach->Samplers[sampler_unit],
-                     &r[0], &r[1], &r[2], lod, &ZeroVec,     /* S, T, P, LOD */
+                     &r[0], &r[1], &r[2], &ZeroVec, lod,    /* S, T, P, C, LOD */
                      control,
                      &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       }
       else {
          fetch_texel(mach->Samplers[sampler_unit],
-                     &r[0], &r[1], &ZeroVec, lod, &ZeroVec,     /* S, T, P, LOD */
+                     &r[0], &r[1], &ZeroVec, &ZeroVec, lod,    /* S, T, P, C, LOD */
                      control,
                      &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       }
@@ -2210,13 +2210,13 @@ exec_sample(struct tgsi_exec_machine *mach,
       if(compare) {
          FETCH(&r[3], 3, TGSI_CHAN_X);
          fetch_texel(mach->Samplers[sampler_unit],
-                     &r[0], &r[1], &r[2], &r[3], &ZeroVec,
+                     &r[0], &r[1], &r[2], &r[3], lod,
                      control,
                      &r[0], &r[1], &r[2], &r[3]);
       }
       else {
          fetch_texel(mach->Samplers[sampler_unit],
-                     &r[0], &r[1], &r[2], lod, &ZeroVec,
+                     &r[0], &r[1], &r[2], &ZeroVec, lod,
                      control,
                      &r[0], &r[1], &r[2], &r[3]);
       }
@@ -2227,12 +2227,6 @@ exec_sample(struct tgsi_exec_machine *mach,
       FETCH(&r[2], 0, TGSI_CHAN_Z);
       FETCH(&r[3], 0, TGSI_CHAN_W);
       if(compare) {
-         assert(modifier == TEX_MODIFIER_NONE);
-         /*
-          * FIXME: lod bias and explicit lod are prohibited but
-          * for sample_c_lz we pass the level zero info as explicit
-          * lod 0.
-          */
          FETCH(&r[4], 3, TGSI_CHAN_X);
          fetch_texel(mach->Samplers[sampler_unit],
                      &r[0], &r[1], &r[2], &r[3], &r[4],
@@ -2276,8 +2270,8 @@ exec_sample_d(struct tgsi_exec_machine *mach,
       FETCH(&r[0], 0, TGSI_CHAN_X);
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
-                  tgsi_sampler_lod_bias,
+                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, C, LOD */
+                  tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
       break;
 
@@ -2288,7 +2282,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
 
       fetch_texel(mach->Samplers[sampler_unit],
                   &r[0], &r[1], &ZeroVec, &ZeroVec, &ZeroVec,   /* inputs */
-                  tgsi_sampler_lod_bias,
+                  tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
       break;
 
@@ -2300,7 +2294,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
 
       fetch_texel(mach->Samplers[sampler_unit],
                   &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,
-                  tgsi_sampler_lod_bias,
+                  tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
 
@@ -2312,7 +2306,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
 
       fetch_texel(mach->Samplers[sampler_unit],
                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,
-                  tgsi_sampler_lod_bias,
+                  tgsi_sampler_lod_none,
                   &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 1a7d979..a66c919 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -89,8 +89,11 @@ struct tgsi_interp_coef
 };
 
 enum tgsi_sampler_control {
+   tgsi_sampler_lod_none,
    tgsi_sampler_lod_bias,
-   tgsi_sampler_lod_explicit
+   tgsi_sampler_lod_explicit,
+   tgsi_sampler_lod_zero
+   /* FIXME: tgsi_sampler_derivs_explicit */
 };
 
 /**
@@ -107,15 +110,14 @@ struct tgsi_sampler
           layer for 1D arrays.
     * p - the third coordinate for sampling for 3D, cube, cube arrays,
     *     layer for 2D arrays. Compare value for 1D/2D shadows.
-    * c0 - lod value for lod variants, compare value for shadow cube
-    *      and shadow 2d arrays.
-    * c1 - cube array only - lod for cube map arrays
-    *                        compare for shadow cube map arrays.
+    * c0 - Compare value for shadow cube and shadow 2d arrays,
+    *      layer for cube arrays.
+    * lod - lod value, except for shadow cube arrays (compare value there).
     */
    void (*get_samples)(struct tgsi_sampler *sampler,
                        const float s[TGSI_QUAD_SIZE],
                        const float t[TGSI_QUAD_SIZE],
-                       const float p[TGSI_QUAD_SIZE],
+                       const float r[TGSI_QUAD_SIZE],
                        const float c0[TGSI_QUAD_SIZE],
                        const float c1[TGSI_QUAD_SIZE],
                        enum tgsi_sampler_control control,
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index da31860..a4262e3 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -127,7 +127,6 @@ repeat(int coord, unsigned size)
  * \param s  the incoming texcoords
  * \param size  the texture image size
  * \param icoord  returns the integer texcoords
- * \return  integer texture index
  */
 static void
 wrap_nearest_repeat(float s, unsigned size, int *icoord)
@@ -1642,20 +1641,91 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
 }
 
 
-/* Calculate level of detail for every fragment.
+/* Calculate level of detail for every fragment,
+ * with lambda already computed.
  * Note that lambda has already been biased by global LOD bias.
+ * \param biased_lambda per-quad lambda.
+ * \param lod_in per-fragment lod_bias or explicit_lod.
+ * \param lod returns the per-fragment lod.
  */
 static INLINE void
 compute_lod(const struct pipe_sampler_state *sampler,
+            enum tgsi_sampler_control control,
             const float biased_lambda,
-            const float lodbias[TGSI_QUAD_SIZE],
+            const float lod_in[TGSI_QUAD_SIZE],
             float lod[TGSI_QUAD_SIZE])
 {
+   float min_lod = sampler->min_lod;
+   float max_lod = sampler->max_lod;
    uint i;
 
-   for (i = 0; i < TGSI_QUAD_SIZE; i++) {
-      lod[i] = biased_lambda + lodbias[i];
-      lod[i] = CLAMP(lod[i], sampler->min_lod, sampler->max_lod);
+   switch (control) {
+   case tgsi_sampler_lod_none:
+   case tgsi_sampler_lod_zero:
+      lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(biased_lambda, min_lod, max_lod);
+      break;
+   case tgsi_sampler_lod_bias:
+      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+         lod[i] = biased_lambda + lod_in[i];
+         lod[i] = CLAMP(lod[i], min_lod, max_lod);
+      }
+      break;
+   case tgsi_sampler_lod_explicit:
+      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+         lod[i] = CLAMP(lod_in[i], min_lod, max_lod);
+      }
+      break;
+   default:
+      assert(0);
+      lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
+   }
+}
+
+
+/* Calculate level of detail for every fragment.
+ * \param lod_in per-fragment lod_bias or explicit_lod.
+ * \param lod results per-fragment lod.
+ */
+static INLINE void
+compute_lambda_lod(struct sp_sampler_variant *samp,
+                   const float s[TGSI_QUAD_SIZE],
+                   const float t[TGSI_QUAD_SIZE],
+                   const float p[TGSI_QUAD_SIZE],
+                   const float lod_in[TGSI_QUAD_SIZE],
+                   enum tgsi_sampler_control control,
+                   float lod[TGSI_QUAD_SIZE])
+{
+   const struct pipe_sampler_state *sampler = samp->sampler;
+   float lod_bias = sampler->lod_bias;
+   float min_lod = sampler->min_lod;
+   float max_lod = sampler->max_lod;
+   float lambda;
+   uint i;
+
+   switch (control) {
+   case tgsi_sampler_lod_none:
+      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;
+   case tgsi_sampler_lod_bias:
+      lambda = samp->compute_lambda(samp, s, t, p) + lod_bias;
+      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+         lod[i] = lambda + lod_in[i];
+         lod[i] = CLAMP(lod[i], min_lod, max_lod);
+      }
+      break;
+   case tgsi_sampler_lod_explicit:
+      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+         lod[i] = CLAMP(lod_in[i], min_lod, max_lod);
+      }
+      break;
+   case tgsi_sampler_lod_zero:
+      /* this is all static state in the sampler really need clamp here? */
+      lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lod_bias, min_lod, max_lod);
+      break;
+   default:
+      assert(0);
+      lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
    }
 }
 
@@ -1666,7 +1736,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
                   const float t[TGSI_QUAD_SIZE],
                   const float p[TGSI_QUAD_SIZE],
                   const float c0[TGSI_QUAD_SIZE],
-                  const float c1[TGSI_QUAD_SIZE],
+                  const float lod_in[TGSI_QUAD_SIZE],
                   enum tgsi_sampler_control control,
                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1675,21 +1745,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
    int j;
    float lod[TGSI_QUAD_SIZE];
 
-   if (control == tgsi_sampler_lod_bias) {
-      float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
-      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
-         compute_lod(samp->sampler, lambda, c1, lod);
-      else
-         compute_lod(samp->sampler, lambda, c0, lod);
-   } else {
-      assert(control == tgsi_sampler_lod_explicit);
-
-      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
-         memcpy(lod, c1, sizeof(lod));
-      else
-         memcpy(lod, c0, sizeof(lod));
-
-   }
+   compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       int level0 = samp->view->u.tex.first_level + (int)lod[j];
@@ -1735,7 +1791,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
                    const float t[TGSI_QUAD_SIZE],
                    const float p[TGSI_QUAD_SIZE],
                    const float c0[TGSI_QUAD_SIZE],
-                   const float c1[TGSI_QUAD_SIZE],
+                   const float lod_in[TGSI_QUAD_SIZE],
                    enum tgsi_sampler_control control,
                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1744,20 +1800,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
    float lod[TGSI_QUAD_SIZE];
    int j;
 
-   if (control == tgsi_sampler_lod_bias) {
-      float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
-      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
-         compute_lod(samp->sampler, lambda, c1, lod);
-      else
-         compute_lod(samp->sampler, lambda, c0, lod);
-   } else {
-      assert(control == tgsi_sampler_lod_explicit);
-
-      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
-         memcpy(lod, c1, sizeof(lod));
-      else
-         memcpy(lod, c0, sizeof(lod));
-   }
+   compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       if (lod[j] < 0.0)
@@ -1783,7 +1826,7 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
                 const float t[TGSI_QUAD_SIZE],
                 const float p[TGSI_QUAD_SIZE],
                 const float c0[TGSI_QUAD_SIZE],
-                const float c1[TGSI_QUAD_SIZE],
+                const float lod_in[TGSI_QUAD_SIZE],
                 enum tgsi_sampler_control control,
                 float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1791,20 +1834,7 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
    float lod[TGSI_QUAD_SIZE];
    int j;
 
-   if (control == tgsi_sampler_lod_bias) {
-      float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
-      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
-         compute_lod(samp->sampler, lambda, c1, lod);
-      else
-         compute_lod(samp->sampler, lambda, c0, lod);
-   } else {
-      assert(control == tgsi_sampler_lod_explicit);
-
-      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
-         memcpy(lod, c1, sizeof(lod));
-      else
-         memcpy(lod, c0, sizeof(lod));
-   }
+   compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       if (lod[j] < 0.0) { 
@@ -1825,7 +1855,7 @@ mip_filter_none_no_filter_select(struct tgsi_sampler *tgsi_sampler,
                                      const float t[TGSI_QUAD_SIZE],
                                      const float p[TGSI_QUAD_SIZE],
                                      const float c0[TGSI_QUAD_SIZE],
-                                     const float c1[TGSI_QUAD_SIZE],
+                                     const float lod_in[TGSI_QUAD_SIZE],
                                      enum tgsi_sampler_control control,
                                      float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -2060,7 +2090,7 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
                         const float t[TGSI_QUAD_SIZE],
                         const float p[TGSI_QUAD_SIZE],
                         const float c0[TGSI_QUAD_SIZE],
-                        const float c1[TGSI_QUAD_SIZE],
+                        const float lod_in[TGSI_QUAD_SIZE],
                         enum tgsi_sampler_control control,
                         float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -2077,7 +2107,8 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
    float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
    float dvdy = (t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]) * t_to_v;
    
-   if (control == tgsi_sampler_lod_bias) {
+   if (control == tgsi_sampler_lod_bias ||
+       control == tgsi_sampler_lod_none) {
       /* note: instead of working with Px and Py, we will use the 
        * squared length instead, to avoid sqrt.
        */
@@ -2114,12 +2145,12 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
        * this since 0.5*log(x) = log(sqrt(x))
        */
       lambda = 0.5F * util_fast_log2(Pmin2) + samp->sampler->lod_bias;
-      compute_lod(samp->sampler, lambda, c0, lod);
+      compute_lod(samp->sampler, control, lambda, lod_in, lod);
    }
    else {
-      assert(control == tgsi_sampler_lod_explicit);
-
-      memcpy(lod, c0, sizeof(lod));
+      assert(control == tgsi_sampler_lod_explicit ||
+             control == tgsi_sampler_lod_zero);
+      compute_lod(samp->sampler, control, samp->sampler->lod_bias, lod_in, lod);
    }
    
    /* XXX: Take into account all lod values.
@@ -2161,24 +2192,16 @@ mip_filter_linear_2d_linear_repeat_POT(
    const float t[TGSI_QUAD_SIZE],
    const float p[TGSI_QUAD_SIZE],
    const float c0[TGSI_QUAD_SIZE],
-   const float c1[TGSI_QUAD_SIZE],
+   const float lod_in[TGSI_QUAD_SIZE],
    enum tgsi_sampler_control control,
    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int j;
-   float lambda;
    float lod[TGSI_QUAD_SIZE];
 
-   if (control == tgsi_sampler_lod_bias) {
-      lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
-      compute_lod(samp->sampler, lambda, c0, lod);
-   } else {
-      assert(control == tgsi_sampler_lod_explicit);
-
-      memcpy(lod, c0, sizeof(lod));
-   }
+   compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       int level0 = samp->view->u.tex.first_level + (int)lod[j];
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index 61dca91..421224a 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -62,7 +62,7 @@ typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler,
                             const float t[TGSI_QUAD_SIZE],
                             const float p[TGSI_QUAD_SIZE],
                             const float c0[TGSI_QUAD_SIZE],
-                            const float c1[TGSI_QUAD_SIZE],
+                            const float lod[TGSI_QUAD_SIZE],
                             enum tgsi_sampler_control control,
                             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
 




More information about the mesa-commit mailing list