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

Jose Fonseca jfonseca at vmware.com
Wed Feb 27 05:12:58 PST 2013


Looks like a step in the right direction to me.

Jose

----- Original Message -----
> 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