softpipe: do texture swizzle during texture sampling
authorBrian Paul <brianp@vmware.com>
Tue, 14 Dec 2010 20:01:00 +0000 (13:01 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 14 Dec 2010 20:01:03 +0000 (13:01 -0700)
Instead of when we read texture tiles.  Now swizzling happens after
the shadow depth compare step.  This fixes the piglit glsl-fs-shadow2d*
tests (except for proj+bias because of a GLSL bug).

src/gallium/drivers/softpipe/sp_state_sampler.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_tex_sample.h
src/gallium/drivers/softpipe/sp_tex_tile_cache.c

index b59fbc33ed67134c21c13e381e182934d27102a3..8972d62cc7e21db73e67a2fa73c4f8fc1a5adf88 100644 (file)
@@ -289,6 +289,7 @@ softpipe_set_geometry_sampler_views(struct pipe_context *pipe,
 static struct sp_sampler_varient *
 get_sampler_varient( unsigned unit,
                      struct sp_sampler *sampler,
+                     struct pipe_sampler_view *view,
                      struct pipe_resource *resource,
                      unsigned processor )
 {
@@ -303,6 +304,10 @@ get_sampler_varient( unsigned unit,
    key.bits.is_pot = sp_texture->pot;
    key.bits.processor = processor;
    key.bits.unit = unit;
+   key.bits.swizzle_r = view->swizzle_r;
+   key.bits.swizzle_g = view->swizzle_g;
+   key.bits.swizzle_b = view->swizzle_b;
+   key.bits.swizzle_a = view->swizzle_a;
    key.bits.pad = 0;
 
    if (sampler->current && 
@@ -347,6 +352,7 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
          softpipe->tgsi.vert_samplers_list[i] = 
             get_sampler_varient( i,
                                  sp_sampler(softpipe->vertex_samplers[i]),
+                                 softpipe->vertex_sampler_views[i],
                                  texture,
                                  TGSI_PROCESSOR_VERTEX );
 
@@ -369,6 +375,7 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
                get_sampler_varient(
                   i,
                   sp_sampler(softpipe->geometry_samplers[i]),
+                  softpipe->geometry_sampler_views[i],
                   texture,
                   TGSI_PROCESSOR_GEOMETRY );
 
@@ -391,6 +398,7 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
          softpipe->tgsi.frag_samplers_list[i] =
             get_sampler_varient( i,
                                  sp_sampler(softpipe->sampler[i]),
+                                 softpipe->sampler_views[i],
                                  texture,
                                  TGSI_PROCESSOR_FRAGMENT );
 
index 2eac4c7a82b73643ca93fba6acaa16c342325bff..acd94f32605629e7d6a261c276679088ddb2b06a 100644 (file)
@@ -1731,6 +1731,86 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
 }
 
 
+static void
+sample_swizzle(struct tgsi_sampler *tgsi_sampler,
+               const float s[QUAD_SIZE],
+               const float t[QUAD_SIZE],
+               const float p[QUAD_SIZE],
+               const float c0[QUAD_SIZE],
+               enum tgsi_sampler_control control,
+               float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+   struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+   float rgba_temp[NUM_CHANNELS][QUAD_SIZE];
+   const unsigned swizzle_r = samp->key.bits.swizzle_r;
+   const unsigned swizzle_g = samp->key.bits.swizzle_g;
+   const unsigned swizzle_b = samp->key.bits.swizzle_b;
+   const unsigned swizzle_a = samp->key.bits.swizzle_a;
+   unsigned j;
+
+   samp->sample_target(tgsi_sampler, s, t, p, c0, control, rgba_temp);
+
+   switch (swizzle_r) {
+   case PIPE_SWIZZLE_ZERO:
+      for (j = 0; j < 4; j++)
+         rgba[0][j] = 0.0f;
+      break;
+   case PIPE_SWIZZLE_ONE:
+      for (j = 0; j < 4; j++)
+         rgba[0][j] = 1.0f;
+      break;
+   default:
+      assert(swizzle_r < 4);
+      for (j = 0; j < 4; j++)
+         rgba[0][j] = rgba_temp[swizzle_r][j];
+   }
+
+   switch (swizzle_g) {
+   case PIPE_SWIZZLE_ZERO:
+      for (j = 0; j < 4; j++)
+         rgba[1][j] = 0.0f;
+      break;
+   case PIPE_SWIZZLE_ONE:
+      for (j = 0; j < 4; j++)
+         rgba[1][j] = 1.0f;
+      break;
+   default:
+      assert(swizzle_g < 4);
+      for (j = 0; j < 4; j++)
+         rgba[1][j] = rgba_temp[swizzle_g][j];
+   }
+
+   switch (swizzle_b) {
+   case PIPE_SWIZZLE_ZERO:
+      for (j = 0; j < 4; j++)
+         rgba[2][j] = 0.0f;
+      break;
+   case PIPE_SWIZZLE_ONE:
+      for (j = 0; j < 4; j++)
+         rgba[2][j] = 1.0f;
+      break;
+   default:
+      assert(swizzle_b < 4);
+      for (j = 0; j < 4; j++)
+         rgba[2][j] = rgba_temp[swizzle_b][j];
+   }
+
+   switch (swizzle_a) {
+   case PIPE_SWIZZLE_ZERO:
+      for (j = 0; j < 4; j++)
+         rgba[3][j] = 0.0f;
+      break;
+   case PIPE_SWIZZLE_ONE:
+      for (j = 0; j < 4; j++)
+         rgba[3][j] = 1.0f;
+      break;
+   default:
+      assert(swizzle_a < 4);
+      for (j = 0; j < 4; j++)
+         rgba[3][j] = rgba_temp[swizzle_a][j];
+   }
+}
+
 
 static wrap_nearest_func
 get_nearest_unorm_wrap(unsigned mode)
@@ -2015,7 +2095,7 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
    }
    
    if (key.bits.target == PIPE_TEXTURE_CUBE) {
-      samp->base.get_samples = sample_cube;
+      samp->sample_target = sample_cube;
    }
    else {
       samp->faces[0] = 0;
@@ -2026,7 +2106,17 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
       /* Skip cube face determination by promoting the compare
        * function pointer:
        */
-      samp->base.get_samples = samp->compare;
+      samp->sample_target = samp->compare;
+   }
+
+   if (key.bits.swizzle_r != PIPE_SWIZZLE_RED ||
+       key.bits.swizzle_g != PIPE_SWIZZLE_GREEN ||
+       key.bits.swizzle_b != PIPE_SWIZZLE_BLUE ||
+       key.bits.swizzle_a != PIPE_SWIZZLE_ALPHA) {
+      samp->base.get_samples = sample_swizzle;
+   }
+   else {
+      samp->base.get_samples = samp->sample_target;
    }
 
    return samp;
index 6114acf73717d0d35a1122aead3f706a47645ee9..0f471a98270fbf4f410bbd2c097512992bc20c26 100644 (file)
@@ -64,7 +64,11 @@ union sp_sampler_key {
       unsigned is_pot:1;
       unsigned processor:2;
       unsigned unit:4;
-      unsigned pad:22;
+      unsigned swizzle_r:3;
+      unsigned swizzle_g:3;
+      unsigned swizzle_b:3;
+      unsigned swizzle_a:3;
+      unsigned pad:10;
    } bits;
    unsigned value;
 };
@@ -113,6 +117,7 @@ struct sp_sampler_varient
 
    filter_func mip_filter;
    filter_func compare;
+   filter_func sample_target;
    
    /* Linked list:
     */
index 1393164150e71688e878efb6ca0150662b9513d2..e5708a1c88a35126e24d4da2deb6006e7242b742 100644 (file)
@@ -279,18 +279,14 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
       }
 
       /* get tile from the transfer (view into texture) */
-      pipe_get_tile_swizzle(tc->pipe,
-                           tc->tex_trans,
-                            addr.bits.x * TILE_SIZE, 
-                            addr.bits.y * TILE_SIZE,
-                            TILE_SIZE,
-                            TILE_SIZE,
-                            tc->swizzle_r,
-                            tc->swizzle_g,
-                            tc->swizzle_b,
-                            tc->swizzle_a,
-                            tc->format,
-                            (float *) tile->data.color);
+      pipe_get_tile_rgba(tc->pipe,
+                         tc->tex_trans,
+                         addr.bits.x * TILE_SIZE, 
+                         addr.bits.y * TILE_SIZE,
+                         TILE_SIZE,
+                         TILE_SIZE,
+                         (float *) tile->data.color);
+                         
       tile->addr = addr;
    }