softpipe: fix texel fetch swizzles
authorDave Airlie <airlied@redhat.com>
Fri, 6 Jan 2012 16:28:32 +0000 (16:28 +0000)
committerDave Airlie <airlied@redhat.com>
Wed, 11 Jan 2012 13:49:02 +0000 (13:49 +0000)
This fixes a number of texelFetch swizzle tests, and consoldiates
the swizzle handling in a new function.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/softpipe/sp_tex_sample.c

index 8123d7bfb1abb84bce8092dd8b92c4e9536a2060..f552b5e323760f24ba3ade6e80a10679dbe83858 100644 (file)
@@ -2286,87 +2286,94 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
    samp->compare(tgsi_sampler, ssss, tttt, NULL, c0, control, rgba);
 }
 
-
-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])
+static void do_swizzling(const struct sp_sampler_variant *samp,
+                         float in[NUM_CHANNELS][QUAD_SIZE],
+                         float out[NUM_CHANNELS][QUAD_SIZE])
 {
-   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
-   float rgba_temp[NUM_CHANNELS][QUAD_SIZE];
+   int j;
    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;
+         out[0][j] = 0.0f;
       break;
    case PIPE_SWIZZLE_ONE:
       for (j = 0; j < 4; j++)
-         rgba[0][j] = 1.0f;
+         out[0][j] = 1.0f;
       break;
    default:
       assert(swizzle_r < 4);
       for (j = 0; j < 4; j++)
-         rgba[0][j] = rgba_temp[swizzle_r][j];
+         out[0][j] = in[swizzle_r][j];
    }
 
    switch (swizzle_g) {
    case PIPE_SWIZZLE_ZERO:
       for (j = 0; j < 4; j++)
-         rgba[1][j] = 0.0f;
+         out[1][j] = 0.0f;
       break;
    case PIPE_SWIZZLE_ONE:
       for (j = 0; j < 4; j++)
-         rgba[1][j] = 1.0f;
+         out[1][j] = 1.0f;
       break;
    default:
       assert(swizzle_g < 4);
       for (j = 0; j < 4; j++)
-         rgba[1][j] = rgba_temp[swizzle_g][j];
+         out[1][j] = in[swizzle_g][j];
    }
 
    switch (swizzle_b) {
    case PIPE_SWIZZLE_ZERO:
       for (j = 0; j < 4; j++)
-         rgba[2][j] = 0.0f;
+         out[2][j] = 0.0f;
       break;
    case PIPE_SWIZZLE_ONE:
       for (j = 0; j < 4; j++)
-         rgba[2][j] = 1.0f;
+         out[2][j] = 1.0f;
       break;
    default:
       assert(swizzle_b < 4);
       for (j = 0; j < 4; j++)
-         rgba[2][j] = rgba_temp[swizzle_b][j];
+         out[2][j] = in[swizzle_b][j];
    }
 
    switch (swizzle_a) {
    case PIPE_SWIZZLE_ZERO:
       for (j = 0; j < 4; j++)
-         rgba[3][j] = 0.0f;
+         out[3][j] = 0.0f;
       break;
    case PIPE_SWIZZLE_ONE:
       for (j = 0; j < 4; j++)
-         rgba[3][j] = 1.0f;
+         out[3][j] = 1.0f;
       break;
    default:
       assert(swizzle_a < 4);
       for (j = 0; j < 4; j++)
-         rgba[3][j] = rgba_temp[swizzle_a][j];
+         out[3][j] = in[swizzle_a][j];
    }
 }
 
+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_variant *samp = sp_sampler_variant(tgsi_sampler);
+   float rgba_temp[NUM_CHANNELS][QUAD_SIZE];
+
+   samp->sample_target(tgsi_sampler, s, t, p, c0, control, rgba_temp);
+
+   do_swizzling(samp, rgba_temp, rgba);
+}
+
 
 static wrap_nearest_func
 get_nearest_unorm_wrap(unsigned mode)
@@ -2638,6 +2645,10 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
    const struct pipe_resource *texture = samp->view->texture;
    int j, c;
    const float *tx;
+   bool need_swizzle = (samp->key.bits.swizzle_r != PIPE_SWIZZLE_RED ||
+                        samp->key.bits.swizzle_g != PIPE_SWIZZLE_GREEN ||
+                        samp->key.bits.swizzle_b != PIPE_SWIZZLE_BLUE ||
+                        samp->key.bits.swizzle_a != PIPE_SWIZZLE_ALPHA);
 
    addr.value = 0;
    /* TODO write a better test for LOD */
@@ -2696,6 +2707,12 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
       assert(!"Unknown or CUBE texture type in TXF processing\n");
       break;
    }
+
+   if (need_swizzle) {
+      float rgba_temp[NUM_CHANNELS][QUAD_SIZE];
+      memcpy(rgba_temp, rgba, sizeof(rgba_temp));
+      do_swizzling(samp, rgba_temp, rgba);
+   }
 }
 /**
  * Create a sampler variant for a given set of non-orthogonal state.