[Mesa-dev] [PATCH] softpipe/draw/tgsi: simplify driver/tgsi sampler interface

sroland at vmware.com sroland at vmware.com
Tue Feb 26 18:33:15 PST 2013


From: Roland Scheidegger <sroland at vmware.com>

Use a single sampler adapter instead of per-sampler-unit samplers,
and just pass along texture unit and sampler unit in the calls.
The reason is that for dx10-style sample opcodes pre-wired
samplers including all the texture state aren't really feasible (and for
sample_i/sviewinfo we don't even have samplers).
Of course right now softpipe doesn't actually do anything more than
just look up all its pre-wired per-texunit/per-samplerunit sampler as
it did before so this doesn't really achieve much except one more
function call, however this is now all softpipe's fault (fixing that in
a way which doesn't suck is still an unsolved problem).
---
 src/gallium/auxiliary/draw/draw_context.c       |   13 +-
 src/gallium/auxiliary/draw/draw_context.h       |    7 +-
 src/gallium/auxiliary/draw/draw_gs.c            |    3 +-
 src/gallium/auxiliary/draw/draw_private.h       |    6 +-
 src/gallium/auxiliary/draw/draw_vs_exec.c       |    3 +-
 src/gallium/auxiliary/tgsi/tgsi_exec.c          |   81 +++++----
 src/gallium/auxiliary/tgsi/tgsi_exec.h          |   22 ++-
 src/gallium/drivers/softpipe/sp_context.c       |   29 ++--
 src/gallium/drivers/softpipe/sp_context.h       |    2 +-
 src/gallium/drivers/softpipe/sp_fs_exec.c       |    9 +-
 src/gallium/drivers/softpipe/sp_state.h         |    2 +-
 src/gallium/drivers/softpipe/sp_state_derived.c |    4 +-
 src/gallium/drivers/softpipe/sp_state_sampler.c |    4 +-
 src/gallium/drivers/softpipe/sp_tex_sample.c    |  206 ++++++++++++++---------
 src/gallium/drivers/softpipe/sp_tex_sample.h    |   47 ++++--
 15 files changed, 249 insertions(+), 189 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 045bb6b..6b70ac8 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -581,18 +581,15 @@ draw_num_shader_outputs(const struct draw_context *draw)
  * This might only be used by software drivers for the time being.
  */
 void
-draw_texture_samplers(struct draw_context *draw,
-                      uint shader,
-                      uint num_samplers,
-                      struct tgsi_sampler **samplers)
+draw_texture_sampler(struct draw_context *draw,
+                     uint shader,
+                     struct tgsi_sampler *sampler)
 {
    if (shader == PIPE_SHADER_VERTEX) {
-      draw->vs.tgsi.num_samplers = num_samplers;
-      draw->vs.tgsi.samplers = samplers;
+      draw->vs.tgsi.sampler = sampler;
    } else {
       debug_assert(shader == PIPE_SHADER_GEOMETRY);
-      draw->gs.tgsi.num_samplers = num_samplers;
-      draw->gs.tgsi.samplers = samplers;
+      draw->gs.tgsi.sampler = sampler;
    }
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index e8e2d94..18c8595 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -132,10 +132,9 @@ draw_num_shader_outputs(const struct draw_context *draw);
 
 
 void
-draw_texture_samplers(struct draw_context *draw,
-                      uint shader_type,
-                      uint num_samplers,
-                      struct tgsi_sampler **samplers);
+draw_texture_sampler(struct draw_context *draw,
+                     uint shader_type,
+                     struct tgsi_sampler *sampler);
 
 void
 draw_set_sampler_views(struct draw_context *draw,
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index 5c55523..25c117b 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -465,7 +465,6 @@ void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
    if (shader && shader->machine->Tokens != shader->state.tokens) {
       tgsi_exec_machine_bind_shader(shader->machine,
                                     shader->state.tokens,
-                                    draw->gs.tgsi.num_samplers,
-                                    draw->gs.tgsi.samplers);
+                                    draw->gs.tgsi.sampler);
    }
 }
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index ec5791c..5063c3c 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -248,8 +248,7 @@ struct draw_context
       struct {
          struct tgsi_exec_machine *machine;
 
-         struct tgsi_sampler **samplers;
-         uint num_samplers;
+         struct tgsi_sampler *sampler;
       } tgsi;
 
       struct translate *fetch;
@@ -268,8 +267,7 @@ struct draw_context
       struct {
          struct tgsi_exec_machine *machine;
 
-         struct tgsi_sampler **samplers;
-         uint num_samplers;
+         struct tgsi_sampler *sampler;
       } tgsi;
 
    } gs;
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 828a155..6100394 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -69,8 +69,7 @@ vs_exec_prepare( struct draw_vertex_shader *shader,
    if (evs->machine->Tokens != shader->state.tokens) {
       tgsi_exec_machine_bind_shader(evs->machine,
                                     shader->state.tokens,
-                                    draw->vs.tgsi.num_samplers,
-                                    draw->vs.tgsi.samplers);
+                                    draw->vs.tgsi.sampler);
    }
 }
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index a2b2a81..6277c3e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -641,8 +641,7 @@ void
 tgsi_exec_machine_bind_shader(
    struct tgsi_exec_machine *mach,
    const struct tgsi_token *tokens,
-   uint numSamplers,
-   struct tgsi_sampler **samplers)
+   struct tgsi_sampler *sampler)
 {
    uint k;
    struct tgsi_parse_context parse;
@@ -657,12 +656,9 @@ tgsi_exec_machine_bind_shader(
 
    util_init_math();
 
-   if (numSamplers) {
-      assert(samplers);
-   }
 
    mach->Tokens = tokens;
-   mach->Samplers = samplers;
+   mach->Sampler = sampler;
 
    if (!tokens) {
       /* unbind and free all */
@@ -1717,6 +1713,8 @@ conditional_emit_primitive(struct tgsi_exec_machine *mach)
  */
 static void
 fetch_texel( struct tgsi_sampler *sampler,
+             const unsigned sview_idx,
+             const unsigned sampler_idx,
              const union tgsi_exec_channel *s,
              const union tgsi_exec_channel *t,
              const union tgsi_exec_channel *p,
@@ -1732,7 +1730,8 @@ fetch_texel( struct tgsi_sampler *sampler,
    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);
+   sampler->get_samples(sampler, sview_idx, sampler_idx,
+                        s->f, t->f, p->f, c0->f, c1->f, control, rgba);
 
    for (j = 0; j < 4; j++) {
       r->f[j] = rgba[0][j];
@@ -1790,7 +1789,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[0], &r[0], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
@@ -1803,7 +1802,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[0], &r[0], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &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 */
@@ -1823,7 +1822,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[2], &r[2], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &r[2], &ZeroVec, lod,    /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -1837,7 +1836,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[0], &r[0], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &ZeroVec, &ZeroVec, lod,   /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -1851,7 +1850,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[0], &r[0], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -1867,7 +1866,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[1], &r[1], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &r[2], &ZeroVec, lod,   /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -1879,7 +1878,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       FETCH(&r[2], 0, TGSI_CHAN_Z);
       FETCH(&r[3], 0, TGSI_CHAN_W);
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,    /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -1896,7 +1895,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       else
          cubelod = ZeroVec;
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &r[2], &r[3], &cubelod,    /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -1913,7 +1912,7 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[2], &r[2], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &r[2], &ZeroVec, lod,
                   control,
                   &r[0], &r[1], &r[2], &r[3]);
@@ -1927,7 +1926,7 @@ exec_tex(struct tgsi_exec_machine *mach,
 
       FETCH(&cubearraycomp, 1, TGSI_CHAN_X);
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, C, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -1972,7 +1971,7 @@ exec_txd(struct tgsi_exec_machine *mach,
 
       FETCH(&r[0], 0, TGSI_CHAN_X);
 
-      fetch_texel(mach->Samplers[unit],
+      fetch_texel(mach->Sampler, unit, unit,
                   &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 */
@@ -1989,7 +1988,7 @@ exec_txd(struct tgsi_exec_machine *mach,
       FETCH(&r[1], 0, TGSI_CHAN_Y);
       FETCH(&r[2], 0, TGSI_CHAN_Z);
 
-      fetch_texel(mach->Samplers[unit],
+      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 */
@@ -2003,7 +2002,7 @@ exec_txd(struct tgsi_exec_machine *mach,
       FETCH(&r[1], 0, TGSI_CHAN_Y);
       FETCH(&r[2], 0, TGSI_CHAN_Z);
 
-      fetch_texel(mach->Samplers[unit],
+      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]);
@@ -2016,7 +2015,7 @@ exec_txd(struct tgsi_exec_machine *mach,
       FETCH(&r[2], 0, TGSI_CHAN_Z);
       FETCH(&r[3], 0, TGSI_CHAN_W);
 
-      fetch_texel(mach->Samplers[unit],
+      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]);
@@ -2038,7 +2037,6 @@ static void
 exec_txf(struct tgsi_exec_machine *mach,
 	 const struct tgsi_full_instruction *inst)
 {
-   struct tgsi_sampler *sampler;
    const uint unit = inst->Src[2].Register.Index;
    union tgsi_exec_channel r[4];
    union tgsi_exec_channel offset[3];
@@ -2088,9 +2086,8 @@ exec_txf(struct tgsi_exec_machine *mach,
       break;
    }      
 
-   sampler = mach->Samplers[unit];
-   sampler->get_texel(sampler, r[0].i, r[1].i, r[2].i, r[3].i,
-		      offsets, rgba);
+   mach->Sampler->get_texel(mach->Sampler, unit, r[0].i, r[1].i, r[2].i, r[3].i,
+                            offsets, rgba);
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       r[0].f[j] = rgba[0][j];
@@ -2110,7 +2107,6 @@ static void
 exec_txq(struct tgsi_exec_machine *mach,
          const struct tgsi_full_instruction *inst)
 {
-   struct tgsi_sampler *sampler;
    const uint unit = inst->Src[1].Register.Index;
    int result[4];
    union tgsi_exec_channel r[4], src;
@@ -2118,20 +2114,19 @@ exec_txq(struct tgsi_exec_machine *mach,
    int i,j;
 
    fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_INT);
-   sampler = mach->Samplers[unit];
 
-   sampler->get_dims(sampler, src.i[0], result);
+   mach->Sampler->get_dims(mach->Sampler, unit, src.i[0], result);
 
    for (i = 0; i < TGSI_QUAD_SIZE; i++) {
       for (j = 0; j < 4; j++) {
-	 r[j].i[i] = result[j];
+         r[j].i[i] = result[j];
       }
    }
 
    for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
-	 store_dest(mach, &r[chan], &inst->Dst[0], inst, chan,
-		    TGSI_EXEC_DATA_INT);
+         store_dest(mach, &r[chan], &inst->Dst[0], inst, chan,
+                    TGSI_EXEC_DATA_INT);
       }
    }
 }
@@ -2173,13 +2168,13 @@ exec_sample(struct tgsi_exec_machine *mach,
    case TGSI_TEXTURE_1D:
       if (compare) {
          FETCH(&r[2], 3, TGSI_CHAN_X);
-         fetch_texel(mach->Samplers[sampler_unit],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &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],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
                      control,
                      &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
@@ -2192,13 +2187,13 @@ exec_sample(struct tgsi_exec_machine *mach,
       FETCH(&r[1], 0, TGSI_CHAN_Y);
       if (compare) {
          FETCH(&r[2], 3, TGSI_CHAN_X);
-         fetch_texel(mach->Samplers[sampler_unit],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &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],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &r[0], &r[1], &ZeroVec, &ZeroVec, lod,    /* S, T, P, C, LOD */
                      control,
                      &r[0], &r[1], &r[2], &r[3]);  /* outputs */
@@ -2212,13 +2207,13 @@ exec_sample(struct tgsi_exec_machine *mach,
       FETCH(&r[2], 0, TGSI_CHAN_Z);
       if(compare) {
          FETCH(&r[3], 3, TGSI_CHAN_X);
-         fetch_texel(mach->Samplers[sampler_unit],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &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],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &r[0], &r[1], &r[2], &ZeroVec, lod,
                      control,
                      &r[0], &r[1], &r[2], &r[3]);
@@ -2231,13 +2226,13 @@ exec_sample(struct tgsi_exec_machine *mach,
       FETCH(&r[3], 0, TGSI_CHAN_W);
       if(compare) {
          FETCH(&r[4], 3, TGSI_CHAN_X);
-         fetch_texel(mach->Samplers[sampler_unit],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &r[0], &r[1], &r[2], &r[3], &r[4],
                      control,
                      &r[0], &r[1], &r[2], &r[3]);
       }
       else {
-         fetch_texel(mach->Samplers[sampler_unit],
+         fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                      &r[0], &r[1], &r[2], &r[3], lod,
                      control,
                      &r[0], &r[1], &r[2], &r[3]);
@@ -2272,7 +2267,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
    case TGSI_TEXTURE_1D:
       FETCH(&r[0], 0, TGSI_CHAN_X);
 
-      fetch_texel(mach->Samplers[sampler_unit],
+      fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                   &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 */
@@ -2283,7 +2278,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
       FETCH(&r[0], 0, TGSI_CHAN_X);
       FETCH(&r[1], 0, TGSI_CHAN_Y);
 
-      fetch_texel(mach->Samplers[sampler_unit],
+      fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                   &r[0], &r[1], &ZeroVec, &ZeroVec, &ZeroVec,   /* inputs */
                   tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
@@ -2295,7 +2290,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
       FETCH(&r[1], 0, TGSI_CHAN_Y);
       FETCH(&r[2], 0, TGSI_CHAN_Z);
 
-      fetch_texel(mach->Samplers[sampler_unit],
+      fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                   &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,
                   tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);
@@ -2307,7 +2302,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
       FETCH(&r[2], 0, TGSI_CHAN_Z);
       FETCH(&r[3], 0, TGSI_CHAN_W);
 
-      fetch_texel(mach->Samplers[sampler_unit],
+      fetch_texel(mach->Sampler, resource_unit, sampler_unit,
                   &r[0], &r[1], &r[2], &r[3], &ZeroVec,
                   tgsi_sampler_lod_none,
                   &r[0], &r[1], &r[2], &r[3]);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index a66c919..c009a97c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -115,6 +115,8 @@ struct tgsi_sampler
     * lod - lod value, except for shadow cube arrays (compare value there).
     */
    void (*get_samples)(struct tgsi_sampler *sampler,
+                       const unsigned sview_index,
+                       const unsigned sampler_index,
                        const float s[TGSI_QUAD_SIZE],
                        const float t[TGSI_QUAD_SIZE],
                        const float r[TGSI_QUAD_SIZE],
@@ -122,12 +124,15 @@ struct tgsi_sampler
                        const float c1[TGSI_QUAD_SIZE],
                        enum tgsi_sampler_control control,
                        float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
-   void (*get_dims)(struct tgsi_sampler *sampler, int level,
-		    int dims[4]);
-   void (*get_texel)(struct tgsi_sampler *sampler, const int i[TGSI_QUAD_SIZE],
-		     const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
-		     const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
-		     float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
+   void (*get_dims)(struct tgsi_sampler *sampler,
+                    const unsigned sview_index,
+                    int level, int dims[4]);
+   void (*get_texel)(struct tgsi_sampler *sampler,
+                     const unsigned sview_index,
+                     const int i[TGSI_QUAD_SIZE],
+                     const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
+                     const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
+                     float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
 };
 
 #define TGSI_EXEC_NUM_TEMPS       4096
@@ -276,7 +281,7 @@ struct tgsi_exec_machine
    struct tgsi_exec_vector       *Addrs;
    struct tgsi_exec_vector       *Predicates;
 
-   struct tgsi_sampler           **Samplers;
+   struct tgsi_sampler           *Sampler;
 
    unsigned                      ImmLimit;
 
@@ -363,8 +368,7 @@ void
 tgsi_exec_machine_bind_shader(
    struct tgsi_exec_machine *mach,
    const struct tgsi_token *tokens,
-   uint numSamplers,
-   struct tgsi_sampler **samplers);
+   struct tgsi_sampler *sampler);
 
 uint
 tgsi_exec_machine_run(
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index e2cc1e1..141b7a8 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -51,6 +51,7 @@
 #include "sp_texture.h"
 #include "sp_query.h"
 #include "sp_screen.h"
+#include "sp_tex_sample.h"
 
 
 static void
@@ -115,6 +116,10 @@ softpipe_destroy( struct pipe_context *pipe )
 
    tgsi_exec_machine_destroy(softpipe->fs_machine);
 
+   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+      FREE(softpipe->tgsi.sampler[i]);
+   }
+
    FREE( softpipe );
 }
 
@@ -190,6 +195,10 @@ softpipe_create_context( struct pipe_screen *screen,
 
    util_init_math();
 
+   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+      softpipe->tgsi.sampler[i] = sp_create_tgsi_sampler();
+   }
+
    softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE );
    softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
 
@@ -256,17 +265,15 @@ softpipe_create_context( struct pipe_screen *screen,
    if (!softpipe->draw) 
       goto fail;
 
-   draw_texture_samplers(softpipe->draw,
-                         PIPE_SHADER_VERTEX,
-                         PIPE_MAX_SAMPLERS,
-                         (struct tgsi_sampler **)
-                            softpipe->tgsi.samplers_list[PIPE_SHADER_VERTEX]);
-
-   draw_texture_samplers(softpipe->draw,
-                         PIPE_SHADER_GEOMETRY,
-                         PIPE_MAX_SAMPLERS,
-                         (struct tgsi_sampler **)
-                            softpipe->tgsi.samplers_list[PIPE_SHADER_GEOMETRY]);
+   draw_texture_sampler(softpipe->draw,
+                        PIPE_SHADER_VERTEX,
+                        (struct tgsi_sampler *)
+                           softpipe->tgsi.sampler[PIPE_SHADER_VERTEX]);
+
+   draw_texture_sampler(softpipe->draw,
+                        PIPE_SHADER_GEOMETRY,
+                        (struct tgsi_sampler *)
+                           softpipe->tgsi.sampler[PIPE_SHADER_GEOMETRY]);
 
    if (debug_get_bool_option( "SOFTPIPE_NO_RAST", FALSE ))
       softpipe->no_rast = TRUE;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 86efcd9..dcd29be 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -159,7 +159,7 @@ struct softpipe_context {
 
    /** TGSI exec things */
    struct {
-      struct sp_sampler_variant *samplers_list[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
+      struct sp_tgsi_sampler *sampler[PIPE_SHADER_TYPES];
    } tgsi;
 
    struct tgsi_exec_machine *fs_machine;
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 3793d9b..9f1d9b4 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -61,16 +61,15 @@ sp_exec_fragment_shader(const struct sp_fragment_shader_variant *var)
 
 static void
 exec_prepare( const struct sp_fragment_shader_variant *var,
-	      struct tgsi_exec_machine *machine,
-	      struct tgsi_sampler **samplers )
+              struct tgsi_exec_machine *machine,
+              struct tgsi_sampler *sampler )
 {
    /*
     * Bind tokens/shader to the interpreter's machine state.
     */
    tgsi_exec_machine_bind_shader(machine,
                                  var->tokens,
-                                 PIPE_MAX_SAMPLERS,
-                                 samplers);
+                                 sampler);
 }
 
 
@@ -181,7 +180,7 @@ exec_delete(struct sp_fragment_shader_variant *var,
             struct tgsi_exec_machine *machine)
 {
    if (machine->Tokens == var->tokens) {
-      tgsi_exec_machine_bind_shader(machine, NULL, 0, NULL);
+      tgsi_exec_machine_bind_shader(machine, NULL, NULL);
    }
 
    FREE( (void *) var->tokens );
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index fa8654f..e2c49d2 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -81,7 +81,7 @@ struct sp_fragment_shader_variant
 
    void (*prepare)(const struct sp_fragment_shader_variant *shader,
 		   struct tgsi_exec_machine *machine,
-		   struct tgsi_sampler **samplers);
+		   struct tgsi_sampler *sampler);
 
    unsigned (*run)(const struct sp_fragment_shader_variant *shader,
 		   struct tgsi_exec_machine *machine,
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index e4a5a63..8fbe27b 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -246,8 +246,8 @@ update_fragment_shader(struct softpipe_context *softpipe, unsigned prim)
       /* prepare the TGSI interpreter for FS execution */
       softpipe->fs_variant->prepare(softpipe->fs_variant, 
                                     softpipe->fs_machine,
-                                    (struct tgsi_sampler **) softpipe->
-                                    tgsi.samplers_list[PIPE_SHADER_FRAGMENT]);
+                                    (struct tgsi_sampler *) softpipe->
+                                    tgsi.sampler[PIPE_SHADER_FRAGMENT]);
    }
    else {
       softpipe->fs_variant = NULL;
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index 0277ef1..eb02ecb 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -314,13 +314,13 @@ reset_sampler_variants(struct softpipe_context *softpipe,
 
    for (i = 0; i <= max_sampler; i++) {
       if (softpipe->samplers[shader][i]) {
-         softpipe->tgsi.samplers_list[shader][i] = 
+         softpipe->tgsi.sampler[shader]->sp_sampler[i] =
             get_sampler_variant(i,
                                 sp_sampler(softpipe->samplers[shader][i]),
                                 softpipe->sampler_views[shader][i],
                                 tgsi_shader);
 
-         sp_sampler_variant_bind_view(softpipe->tgsi.samplers_list[shader][i],
+         sp_sampler_variant_bind_view(softpipe->tgsi.sampler[shader]->sp_sampler[i],
                                       softpipe->tex_cache[shader][i],
                                       softpipe->sampler_views[shader][i]);
       }
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index a4262e3..30ecc6f 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -898,7 +898,7 @@ print_sample_4(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZ
 /* Some image-filter fastpaths:
  */
 static INLINE void
-img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_linear_repeat_POT(struct sp_sampler_variant *samp,
                                 float s,
                                 float t,
                                 float p,
@@ -906,7 +906,6 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
                                 unsigned face_id,
                                 float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    unsigned xpot = pot_level_size(samp->xpot, level);
    unsigned ypot = pot_level_size(samp->ypot, level);
    unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */
@@ -956,7 +955,7 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
 
 
 static INLINE void
-img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_nearest_repeat_POT(struct sp_sampler_variant *samp,
                                  float s,
                                  float t,
                                  float p,
@@ -964,7 +963,6 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
                                  unsigned face_id,
                                  float rgba[TGSI_QUAD_SIZE])
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    unsigned xpot = pot_level_size(samp->xpot, level);
    unsigned ypot = pot_level_size(samp->ypot, level);
    const float *out;
@@ -994,7 +992,7 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
 
 
 static INLINE void
-img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_nearest_clamp_POT(struct sp_sampler_variant *samp,
                                 float s,
                                 float t,
                                 float p,
@@ -1002,7 +1000,6 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
                                 unsigned face_id,
                                 float rgba[TGSI_QUAD_SIZE])
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    unsigned xpot = pot_level_size(samp->xpot, level);
    unsigned ypot = pot_level_size(samp->ypot, level);
    union tex_tile_address addr;
@@ -1040,7 +1037,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
+img_filter_1d_nearest(struct sp_sampler_variant *samp,
                       float s,
                       float t,
                       float p,
@@ -1048,7 +1045,6 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
                       unsigned face_id,
                       float rgba[TGSI_QUAD_SIZE])
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width;
    int x;
@@ -1076,7 +1072,7 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler,
+img_filter_1d_array_nearest(struct sp_sampler_variant *samp,
                             float s,
                             float t,
                             float p,
@@ -1084,7 +1080,6 @@ img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler,
                             unsigned face_id,
                             float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width;
    int x, layer;
@@ -1113,7 +1108,7 @@ img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_nearest(struct sp_sampler_variant *samp,
                       float s,
                       float t,
                       float p,
@@ -1121,7 +1116,6 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
                       unsigned face_id,
                       float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x, y;
@@ -1152,7 +1146,7 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_2d_array_nearest(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_array_nearest(struct sp_sampler_variant *samp,
                             float s,
                             float t,
                             float p,
@@ -1160,7 +1154,6 @@ img_filter_2d_array_nearest(struct tgsi_sampler *tgsi_sampler,
                             unsigned face_id,
                             float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x, y, layer;
@@ -1200,7 +1193,7 @@ face(union tex_tile_address addr, unsigned face )
 
 
 static void
-img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
+img_filter_cube_nearest(struct sp_sampler_variant *samp,
                         float s,
                         float t,
                         float p,
@@ -1208,7 +1201,6 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
                         unsigned face_id,
                         float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x, y;
@@ -1247,7 +1239,7 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
 }
 
 static void
-img_filter_cube_array_nearest(struct tgsi_sampler *tgsi_sampler,
+img_filter_cube_array_nearest(struct sp_sampler_variant *samp,
                         float s,
                         float t,
                         float p,
@@ -1255,7 +1247,6 @@ img_filter_cube_array_nearest(struct tgsi_sampler *tgsi_sampler,
                         unsigned face_id,
                         float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x, y, layer;
@@ -1286,7 +1277,7 @@ img_filter_cube_array_nearest(struct tgsi_sampler *tgsi_sampler,
 }
 
 static void
-img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
+img_filter_3d_nearest(struct sp_sampler_variant *samp,
                       float s,
                       float t,
                       float p,
@@ -1294,7 +1285,6 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
                       unsigned face_id,
                       float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height, depth;
    int x, y, z;
@@ -1324,7 +1314,7 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
+img_filter_1d_linear(struct sp_sampler_variant *samp,
                      float s,
                      float t,
                      float p,
@@ -1332,7 +1322,6 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
                      unsigned face_id,
                      float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width;
    int x0, x1;
@@ -1360,7 +1349,7 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler,
+img_filter_1d_array_linear(struct sp_sampler_variant *samp,
                            float s,
                            float t,
                            float p,
@@ -1368,7 +1357,6 @@ img_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler,
                            unsigned face_id,
                            float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width;
    int x0, x1, layer;
@@ -1397,7 +1385,7 @@ img_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_linear(struct sp_sampler_variant *samp,
                      float s,
                      float t,
                      float p,
@@ -1405,7 +1393,6 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
                      unsigned face_id,
                      float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x0, y0, x1, y1;
@@ -1440,7 +1427,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_array_linear(struct sp_sampler_variant *samp,
                            float s,
                            float t,
                            float p,
@@ -1448,7 +1435,6 @@ img_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler,
                            unsigned face_id,
                            float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x0, y0, x1, y1, layer;
@@ -1484,7 +1470,7 @@ img_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
+img_filter_cube_linear(struct sp_sampler_variant *samp,
                        float s,
                        float t,
                        float p,
@@ -1492,7 +1478,6 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
                        unsigned face_id,
                        float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x0, y0, x1, y1;
@@ -1545,7 +1530,7 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-img_filter_cube_array_linear(struct tgsi_sampler *tgsi_sampler,
+img_filter_cube_array_linear(struct sp_sampler_variant *samp,
                              float s,
                              float t,
                              float p,
@@ -1553,7 +1538,6 @@ img_filter_cube_array_linear(struct tgsi_sampler *tgsi_sampler,
                              unsigned face_id,
                              float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height;
    int x0, y0, x1, y1, layer;
@@ -1588,7 +1572,7 @@ img_filter_cube_array_linear(struct tgsi_sampler *tgsi_sampler,
 }
 
 static void
-img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
+img_filter_3d_linear(struct sp_sampler_variant *samp,
                      float s,
                      float t,
                      float p,
@@ -1596,7 +1580,6 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
                      unsigned face_id,
                      float *rgba)
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
    int width, height, depth;
    int x0, x1, y0, y1, z0, z1;
@@ -1731,7 +1714,7 @@ compute_lambda_lod(struct sp_sampler_variant *samp,
 
 
 static void
-mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
+mip_filter_linear(struct sp_sampler_variant *samp,
                   const float s[TGSI_QUAD_SIZE],
                   const float t[TGSI_QUAD_SIZE],
                   const float p[TGSI_QUAD_SIZE],
@@ -1740,7 +1723,6 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
                   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 lod[TGSI_QUAD_SIZE];
@@ -1751,11 +1733,11 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
       int level0 = samp->view->u.tex.first_level + (int)lod[j];
 
       if (lod[j] < 0.0)
-         samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level,
+         samp->mag_img_filter(samp, s[j], t[j], p[j], samp->view->u.tex.first_level,
                               samp->faces[j], &rgba[0][j]);
 
       else if (level0 >= texture->last_level)
-         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], texture->last_level,
+         samp->min_img_filter(samp, s[j], t[j], p[j], texture->last_level,
                               samp->faces[j], &rgba[0][j]);
 
       else {
@@ -1763,9 +1745,9 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
          float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
          int c;
 
-         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level0,
+         samp->min_img_filter(samp, s[j], t[j], p[j], level0,
                               samp->faces[j], &rgbax[0][0]);
-         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level0+1,
+         samp->min_img_filter(samp, s[j], t[j], p[j], level0+1,
                               samp->faces[j], &rgbax[0][1]);
 
          for (c = 0; c < 4; c++) {
@@ -1786,7 +1768,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
  * \param c0  the LOD bias factors, or absolute LODs (depending on control)
  */
 static void
-mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
+mip_filter_nearest(struct sp_sampler_variant *samp,
                    const float s[TGSI_QUAD_SIZE],
                    const float t[TGSI_QUAD_SIZE],
                    const float p[TGSI_QUAD_SIZE],
@@ -1795,7 +1777,6 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
                    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;
    float lod[TGSI_QUAD_SIZE];
    int j;
@@ -1804,12 +1785,12 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       if (lod[j] < 0.0)
-         samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level,
+         samp->mag_img_filter(samp, s[j], t[j], p[j], samp->view->u.tex.first_level,
                               samp->faces[j], &rgba[0][j]);
       else {
          float level = samp->view->u.tex.first_level + (int)(lod[j] + 0.5F) ;
          level = MIN2(level, (int)texture->last_level);
-         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level, samp->faces[j],
+         samp->min_img_filter(samp, s[j], t[j], p[j], level, samp->faces[j],
                               &rgba[0][j]);
       }
    }
@@ -1821,7 +1802,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-mip_filter_none(struct tgsi_sampler *tgsi_sampler,
+mip_filter_none(struct sp_sampler_variant *samp,
                 const float s[TGSI_QUAD_SIZE],
                 const float t[TGSI_QUAD_SIZE],
                 const float p[TGSI_QUAD_SIZE],
@@ -1830,7 +1811,6 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
                 enum tgsi_sampler_control control,
                 float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
-   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    float lod[TGSI_QUAD_SIZE];
    int j;
 
@@ -1838,11 +1818,11 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
       if (lod[j] < 0.0) { 
-         samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level,
+         samp->mag_img_filter(samp, s[j], t[j], p[j], samp->view->u.tex.first_level,
                               samp->faces[j], &rgba[0][j]);
       }
       else {
-         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level,
+         samp->min_img_filter(samp, s[j], t[j], p[j], samp->view->u.tex.first_level,
                               samp->faces[j], &rgba[0][j]);
       }
    }
@@ -1850,7 +1830,7 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
-mip_filter_none_no_filter_select(struct tgsi_sampler *tgsi_sampler,
+mip_filter_none_no_filter_select(struct sp_sampler_variant *samp,
                                      const float s[TGSI_QUAD_SIZE],
                                      const float t[TGSI_QUAD_SIZE],
                                      const float p[TGSI_QUAD_SIZE],
@@ -1859,11 +1839,10 @@ mip_filter_none_no_filter_select(struct tgsi_sampler *tgsi_sampler,
                                      enum tgsi_sampler_control control,
                                      float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
-   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    int j;
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++)
-      samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level,
+      samp->mag_img_filter(samp, s[j], t[j], p[j], samp->view->u.tex.first_level,
                            samp->faces[j], &rgba[0][j]);
 }
 
@@ -1901,7 +1880,7 @@ create_filter_table(void)
  * "Fundamentals of Texture Mapping and Image Warping" (1989)
  */
 static void
-img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler,
+img_filter_2d_ewa(struct sp_sampler_variant *samp,
                   const float s[TGSI_QUAD_SIZE],
                   const float t[TGSI_QUAD_SIZE],
                   const float p[TGSI_QUAD_SIZE],
@@ -1910,7 +1889,6 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler,
                   const float dudy, const float dvdy,
                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    const struct pipe_resource *texture = samp->view->texture;
 
    // ??? Won't the image filters blow up if level is negative?
@@ -2016,7 +1994,7 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler,
                    * accelerated img_filter_2d_nearest_XXX functions.
                    */
                   for (jj = 0; jj < buffer_next; jj++) {
-                     samp->min_img_filter(tgsi_sampler, s_buffer[jj], t_buffer[jj], p[jj],
+                     samp->min_img_filter(samp, s_buffer[jj], t_buffer[jj], p[jj],
                                           level, samp->faces[j], &rgba_temp[0][jj]);
                      num[0] += weight_buffer[jj] * rgba_temp[0][jj];
                      num[1] += weight_buffer[jj] * rgba_temp[1][jj];
@@ -2044,7 +2022,7 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler,
           * accelerated img_filter_2d_nearest_XXX functions.
           */
          for (jj = 0; jj < buffer_next; jj++) {
-            samp->min_img_filter(tgsi_sampler, s_buffer[jj], t_buffer[jj], p[jj], level,
+            samp->min_img_filter(samp, s_buffer[jj], t_buffer[jj], p[jj], level,
                                  samp->faces[j], &rgba_temp[0][jj]);
             num[0] += weight_buffer[jj] * rgba_temp[0][jj];
             num[1] += weight_buffer[jj] * rgba_temp[1][jj];
@@ -2064,7 +2042,7 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler,
          rgba[2]=0;
          rgba[3]=0;*/
          /* not enough pixels in resampling, resort to direct interpolation */
-         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level, samp->faces[j],
+         samp->min_img_filter(samp, s[j], t[j], p[j], level, samp->faces[j],
                               &rgba_temp[0][j]);
          den = 1;
          num[0] = rgba_temp[0][j];
@@ -2085,7 +2063,7 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler,
  * Sample 2D texture using an anisotropic filter.
  */
 static void
-mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
+mip_filter_linear_aniso(struct sp_sampler_variant *samp,
                         const float s[TGSI_QUAD_SIZE],
                         const float t[TGSI_QUAD_SIZE],
                         const float p[TGSI_QUAD_SIZE],
@@ -2094,7 +2072,6 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
                         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 level0;
    float lambda;
@@ -2164,14 +2141,14 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
    if (level0 >= (int) texture->last_level) {
       int j;
       for (j = 0; j < TGSI_QUAD_SIZE; j++)
-         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], texture->last_level,
+         samp->min_img_filter(samp, s[j], t[j], p[j], texture->last_level,
                               samp->faces[j], &rgba[0][j]);
    }
    else {
       /* don't bother interpolating between multiple LODs; it doesn't
        * seem to be worth the extra running time.
        */
-      img_filter_2d_ewa(tgsi_sampler, s, t, p, level0,
+      img_filter_2d_ewa(samp, s, t, p, level0,
                         dudx, dvdx, dudy, dvdy, rgba);
    }
 
@@ -2187,7 +2164,7 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
  */
 static void
 mip_filter_linear_2d_linear_repeat_POT(
-   struct tgsi_sampler *tgsi_sampler,
+   struct sp_sampler_variant *samp,
    const float s[TGSI_QUAD_SIZE],
    const float t[TGSI_QUAD_SIZE],
    const float p[TGSI_QUAD_SIZE],
@@ -2196,7 +2173,6 @@ mip_filter_linear_2d_linear_repeat_POT(
    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 lod[TGSI_QUAD_SIZE];
@@ -2210,11 +2186,11 @@ mip_filter_linear_2d_linear_repeat_POT(
        */
       if ((unsigned)level0 >= texture->last_level) { 
          if (level0 < 0)
-            img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j],
+            img_filter_2d_linear_repeat_POT(samp, s[j], t[j], p[j],
                                             samp->view->u.tex.first_level,
                                             samp->faces[j], &rgba[0][j]);
          else
-            img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j],
+            img_filter_2d_linear_repeat_POT(samp, s[j], t[j], p[j],
                                             samp->view->texture->last_level,
                                             samp->faces[j], &rgba[0][j]);
 
@@ -2224,9 +2200,9 @@ mip_filter_linear_2d_linear_repeat_POT(
          float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
          int c;
 
-         img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], level0,
+         img_filter_2d_linear_repeat_POT(samp, s[j], t[j], p[j], level0,
                                          samp->faces[j], &rgbax[0][0]);
-         img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], level0+1,
+         img_filter_2d_linear_repeat_POT(samp, s[j], t[j], p[j], level0+1,
                                          samp->faces[j], &rgbax[0][1]);
 
          for (c = 0; c < TGSI_NUM_CHANNELS; c++)
@@ -2244,7 +2220,7 @@ mip_filter_linear_2d_linear_repeat_POT(
  * Do shadow/depth comparisons.
  */
 static void
-sample_compare(struct tgsi_sampler *tgsi_sampler,
+sample_compare(struct sp_sampler_variant *samp,
                const float s[TGSI_QUAD_SIZE],
                const float t[TGSI_QUAD_SIZE],
                const float p[TGSI_QUAD_SIZE],
@@ -2253,13 +2229,12 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
                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_sampler_state *sampler = samp->sampler;
    int j, k0, k1, k2, k3;
    float val;
    float pc0, pc1, pc2, pc3;
 
-   samp->mip_filter(tgsi_sampler, s, t, p, c0, c1, control, rgba);
+   samp->mip_filter(samp, s, t, p, c0, c1, control, rgba);
 
    /**
     * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
@@ -2360,7 +2335,7 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
  * Put face info into the sampler faces[] array.
  */
 static void
-sample_cube(struct tgsi_sampler *tgsi_sampler,
+sample_cube(struct sp_sampler_variant *samp,
             const float s[TGSI_QUAD_SIZE],
             const float t[TGSI_QUAD_SIZE],
             const float p[TGSI_QUAD_SIZE],
@@ -2369,7 +2344,6 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
             enum tgsi_sampler_control control,
             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
-   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    unsigned j;
    float ssss[4], tttt[4];
 
@@ -2449,7 +2423,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
     * is not active, this will point somewhere deeper into the
     * pipeline, eg. to mip_filter or even img_filter.
     */
-   samp->compare(tgsi_sampler, ssss, tttt, pppp, c0, c1, control, rgba);
+   samp->compare(samp, ssss, tttt, pppp, c0, c1, control, rgba);
 }
 
 
@@ -2527,7 +2501,7 @@ do_swizzling(const struct sp_sampler_variant *samp,
 
 
 static void
-sample_swizzle(struct tgsi_sampler *tgsi_sampler,
+sample_swizzle(struct sp_sampler_variant *samp,
                const float s[TGSI_QUAD_SIZE],
                const float t[TGSI_QUAD_SIZE],
                const float p[TGSI_QUAD_SIZE],
@@ -2536,10 +2510,9 @@ sample_swizzle(struct tgsi_sampler *tgsi_sampler,
                enum tgsi_sampler_control control,
                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
-   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
 
-   samp->sample_target(tgsi_sampler, s, t, p, c0, c1, control, rgba_temp);
+   samp->sample_target(samp, s, t, p, c0, c1, control, rgba_temp);
 
    do_swizzling(samp, rgba_temp, rgba);
 }
@@ -2782,10 +2755,9 @@ sp_sampler_variant_destroy( struct sp_sampler_variant *samp )
 
 
 static void
-sample_get_dims(struct tgsi_sampler *tgsi_sampler, int level,
-		int dims[4])
+sample_get_dims(struct sp_sampler_variant *samp, int level,
+                int dims[4])
 {
-    struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
     const struct pipe_sampler_view *view = samp->view;
     const struct pipe_resource *texture = view->texture;
 
@@ -2834,7 +2806,7 @@ sample_get_dims(struct tgsi_sampler *tgsi_sampler, int level,
  * coords to the texture image size.
  */
 static void
-sample_get_texels(struct tgsi_sampler *tgsi_sampler,
+sample_get_texels(struct sp_sampler_variant *samp,
                   const int v_i[TGSI_QUAD_SIZE],
                   const int v_j[TGSI_QUAD_SIZE],
                   const int v_k[TGSI_QUAD_SIZE],
@@ -2842,7 +2814,6 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
                   const int8_t offset[3],
                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
-   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    union tex_tile_address addr;
    const struct pipe_resource *texture = samp->view->texture;
    int j, c;
@@ -3045,13 +3016,80 @@ sp_create_sampler_variant( const struct pipe_sampler_state *sampler,
    }
 
    if (any_swizzle(key)) {
-      samp->base.get_samples = sample_swizzle;
+      samp->get_samples = sample_swizzle;
    }
    else {
-      samp->base.get_samples = samp->sample_target;
+      samp->get_samples = samp->sample_target;
    }
 
-   samp->base.get_dims = sample_get_dims;
-   samp->base.get_texel = sample_get_texels;
+   samp->get_dims = sample_get_dims;
+   samp->get_texel = sample_get_texels;
    return samp;
 }
+
+
+
+static void
+sp_tgsi_get_dims(struct tgsi_sampler *tgsi_sampler,
+                 const unsigned sview_index,
+                 int level, int dims[4])
+{
+   const struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
+
+   assert(sp_samp->sp_sampler[sview_index]);
+   sp_samp->sp_sampler[sview_index]->get_dims(sp_samp->sp_sampler[sview_index],
+                                              level, dims);
+}
+
+
+static void
+sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
+                    const unsigned sview_index,
+                    const unsigned sampler_index,
+                    const float s[TGSI_QUAD_SIZE],
+                    const float t[TGSI_QUAD_SIZE],
+                    const float p[TGSI_QUAD_SIZE],
+                    const float c0[TGSI_QUAD_SIZE],
+                    const float lod[TGSI_QUAD_SIZE],
+                    enum tgsi_sampler_control control,
+                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
+{
+   const struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
+   assert(sview_index < PIPE_MAX_SAMPLERS);
+   assert(sview_index == sampler_index);
+   assert(sp_samp->sp_sampler[sampler_index]);
+   sp_samp->sp_sampler[sview_index]->get_samples(sp_samp->sp_sampler[sampler_index],
+                                                 s, t, p, c0, lod, control, rgba);
+}
+
+
+static void
+sp_tgsi_get_texel(struct tgsi_sampler *tgsi_sampler,
+                  const unsigned sview_index,
+                  const int i[TGSI_QUAD_SIZE],
+                  const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
+                  const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
+                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
+{
+   const struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
+   assert(sview_index < PIPE_MAX_SAMPLERS);
+   assert(sp_samp->sp_sampler[sview_index]);
+   sp_samp->sp_sampler[sview_index]->get_texel(sp_samp->sp_sampler[sview_index],
+                                               i, j, k, lod, offset, rgba);
+}
+
+
+struct sp_tgsi_sampler *
+sp_create_tgsi_sampler(void)
+{
+   struct sp_tgsi_sampler *samp = CALLOC_STRUCT(sp_tgsi_sampler);
+   if (!samp)
+      return NULL;
+
+   samp->base.get_dims = sp_tgsi_get_dims;
+   samp->base.get_samples = sp_tgsi_get_samples;
+   samp->base.get_texel = sp_tgsi_get_texel;
+
+   return samp;
+}
+
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index 421224a..b8ed871 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -44,12 +44,12 @@ typedef void (*wrap_linear_func)(float s,
                                  int *icoord1,
                                  float *w);
 
-typedef float (*compute_lambda_func)(const struct sp_sampler_variant *sampler,
+typedef float (*compute_lambda_func)(const struct sp_sampler_variant *samp,
                                      const float s[TGSI_QUAD_SIZE],
                                      const float t[TGSI_QUAD_SIZE],
                                      const float p[TGSI_QUAD_SIZE]);
 
-typedef void (*img_filter_func)(struct tgsi_sampler *tgsi_sampler,
+typedef void (*img_filter_func)(struct sp_sampler_variant *samp,
                                 float s,
                                 float t,
                                 float p,
@@ -57,7 +57,7 @@ typedef void (*img_filter_func)(struct tgsi_sampler *tgsi_sampler,
                                 unsigned face_id,
                                 float *rgba);
 
-typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler,
+typedef void (*filter_func)(struct sp_sampler_variant *sp_samp,
                             const float s[TGSI_QUAD_SIZE],
                             const float t[TGSI_QUAD_SIZE],
                             const float p[TGSI_QUAD_SIZE],
@@ -67,6 +67,16 @@ typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler,
                             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
 
 
+typedef void (*get_dim_func)(struct sp_sampler_variant *sp_samp,
+                             int level, int dims[4]);
+
+typedef void (*fetch_func)(struct sp_sampler_variant *sp_samp,
+                           const int i[TGSI_QUAD_SIZE],
+                           const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
+                           const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
+                           float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
+
+
 union sp_sampler_key {
    struct {
       unsigned target:5;
@@ -82,13 +92,9 @@ union sp_sampler_key {
    unsigned value;
 };
 
-/**
- * Subclass of tgsi_sampler
- */
+
 struct sp_sampler_variant
 {
-   struct tgsi_sampler base;  /**< base class */
-
    union sp_sampler_key key;
 
    /* The owner of this struct:
@@ -101,8 +107,6 @@ struct sp_sampler_variant
    const struct pipe_sampler_view *view;
    struct softpipe_tex_tile_cache *cache;
 
-   unsigned processor;
-
    /* For sp_get_samples_2d_linear_POT:
     */
    unsigned xpot;
@@ -126,12 +130,29 @@ struct sp_sampler_variant
    filter_func mip_filter;
    filter_func compare;
    filter_func sample_target;
-   
+
+   filter_func get_samples;
+   fetch_func get_texel;
+   get_dim_func get_dims;
+
+
    /* Linked list:
     */
    struct sp_sampler_variant *next;
 };
 
+
+/**
+ * Subclass of tgsi_sampler
+ */
+struct sp_tgsi_sampler
+{
+   struct tgsi_sampler base;  /**< base class */
+   struct sp_sampler_variant *sp_sampler[PIPE_MAX_SAMPLERS];
+
+};
+
+
 struct sp_sampler;
 
 /* Create a sampler variant for a given set of non-orthogonal state.  Currently the 
@@ -163,4 +184,8 @@ sp_get_samples(struct tgsi_sampler *tgsi_sampler,
                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
 
 
+struct sp_tgsi_sampler *
+sp_create_tgsi_sampler(void);
+
+
 #endif /* SP_TEX_SAMPLE_H */
-- 
1.7.9.5



More information about the mesa-dev mailing list