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).
This commit is contained in:
Brian Paul 2010-12-14 13:01:00 -07:00
parent be2aa81f5f
commit c62bb90d6a
4 changed files with 114 additions and 15 deletions

View 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 );

View 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;

View 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:
*/

View 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;
}