diff options
| author | Keith Whitwell <keithw@vmware.com> | 2009-08-20 18:36:57 +0100 | 
|---|---|---|
| committer | Keith Whitwell <keithw@vmware.com> | 2009-08-20 18:36:57 +0100 | 
| commit | 00c835918259f8d41c3f74eca679a972713b11b2 (patch) | |
| tree | f2dc09454abd960fdcc12451181d97b6978d6e09 /src | |
| parent | 0d9979d9ec5b931856d29c4ec44edb1f4931d1ac (diff) | |
softpipe: allow the existing sampler routines to be hooked up directly
Let eg. sp_get_samples_rect be hooked directly in as the tgsi sampler
routine.
Add a field to determine whether this is a vertex or fragment sampling
call, and massage parameters to match the tgsi call.
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_context.c | 6 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_state_derived.c | 3 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 193 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.h | 21 | 
4 files changed, 94 insertions, 129 deletions
| diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index e35c6b3aec..a0196955c8 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -230,14 +230,16 @@ softpipe_create( struct pipe_screen *screen )     /* vertex shader samplers */     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex; +      softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples; +      softpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX;        softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i];        softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i];     }     /* fragment shader samplers */     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment; +      softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples; +      softpipe->tgsi.frag_samplers[i].processor = TGSI_PROCESSOR_FRAGMENT;        softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i];        softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i];     } diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 3ed1de7e17..1f6e2ccb83 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -202,13 +202,14 @@ update_tgsi_samplers( struct softpipe_context *softpipe )     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {        softpipe->tgsi.vert_samplers[i].sampler = softpipe->sampler[i];        softpipe->tgsi.vert_samplers[i].texture = softpipe->texture[i]; +      softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples;     }     /* fragment shader samplers */     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {        softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i];        softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i]; -      softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment; +      softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples;     }     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 2987548fb3..6c75158d59 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -41,6 +41,7 @@  #include "sp_tile_cache.h"  #include "pipe/p_context.h"  #include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h"  #include "util/u_math.h"  #include "util/u_memory.h" @@ -521,15 +522,20 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)   * This is only done for fragment shaders, not vertex shaders.   */  static float -compute_lambda(const struct pipe_texture *tex, -               const struct pipe_sampler_state *sampler, +compute_lambda(struct tgsi_sampler *tgsi_sampler,                 const float s[QUAD_SIZE],                 const float t[QUAD_SIZE],                 const float p[QUAD_SIZE],                 float lodbias)  { +   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); +   const struct pipe_texture *texture = samp->texture; +   const struct pipe_sampler_state *sampler = samp->sampler;     float rho, lambda; +   if (samp->processor == TGSI_PROCESSOR_VERTEX) +      return lodbias; +     assert(sampler->normalized_coords);     assert(s); @@ -538,7 +544,7 @@ compute_lambda(const struct pipe_texture *tex,        float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];        dsdx = fabsf(dsdx);        dsdy = fabsf(dsdy); -      rho = MAX2(dsdx, dsdy) * tex->width[0]; +      rho = MAX2(dsdx, dsdy) * texture->width[0];     }     if (t) {        float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; @@ -546,7 +552,7 @@ compute_lambda(const struct pipe_texture *tex,        float max;        dtdx = fabsf(dtdx);        dtdy = fabsf(dtdy); -      max = MAX2(dtdx, dtdy) * tex->height[0]; +      max = MAX2(dtdx, dtdy) * texture->height[0];        rho = MAX2(rho, max);     }     if (p) { @@ -555,7 +561,7 @@ compute_lambda(const struct pipe_texture *tex,        float max;        dpdx = fabsf(dpdx);        dpdy = fabsf(dpdy); -      max = MAX2(dpdx, dpdy) * tex->depth[0]; +      max = MAX2(dpdx, dpdy) * texture->depth[0];        rho = MAX2(rho, max);     } @@ -579,16 +585,18 @@ compute_lambda(const struct pipe_texture *tex,   * \param imgFilter  Returns either the min or mag filter, depending on lambda   */  static void -choose_mipmap_levels(const struct pipe_texture *texture, -                     const struct pipe_sampler_state *sampler, +choose_mipmap_levels(struct tgsi_sampler *tgsi_sampler,                       const float s[QUAD_SIZE],                       const float t[QUAD_SIZE],                       const float p[QUAD_SIZE], -                     boolean computeLambda,                       float lodbias,                       unsigned *level0, unsigned *level1, float *levelBlend,                       unsigned *imgFilter)  { +   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); +   const struct pipe_texture *texture = samp->texture; +   const struct pipe_sampler_state *sampler = samp->sampler; +     if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {        /* no mipmap selection needed */        *level0 = *level1 = CLAMP((int) sampler->min_lod, @@ -598,7 +606,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,           /* non-mipmapped texture, but still need to determine if doing            * minification or magnification.            */ -         float lambda = compute_lambda(texture, sampler, s, t, p, lodbias); +         float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);           if (lambda <= 0.0) {              *imgFilter = sampler->mag_img_filter;           } @@ -611,14 +619,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,        }     }     else { -      float lambda; - -      if (computeLambda) -         /* fragment shader */ -         lambda = compute_lambda(texture, sampler, s, t, p, lodbias); -      else -         /* vertex shader */ -         lambda = lodbias; /* not really a bias, but absolute LOD */ +      float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);        if (lambda <= 0.0) { /* XXX threshold depends on the filter */           /* magnifying */ @@ -1028,11 +1029,10 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler  {     struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);     const struct pipe_texture *texture = samp->texture; -   const struct pipe_sampler_state *sampler = samp->sampler;     int level0;     float lambda; -   lambda = compute_lambda(texture, sampler, s, t, p, lodbias); +   lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);     level0 = (int)lambda;     if (lambda < 0.0) {  @@ -1072,11 +1072,10 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler   * Could probably extend for 3D...   */  static void -sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, +sp_get_samples_2d_common(struct tgsi_sampler *tgsi_sampler,                           const float s[QUAD_SIZE],                           const float t[QUAD_SIZE],                           const float p[QUAD_SIZE], -                         boolean computeLambda,                           float lodbias,                           float rgba[NUM_CHANNELS][QUAD_SIZE],                           const unsigned faces[4]) @@ -1088,7 +1087,8 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,     int width, height;     float levelBlend; -   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, +   choose_mipmap_levels(tgsi_sampler, s, t, p,  +                        lodbias,                          &level0, &level1, &levelBlend, &imgFilter);     assert(sampler->normalized_coords); @@ -1199,42 +1199,39 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,  static INLINE void -sp_get_samples_1d(const struct tgsi_sampler *sampler, +sp_get_samples_1d(struct tgsi_sampler *sampler,                    const float s[QUAD_SIZE],                    const float t[QUAD_SIZE],                    const float p[QUAD_SIZE], -                  boolean computeLambda,                    float lodbias,                    float rgba[NUM_CHANNELS][QUAD_SIZE])  {     static const unsigned faces[4] = {0, 0, 0, 0};     static const float tzero[4] = {0, 0, 0, 0};     sp_get_samples_2d_common(sampler, s, tzero, NULL, -                            computeLambda, lodbias, rgba, faces); +                            lodbias, rgba, faces);  }  static INLINE void -sp_get_samples_2d(const struct tgsi_sampler *sampler, +sp_get_samples_2d(struct tgsi_sampler *sampler,                    const float s[QUAD_SIZE],                    const float t[QUAD_SIZE],                    const float p[QUAD_SIZE], -                  boolean computeLambda,                    float lodbias,                    float rgba[NUM_CHANNELS][QUAD_SIZE])  {     static const unsigned faces[4] = {0, 0, 0, 0};     sp_get_samples_2d_common(sampler, s, t, p, -                            computeLambda, lodbias, rgba, faces); +                            lodbias, rgba, faces);  }  static INLINE void -sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, +sp_get_samples_3d(struct tgsi_sampler *tgsi_sampler,                    const float s[QUAD_SIZE],                    const float t[QUAD_SIZE],                    const float p[QUAD_SIZE], -                  boolean computeLambda,                    float lodbias,                    float rgba[NUM_CHANNELS][QUAD_SIZE])  { @@ -1247,7 +1244,8 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,     float levelBlend;     const uint face = 0; -   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, +   choose_mipmap_levels(tgsi_sampler, s, t, p,  +                        lodbias,                          &level0, &level1, &levelBlend, &imgFilter);     assert(sampler->normalized_coords); @@ -1356,11 +1354,10 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,  static void -sp_get_samples_cube(const struct tgsi_sampler *sampler, +sp_get_samples_cube(struct tgsi_sampler *sampler,                      const float s[QUAD_SIZE],                      const float t[QUAD_SIZE],                      const float p[QUAD_SIZE], -                    boolean computeLambda,                      float lodbias,                      float rgba[NUM_CHANNELS][QUAD_SIZE])  { @@ -1370,16 +1367,15 @@ sp_get_samples_cube(const struct tgsi_sampler *sampler,        faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);     }     sp_get_samples_2d_common(sampler, ssss, tttt, NULL, -                            computeLambda, lodbias, rgba, faces); +                            lodbias, rgba, faces);  }  static void -sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, +sp_get_samples_rect(struct tgsi_sampler *tgsi_sampler,                      const float s[QUAD_SIZE],                      const float t[QUAD_SIZE],                      const float p[QUAD_SIZE], -                    boolean computeLambda,                      float lodbias,                      float rgba[NUM_CHANNELS][QUAD_SIZE])  { @@ -1391,7 +1387,8 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,     int width, height;     float levelBlend; -   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, +   choose_mipmap_levels(tgsi_sampler, s, t, p,  +                        lodbias,                          &level0, &level1, &levelBlend, &imgFilter);     /* texture RECTS cannot be mipmapped */ @@ -1447,90 +1444,77 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,  /** - * Common code for vertex/fragment program texture sampling. + * Error condition handler   */  static INLINE void +sp_get_samples_null(struct tgsi_sampler *tgsi_sampler, +                    const float s[QUAD_SIZE], +                    const float t[QUAD_SIZE], +                    const float p[QUAD_SIZE], +                    float lodbias, +                    float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ +   int i,j; + +   for (i = 0; i < 4; i++) +      for (j = 0; j < 4; j++) +         rgba[i][j] = 1.0; +} + +/** + * Called via tgsi_sampler::get_samples() when using a sampler for the + * first time.  Determine the actual sampler function, link it in and + * call it. + */ +void  sp_get_samples(struct tgsi_sampler *tgsi_sampler,                 const float s[QUAD_SIZE],                 const float t[QUAD_SIZE],                 const float p[QUAD_SIZE], -               boolean computeLambda,                 float lodbias,                 float rgba[NUM_CHANNELS][QUAD_SIZE])  { -   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); +   struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);     const struct pipe_texture *texture = samp->texture;     const struct pipe_sampler_state *sampler = samp->sampler; -   if (!texture) -      return; +   /* Default to the 'undefined' case: +    */ +   tgsi_sampler->get_samples = sp_get_samples_null; + +   if (!texture) { +      assert(0);                /* is this legal?? */ +      goto out; +   } + +   if (!sampler->normalized_coords) { +      assert (texture->target == PIPE_TEXTURE_2D); +      tgsi_sampler->get_samples = sp_get_samples_rect; +      goto out; +   }     switch (texture->target) {     case PIPE_TEXTURE_1D: -      assert(sampler->normalized_coords); -      sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); +      tgsi_sampler->get_samples = sp_get_samples_1d;        break;     case PIPE_TEXTURE_2D: -      if (sampler->normalized_coords) -         sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); -      else -         sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); +      tgsi_sampler->get_samples = sp_get_samples_2d;        break;     case PIPE_TEXTURE_3D: -      assert(sampler->normalized_coords); -      sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); +      tgsi_sampler->get_samples = sp_get_samples_3d;        break;     case PIPE_TEXTURE_CUBE: -      assert(sampler->normalized_coords); -      sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); +      tgsi_sampler->get_samples = sp_get_samples_cube;        break;     default:        assert(0); +      break;     } -#if 0 /* DEBUG */ -   { -      int i; -      printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); -      for (i = 0; i < 4; i++) { -         printf("Frag %d: %f %f %f %f\n", i, -                rgba[0][i], -                rgba[1][i], -                rgba[2][i], -                rgba[3][i]); -      } -   } -#endif -} - -static void -sp_get_samples_fallback(struct tgsi_sampler *tgsi_sampler, -                        const float s[QUAD_SIZE], -                        const float t[QUAD_SIZE], -                        const float p[QUAD_SIZE], -                        float lodbias, -                        float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ -   sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba); -} - -/** - * Called via tgsi_sampler::get_samples() when running a fragment shader. - * Get four filtered RGBA values from the sampler's texture. - */ -void -sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, -                        const float s[QUAD_SIZE], -                        const float t[QUAD_SIZE], -                        const float p[QUAD_SIZE], -                        float lodbias, -                        float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ -   struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); -   const struct pipe_texture *texture = samp->texture; -   const struct pipe_sampler_state *sampler = samp->sampler; - -   tgsi_sampler->get_samples = sp_get_samples_fallback; +   /* Do this elsewhere:  +    */ +   samp->xpot = util_unsigned_logbase2( samp->texture->width[0] ); +   samp->ypot = util_unsigned_logbase2( samp->texture->height[0] );     /* Try to hook in a faster sampler.  Ultimately we'll have to      * code-generate these.  Luckily most of this looks like it is @@ -1542,9 +1526,6 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,         sampler->compare_mode == FALSE &&         sampler->normalized_coords)      { -      samp->xpot = util_unsigned_logbase2( samp->texture->width[0] ); -      samp->ypot = util_unsigned_logbase2( samp->texture->height[0] ); -        if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {           samp->level = CLAMP((int) sampler->min_lod,                               0, (int) texture->last_level); @@ -1593,21 +1574,7 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,                      sampler->normalized_coords, TRUE);     } +out:     tgsi_sampler->get_samples( tgsi_sampler, s, t, p, lodbias, rgba );  } - -/** - * Called via tgsi_sampler::get_samples() when running a vertex shader. - * Get four filtered RGBA values from the sampler's texture. - */ -void -sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler, -                      const float s[QUAD_SIZE], -                      const float t[QUAD_SIZE], -                      const float p[QUAD_SIZE], -                      float lodbias, -                      float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ -   sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba); -} diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 0650c7830b..c73ae44131 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -39,6 +39,8 @@ struct sp_shader_sampler  {     struct tgsi_sampler base;  /**< base class */ +   unsigned processor; +     /* For sp_get_samples_2d_linear_POT:      */     unsigned xpot; @@ -60,21 +62,14 @@ sp_shader_sampler(const struct tgsi_sampler *sampler)  } -extern void -sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, -                        const float s[QUAD_SIZE], -                        const float t[QUAD_SIZE], -                        const float p[QUAD_SIZE], -                        float lodbias, -                        float rgba[NUM_CHANNELS][QUAD_SIZE]);  extern void -sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler, -                      const float s[QUAD_SIZE], -                      const float t[QUAD_SIZE], -                      const float p[QUAD_SIZE], -                      float lodbias, -                      float rgba[NUM_CHANNELS][QUAD_SIZE]); +sp_get_samples(struct tgsi_sampler *tgsi_sampler, +               const float s[QUAD_SIZE], +               const float t[QUAD_SIZE], +               const float p[QUAD_SIZE], +               float lodbias, +               float rgba[NUM_CHANNELS][QUAD_SIZE]);  #endif /* SP_TEX_SAMPLE_H */ | 
