summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/softpipe/sp_tex_sample.c
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-12-14 13:01:00 -0700
committerBrian Paul <brianp@vmware.com>2010-12-14 13:01:03 -0700
commitc62bb90d6a864468fe1a717aebb9c1a9c43bf3c8 (patch)
tree22fef0c50d5e49f8dcf379b224ecf2c023c99492 /src/gallium/drivers/softpipe/sp_tex_sample.c
parentbe2aa81f5f8f44be8c9c8854098d29635352c4f8 (diff)
softpipe: do texture swizzle during texture sampling
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).
Diffstat (limited to 'src/gallium/drivers/softpipe/sp_tex_sample.c')
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c94
1 files changed, 92 insertions, 2 deletions
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 2eac4c7a82..acd94f3260 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -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;