diff options
author | Olivier Galibert <[email protected]> | 2012-06-19 21:01:37 +0200 |
---|---|---|
committer | Brian Paul <[email protected]> | 2012-07-18 08:02:39 -0600 |
commit | 229a1a7e4da1a9c60b35b79f2a63e0bab451a76e (patch) | |
tree | 312277c6cd59a45eef2309f194133507edd17c7e | |
parent | 99c65bac341f808279a8a847158ace4f058aa72e (diff) |
softpipe: Take all lods into account when texture sampling.
This patch churns a lot because it needs to change 4-wide filters into
single pixel filters, since each fragment may use a different filter.
The only case not entirely supported is the anisotropic filtering.
Not sure what we want to do there, since a full quad is required by
that filter.
Signed-off-by: Olivier Galibert <[email protected]>
Reviewed-by: Brian Paul <[email protected]>
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 1383 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.h | 28 |
2 files changed, 645 insertions, 766 deletions
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index f29a6c75fe7..292dc6e8d71 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -129,313 +129,263 @@ repeat(int coord, unsigned size) * \return integer texture index */ static void -wrap_nearest_repeat(const float s[4], unsigned size, int icoord[4]) +wrap_nearest_repeat(float s, unsigned size, int *icoord) { - uint ch; /* s limited to [0,1) */ /* i limited to [0,size-1] */ - for (ch = 0; ch < 4; ch++) { - int i = util_ifloor(s[ch] * size); - icoord[ch] = repeat(i, size); - } + int i = util_ifloor(s * size); + *icoord = repeat(i, size); } static void -wrap_nearest_clamp(const float s[4], unsigned size, int icoord[4]) +wrap_nearest_clamp(float s, unsigned size, int *icoord) { - uint ch; /* s limited to [0,1] */ /* i limited to [0,size-1] */ - for (ch = 0; ch < 4; ch++) { - if (s[ch] <= 0.0F) - icoord[ch] = 0; - else if (s[ch] >= 1.0F) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(s[ch] * size); - } + if (s <= 0.0F) + *icoord = 0; + else if (s >= 1.0F) + *icoord = size - 1; + else + *icoord = util_ifloor(s * size); } static void -wrap_nearest_clamp_to_edge(const float s[4], unsigned size, int icoord[4]) +wrap_nearest_clamp_to_edge(float s, unsigned size, int *icoord) { - uint ch; /* s limited to [min,max] */ /* i limited to [0, size-1] */ const float min = 1.0F / (2.0F * size); const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - if (s[ch] < min) - icoord[ch] = 0; - else if (s[ch] > max) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(s[ch] * size); - } + if (s < min) + *icoord = 0; + else if (s > max) + *icoord = size - 1; + else + *icoord = util_ifloor(s * size); } static void -wrap_nearest_clamp_to_border(const float s[4], unsigned size, int icoord[4]) +wrap_nearest_clamp_to_border(float s, unsigned size, int *icoord) { - uint ch; /* s limited to [min,max] */ /* i limited to [-1, size] */ const float min = -1.0F / (2.0F * size); const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - if (s[ch] <= min) - icoord[ch] = -1; - else if (s[ch] >= max) - icoord[ch] = size; - else - icoord[ch] = util_ifloor(s[ch] * size); - } + if (s <= min) + *icoord = -1; + else if (s >= max) + *icoord = size; + else + *icoord = util_ifloor(s * size); } static void -wrap_nearest_mirror_repeat(const float s[4], unsigned size, int icoord[4]) +wrap_nearest_mirror_repeat(float s, unsigned size, int *icoord) { - uint ch; const float min = 1.0F / (2.0F * size); const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - const int flr = util_ifloor(s[ch]); - float u = frac(s[ch]); - if (flr & 1) - u = 1.0F - u; - if (u < min) - icoord[ch] = 0; - else if (u > max) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(u * size); - } + const int flr = util_ifloor(s); + float u = frac(s); + if (flr & 1) + u = 1.0F - u; + if (u < min) + *icoord = 0; + else if (u > max) + *icoord = size - 1; + else + *icoord = util_ifloor(u * size); } static void -wrap_nearest_mirror_clamp(const float s[4], unsigned size, int icoord[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - /* s limited to [0,1] */ - /* i limited to [0,size-1] */ - const float u = fabsf(s[ch]); - if (u <= 0.0F) - icoord[ch] = 0; - else if (u >= 1.0F) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(u * size); - } +wrap_nearest_mirror_clamp(float s, unsigned size, int *icoord) +{ + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + const float u = fabsf(s); + if (u <= 0.0F) + *icoord = 0; + else if (u >= 1.0F) + *icoord = size - 1; + else + *icoord = util_ifloor(u * size); } static void -wrap_nearest_mirror_clamp_to_edge(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int *icoord) { - uint ch; /* s limited to [min,max] */ /* i limited to [0, size-1] */ const float min = 1.0F / (2.0F * size); const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - const float u = fabsf(s[ch]); - if (u < min) - icoord[ch] = 0; - else if (u > max) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(u * size); - } + const float u = fabsf(s); + if (u < min) + *icoord = 0; + else if (u > max) + *icoord = size - 1; + else + *icoord = util_ifloor(u * size); } static void -wrap_nearest_mirror_clamp_to_border(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord) { - uint ch; /* s limited to [min,max] */ /* i limited to [0, size-1] */ const float min = -1.0F / (2.0F * size); const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - const float u = fabsf(s[ch]); - if (u < min) - icoord[ch] = -1; - else if (u > max) - icoord[ch] = size; - else - icoord[ch] = util_ifloor(u * size); - } + const float u = fabsf(s); + if (u < min) + *icoord = -1; + else if (u > max) + *icoord = size; + else + *icoord = util_ifloor(u * size); } /** - * Used to compute texel locations for linear sampling for four texcoords. + * Used to compute texel locations for linear sampling * \param wrapMode PIPE_TEX_WRAP_x - * \param s the texcoords + * \param s the texcoord * \param size the texture image size - * \param icoord0 returns first texture indexes - * \param icoord1 returns second texture indexes (usually icoord0 + 1) - * \param w returns blend factor/weight between texture indexes - * \param icoord returns the computed integer texture coords + * \param icoord0 returns first texture index + * \param icoord1 returns second texture index (usually icoord0 + 1) + * \param w returns blend factor/weight between texture indices + * \param icoord returns the computed integer texture coord */ static void -wrap_linear_repeat(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = s[ch] * size - 0.5F; - icoord0[ch] = repeat(util_ifloor(u), size); - icoord1[ch] = repeat(icoord0[ch] + 1, size); - w[ch] = frac(u); - } +wrap_linear_repeat(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + float u = s * size - 0.5F; + *icoord0 = repeat(util_ifloor(u), size); + *icoord1 = repeat(*icoord0 + 1, size); + *w = frac(u); } static void -wrap_linear_clamp(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], 0.0F, 1.0F); - u = u * size - 0.5f; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = frac(u); - } +wrap_linear_clamp(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + float u = CLAMP(s, 0.0F, 1.0F); + u = u * size - 0.5f; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + *w = frac(u); } static void -wrap_linear_clamp_to_edge(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], 0.0F, 1.0F); - u = u * size - 0.5f; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord0[ch] < 0) - icoord0[ch] = 0; - if (icoord1[ch] >= (int) size) - icoord1[ch] = size - 1; - w[ch] = frac(u); - } +wrap_linear_clamp_to_edge(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + float u = CLAMP(s, 0.0F, 1.0F); + u = u * size - 0.5f; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + if (*icoord0 < 0) + *icoord0 = 0; + if (*icoord1 >= (int) size) + *icoord1 = size - 1; + *w = frac(u); } static void -wrap_linear_clamp_to_border(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) +wrap_linear_clamp_to_border(float s, unsigned size, + int *icoord0, int *icoord1, float *w) { const float min = -1.0F / (2.0F * size); const float max = 1.0F - min; - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], min, max); - u = u * size - 0.5f; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = frac(u); - } + float u = CLAMP(s, min, max); + u = u * size - 0.5f; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + *w = frac(u); } static void -wrap_linear_mirror_repeat(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - const int flr = util_ifloor(s[ch]); - float u = frac(s[ch]); - if (flr & 1) - u = 1.0F - u; - u = u * size - 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord0[ch] < 0) - icoord0[ch] = 0; - if (icoord1[ch] >= (int) size) - icoord1[ch] = size - 1; - w[ch] = frac(u); - } +wrap_linear_mirror_repeat(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + const int flr = util_ifloor(s); + float u = frac(s); + if (flr & 1) + u = 1.0F - u; + u = u * size - 0.5F; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + if (*icoord0 < 0) + *icoord0 = 0; + if (*icoord1 >= (int) size) + *icoord1 = size - 1; + *w = frac(u); } static void -wrap_linear_mirror_clamp(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = fabsf(s[ch]); - if (u >= 1.0F) - u = (float) size; - else - u *= size; - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = frac(u); - } +wrap_linear_mirror_clamp(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + float u = fabsf(s); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + *w = frac(u); } static void -wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = fabsf(s[ch]); - if (u >= 1.0F) - u = (float) size; - else - u *= size; - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord0[ch] < 0) - icoord0[ch] = 0; - if (icoord1[ch] >= (int) size) - icoord1[ch] = size - 1; - w[ch] = frac(u); - } +wrap_linear_mirror_clamp_to_edge(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + float u = fabsf(s); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + if (*icoord0 < 0) + *icoord0 = 0; + if (*icoord1 >= (int) size) + *icoord1 = size - 1; + *w = frac(u); } static void -wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) +wrap_linear_mirror_clamp_to_border(float s, unsigned size, + int *icoord0, int *icoord1, float *w) { const float min = -1.0F / (2.0F * size); const float max = 1.0F - min; - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = fabsf(s[ch]); - if (u <= min) - u = min * size; - else if (u >= max) - u = max * size; - else - u *= size; - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = frac(u); - } + float u = fabsf(s); + if (u <= min) + u = min * size; + else if (u >= max) + u = max * size; + else + u *= size; + u -= 0.5F; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + *w = frac(u); } @@ -443,13 +393,10 @@ wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size, * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords. */ static void -wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4]) +wrap_nearest_unorm_clamp(float s, unsigned size, int *icoord) { - uint ch; - for (ch = 0; ch < 4; ch++) { - int i = util_ifloor(s[ch]); - icoord[ch]= CLAMP(i, 0, (int) size-1); - } + int i = util_ifloor(s); + *icoord = CLAMP(i, 0, (int) size-1); } @@ -457,13 +404,9 @@ wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4]) * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords. */ static void -wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord) { - uint ch; - for (ch = 0; ch < 4; ch++) { - icoord[ch]= util_ifloor( CLAMP(s[ch], -0.5F, (float) size + 0.5F) ); - } + *icoord = util_ifloor( CLAMP(s, -0.5F, (float) size + 0.5F) ); } @@ -471,13 +414,9 @@ wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size, * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords. */ static void -wrap_nearest_unorm_clamp_to_edge(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord) { - uint ch; - for (ch = 0; ch < 4; ch++) { - icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) ); - } + *icoord = util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); } @@ -485,17 +424,14 @@ wrap_nearest_unorm_clamp_to_edge(const float s[4], unsigned size, * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords. */ static void -wrap_linear_unorm_clamp(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - /* Not exactly what the spec says, but it matches NVIDIA output */ - float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f); - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = frac(u); - } +wrap_linear_unorm_clamp(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + /* Not exactly what the spec says, but it matches NVIDIA output */ + float u = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f); + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + *w = frac(u); } @@ -503,19 +439,16 @@ wrap_linear_unorm_clamp(const float s[4], unsigned size, * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords. */ static void -wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], -0.5F, (float) size + 0.5F); - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord1[ch] > (int) size - 1) - icoord1[ch] = size - 1; - w[ch] = frac(u); - } +wrap_linear_unorm_clamp_to_border(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + float u = CLAMP(s, -0.5F, (float) size + 0.5F); + u -= 0.5F; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + if (*icoord1 > (int) size - 1) + *icoord1 = size - 1; + *w = frac(u); } @@ -523,19 +456,16 @@ wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size, * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords. */ static void -wrap_linear_unorm_clamp_to_edge(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) -{ - uint ch; - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], +0.5F, (float) size - 0.5F); - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord1[ch] > (int) size - 1) - icoord1[ch] = size - 1; - w[ch] = frac(u); - } +wrap_linear_unorm_clamp_to_edge(float s, unsigned size, + int *icoord0, int *icoord1, float *w) +{ + float u = CLAMP(s, +0.5F, (float) size - 0.5F); + u -= 0.5F; + *icoord0 = util_ifloor(u); + *icoord1 = *icoord0 + 1; + if (*icoord1 > (int) size - 1) + *icoord1 = size - 1; + *w = frac(u); } @@ -543,13 +473,10 @@ wrap_linear_unorm_clamp_to_edge(const float s[4], unsigned size, * Do coordinate to array index conversion. For array textures. */ static INLINE void -wrap_array_layer(const float coord[4], unsigned size, int layer[4]) +wrap_array_layer(float coord, unsigned size, int *layer) { - uint ch; - for (ch = 0; ch < 4; ch++) { - int c = util_ifloor(coord[ch] + 0.5F); - layer[ch] = CLAMP(c, 0, size - 1); - } + int c = util_ifloor(coord + 0.5F); + *layer = CLAMP(c, 0, size - 1); } @@ -640,7 +567,7 @@ compute_lambda_vert(const struct sp_sampler_variant *samp, * \param rgba the quad to put the texel/color into * * XXX maybe move this into sp_tex_tile_cache.c and merge with the - * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... + * sp_get_cached_tile_tex() function. */ @@ -827,7 +754,16 @@ pot_level_size(unsigned base_pot, unsigned level) static void -print_sample(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) +print_sample(const char *function, const float *rgba) +{ + debug_printf("%s %g %g %g %g\n", + function, + rgba[0], rgba[TGSI_NUM_CHANNELS], rgba[2*TGSI_NUM_CHANNELS], rgba[3*TGSI_NUM_CHANNELS]); +} + + +static void +print_sample_4(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { debug_printf("%s %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n", function, @@ -837,64 +773,61 @@ print_sample(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE] rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]); } - /* Some image-filter fastpaths: */ static INLINE void img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); - unsigned j; - unsigned level = samp->level; unsigned xpot = pot_level_size(samp->xpot, level); unsigned ypot = pot_level_size(samp->ypot, level); unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */ unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */ union tex_tile_address addr; + int c; - addr.value = 0; - addr.bits.level = samp->level; - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - int c; - float u = s[j] * xpot - 0.5F; - float v = t[j] * ypot - 0.5F; + float u = s * xpot - 0.5F; + float v = t * ypot - 0.5F; - int uflr = util_ifloor(u); - int vflr = util_ifloor(v); + int uflr = util_ifloor(u); + int vflr = util_ifloor(v); - float xw = u - (float)uflr; - float yw = v - (float)vflr; + float xw = u - (float)uflr; + float yw = v - (float)vflr; - int x0 = uflr & (xpot - 1); - int y0 = vflr & (ypot - 1); + int x0 = uflr & (xpot - 1); + int y0 = vflr & (ypot - 1); - const float *tx[4]; + const float *tx[4]; - /* Can we fetch all four at once: - */ - if (x0 < xmax && y0 < ymax) { - get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx); - } - else { - unsigned x1 = (x0 + 1) & (xpot - 1); - unsigned y1 = (y0 + 1) & (ypot - 1); - get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx); - } + addr.value = 0; + addr.bits.level = level; - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_2d(xw, yw, - tx[0][c], tx[1][c], - tx[2][c], tx[3][c]); - } + /* Can we fetch all four at once: + */ + if (x0 < xmax && y0 < ymax) { + get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx); + } + else { + unsigned x1 = (x0 + 1) & (xpot - 1); + unsigned y1 = (y0 + 1) & (ypot - 1); + get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx); + } + + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) { + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx[0][c], tx[1][c], + tx[2][c], tx[3][c]); } if (DEBUG_TEX) { @@ -905,41 +838,36 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, static INLINE void img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float rgba[TGSI_QUAD_SIZE]) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); - unsigned j; - unsigned level = samp->level; unsigned xpot = pot_level_size(samp->xpot, level); unsigned ypot = pot_level_size(samp->ypot, level); + const float *out; union tex_tile_address addr; + int c; - addr.value = 0; - addr.bits.level = samp->level; - - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - int c; - - float u = s[j] * xpot; - float v = t[j] * ypot; + float u = s * xpot; + float v = t * ypot; - int uflr = util_ifloor(u); - int vflr = util_ifloor(v); + int uflr = util_ifloor(u); + int vflr = util_ifloor(v); - int x0 = uflr & (xpot - 1); - int y0 = vflr & (ypot - 1); + int x0 = uflr & (xpot - 1); + int y0 = vflr & (ypot - 1); - const float *out = get_texel_2d_no_border(samp, addr, x0, y0); + addr.value = 0; + addr.bits.level = level; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + out = get_texel_2d_no_border(samp, addr, x0, y0); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; if (DEBUG_TEX) { print_sample(__FUNCTION__, rgba); @@ -949,50 +877,44 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, static INLINE void img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float rgba[TGSI_QUAD_SIZE]) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); - unsigned j; - unsigned level = samp->level; unsigned xpot = pot_level_size(samp->xpot, level); unsigned ypot = pot_level_size(samp->ypot, level); union tex_tile_address addr; + int c; - addr.value = 0; - addr.bits.level = samp->level; - - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - int c; - - float u = s[j] * xpot; - float v = t[j] * ypot; - - int x0, y0; - const float *out; - - x0 = util_ifloor(u); - if (x0 < 0) - x0 = 0; - else if (x0 > xpot - 1) - x0 = xpot - 1; + float u = s * xpot; + float v = t * ypot; - y0 = util_ifloor(v); - if (y0 < 0) - y0 = 0; - else if (y0 > ypot - 1) - y0 = ypot - 1; - - out = get_texel_2d_no_border(samp, addr, x0, y0); + int x0, y0; + const float *out; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + addr.value = 0; + addr.bits.level = level; + + x0 = util_ifloor(u); + if (x0 < 0) + x0 = 0; + else if (x0 > xpot - 1) + x0 = xpot - 1; + + y0 = util_ifloor(v); + if (y0 < 0) + y0 = 0; + else if (y0 > ypot - 1) + y0 = ypot - 1; + + out = get_texel_2d_no_border(samp, addr, x0, y0); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; if (DEBUG_TEX) { print_sample(__FUNCTION__, rgba); @@ -1002,37 +924,34 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, static void img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float s, + float t, + float p, + unsigned level, + unsigned face_id, + enum tgsi_sampler_control control, + float rgba[TGSI_QUAD_SIZE]) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width; - int x[4]; + int x; union tex_tile_address addr; + const float *out; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); + width = u_minify(texture->width0, level); assert(width > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->nearest_texcoord_s(s, width, x); + samp->nearest_texcoord_s(s, width, &x); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *out = get_texel_2d(samp, addr, x[j], 0); - int c; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + out = get_texel_2d(samp, addr, x, 0); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; if (DEBUG_TEX) { print_sample(__FUNCTION__, rgba); @@ -1042,38 +961,35 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, static void img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width; - int x[4], layer[4]; + int x, layer; union tex_tile_address addr; + const float *out; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); + width = u_minify(texture->width0, level); assert(width > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->nearest_texcoord_s(s, width, x); - wrap_array_layer(t, texture->array_size, layer); + samp->nearest_texcoord_s(s, width, &x); + wrap_array_layer(t, texture->array_size, &layer); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *out = get_texel_1d_array(samp, addr, x[j], layer[j]); - int c; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + out = get_texel_1d_array(samp, addr, x, layer); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; if (DEBUG_TEX) { print_sample(__FUNCTION__, rgba); @@ -1083,41 +999,37 @@ img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler, static void img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width, height; - int x[4], y[4]; + int x, y; union tex_tile_address addr; + const float *out; + int c; - - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->nearest_texcoord_s(s, width, x); - samp->nearest_texcoord_t(t, height, y); + samp->nearest_texcoord_s(s, width, &x); + samp->nearest_texcoord_t(t, height, &y); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *out = get_texel_2d(samp, addr, x[j], y[j]); - int c; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + out = get_texel_2d(samp, addr, x, y); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; if (DEBUG_TEX) { print_sample(__FUNCTION__, rgba); @@ -1127,41 +1039,38 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, static void img_filter_2d_array_nearest(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width, height; - int x[4], y[4], layer[4]; + int x, y, layer; union tex_tile_address addr; + const float *out; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->nearest_texcoord_s(s, width, x); - samp->nearest_texcoord_t(t, height, y); - wrap_array_layer(p, texture->array_size, layer); + samp->nearest_texcoord_s(s, width, &x); + samp->nearest_texcoord_t(t, height, &y); + wrap_array_layer(p, texture->array_size, &layer); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *out = get_texel_2d_array(samp, addr, x[j], y[j], layer[j]); - int c; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + out = get_texel_2d_array(samp, addr, x, y, layer); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; if (DEBUG_TEX) { print_sample(__FUNCTION__, rgba); @@ -1179,41 +1088,37 @@ face(union tex_tile_address addr, unsigned face ) static void img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - const unsigned *faces = samp->faces; /* zero when not cube-mapping */ - unsigned level0, j; int width, height; - int x[4], y[4]; + int x, y; union tex_tile_address addr; + const float *out; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->nearest_texcoord_s(s, width, x); - samp->nearest_texcoord_t(t, height, y); + samp->nearest_texcoord_s(s, width, &x); + samp->nearest_texcoord_t(t, height, &y); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *out = get_texel_2d(samp, face(addr, faces[j]), x[j], y[j]); - int c; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + out = get_texel_2d(samp, face(addr, face_id), x, y); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; if (DEBUG_TEX) { print_sample(__FUNCTION__, rgba); @@ -1223,326 +1128,304 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, static void img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width, height, depth; - int x[4], y[4], z[4]; + int x, y, z; union tex_tile_address addr; + const float *out; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); - depth = u_minify(texture->depth0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); + depth = u_minify(texture->depth0, level); assert(width > 0); assert(height > 0); assert(depth > 0); - samp->nearest_texcoord_s(s, width, x); - samp->nearest_texcoord_t(t, height, y); - samp->nearest_texcoord_p(p, depth, z); + samp->nearest_texcoord_s(s, width, &x); + samp->nearest_texcoord_t(t, height, &y); + samp->nearest_texcoord_p(p, depth, &z); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *out = get_texel_3d(samp, addr, x[j], y[j], z[j]); - int c; - for (c = 0; c < 4; c++) { - rgba[c][j] = out[c]; - } - } + out = get_texel_3d(samp, addr, x, y, z); + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = out[c]; } static void img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width; - int x0[4], x1[4]; - float xw[4]; /* weights */ + int x0, x1; + float xw; /* weights */ union tex_tile_address addr; + const float *tx0, *tx1; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); + width = u_minify(texture->width0, level); assert(width > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->linear_texcoord_s(s, width, x0, x1, xw); + samp->linear_texcoord_s(s, width, &x0, &x1, &xw); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *tx0 = get_texel_2d(samp, addr, x0[j], 0); - const float *tx1 = get_texel_2d(samp, addr, x1[j], 0); - int c; + tx0 = get_texel_2d(samp, addr, x0, 0); + tx1 = get_texel_2d(samp, addr, x1, 0); - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp(xw[j], tx0[c], tx1[c]); - } - } + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]); } static void img_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width; - int x0[4], x1[4], layer[4]; - float xw[4]; /* weights */ + int x0, x1, layer; + float xw; /* weights */ union tex_tile_address addr; + const float *tx0, *tx1; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); + width = u_minify(texture->width0, level); assert(width > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->linear_texcoord_s(s, width, x0, x1, xw); - wrap_array_layer(t, texture->array_size, layer); + samp->linear_texcoord_s(s, width, &x0, &x1, &xw); + wrap_array_layer(t, texture->array_size, &layer); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *tx0 = get_texel_1d_array(samp, addr, x0[j], layer[j]); - const float *tx1 = get_texel_1d_array(samp, addr, x1[j], layer[j]); - int c; + tx0 = get_texel_1d_array(samp, addr, x0, layer); + tx1 = get_texel_1d_array(samp, addr, x1, layer); - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp(xw[j], tx0[c], tx1[c]); - } - } + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]); } static void img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width, height; - int x0[4], y0[4], x1[4], y1[4]; - float xw[4], yw[4]; /* weights */ + int x0, y0, x1, y1; + float xw, yw; /* weights */ union tex_tile_address addr; + const float *tx0, *tx1, *tx2, *tx3; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->linear_texcoord_s(s, width, x0, x1, xw); - samp->linear_texcoord_t(t, height, y0, y1, yw); + samp->linear_texcoord_s(s, width, &x0, &x1, &xw); + samp->linear_texcoord_t(t, height, &y0, &y1, &yw); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *tx0 = get_texel_2d(samp, addr, x0[j], y0[j]); - const float *tx1 = get_texel_2d(samp, addr, x1[j], y0[j]); - const float *tx2 = get_texel_2d(samp, addr, x0[j], y1[j]); - const float *tx3 = get_texel_2d(samp, addr, x1[j], y1[j]); - int c; + tx0 = get_texel_2d(samp, addr, x0, y0); + tx1 = get_texel_2d(samp, addr, x1, y0); + tx2 = get_texel_2d(samp, addr, x0, y1); + tx3 = get_texel_2d(samp, addr, x1, y1); - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_2d(xw[j], yw[j], - tx0[c], tx1[c], - tx2[c], tx3[c]); - } - } + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx0[c], tx1[c], + tx2[c], tx3[c]); } static void img_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width, height; - int x0[4], y0[4], x1[4], y1[4], layer[4]; - float xw[4], yw[4]; /* weights */ + int x0, y0, x1, y1, layer; + float xw, yw; /* weights */ union tex_tile_address addr; + const float *tx0, *tx1, *tx2, *tx3; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->linear_texcoord_s(s, width, x0, x1, xw); - samp->linear_texcoord_t(t, height, y0, y1, yw); - wrap_array_layer(p, texture->array_size, layer); + samp->linear_texcoord_s(s, width, &x0, &x1, &xw); + samp->linear_texcoord_t(t, height, &y0, &y1, &yw); + wrap_array_layer(p, texture->array_size, &layer); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - const float *tx0 = get_texel_2d_array(samp, addr, x0[j], y0[j], layer[j]); - const float *tx1 = get_texel_2d_array(samp, addr, x1[j], y0[j], layer[j]); - const float *tx2 = get_texel_2d_array(samp, addr, x0[j], y1[j], layer[j]); - const float *tx3 = get_texel_2d_array(samp, addr, x1[j], y1[j], layer[j]); - int c; + tx0 = get_texel_2d_array(samp, addr, x0, y0, layer); + tx1 = get_texel_2d_array(samp, addr, x1, y0, layer); + tx2 = get_texel_2d_array(samp, addr, x0, y1, layer); + tx3 = get_texel_2d_array(samp, addr, x1, y1, layer); - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_2d(xw[j], yw[j], - tx0[c], tx1[c], - tx2[c], tx3[c]); - } - } + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx0[c], tx1[c], + tx2[c], tx3[c]); } static void img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - const unsigned *faces = samp->faces; /* zero when not cube-mapping */ - unsigned level0, j; int width, height; - int x0[4], y0[4], x1[4], y1[4]; - float xw[4], yw[4]; /* weights */ - union tex_tile_address addr; + int x0, y0, x1, y1; + float xw, yw; /* weights */ + union tex_tile_address addr, addrj; + const float *tx0, *tx1, *tx2, *tx3; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = samp->level; + addr.bits.level = level; - samp->linear_texcoord_s(s, width, x0, x1, xw); - samp->linear_texcoord_t(t, height, y0, y1, yw); + samp->linear_texcoord_s(s, width, &x0, &x1, &xw); + samp->linear_texcoord_t(t, height, &y0, &y1, &yw); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - union tex_tile_address addrj = face(addr, faces[j]); - const float *tx0 = get_texel_2d(samp, addrj, x0[j], y0[j]); - const float *tx1 = get_texel_2d(samp, addrj, x1[j], y0[j]); - const float *tx2 = get_texel_2d(samp, addrj, x0[j], y1[j]); - const float *tx3 = get_texel_2d(samp, addrj, x1[j], y1[j]); - int c; + addrj = face(addr, face_id); + tx0 = get_texel_2d(samp, addrj, x0, y0); + tx1 = get_texel_2d(samp, addrj, x1, y0); + tx2 = get_texel_2d(samp, addrj, x0, y1); + tx3 = get_texel_2d(samp, addrj, x1, y1); - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_2d(xw[j], yw[j], - tx0[c], tx1[c], - tx2[c], tx3[c]); - } - } + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx0[c], tx1[c], + tx2[c], tx3[c]); } static void img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, - const float s[TGSI_QUAD_SIZE], - const float t[TGSI_QUAD_SIZE], - const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + float s, + float t, + float p, + unsigned level, + unsigned face_id, enum tgsi_sampler_control control, - float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) + float *rgba) { const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0, j; int width, height, depth; - int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; - float xw[4], yw[4], zw[4]; /* interpolation weights */ + int x0, x1, y0, y1, z0, z1; + float xw, yw, zw; /* interpolation weights */ union tex_tile_address addr; + const float *tx00, *tx01, *tx02, *tx03, *tx10, *tx11, *tx12, *tx13; + int c; - level0 = samp->level; - width = u_minify(texture->width0, level0); - height = u_minify(texture->height0, level0); - depth = u_minify(texture->depth0, level0); + width = u_minify(texture->width0, level); + height = u_minify(texture->height0, level); + depth = u_minify(texture->depth0, level); addr.value = 0; - addr.bits.level = level0; + addr.bits.level = level; assert(width > 0); assert(height > 0); assert(depth > 0); - samp->linear_texcoord_s(s, width, x0, x1, xw); - samp->linear_texcoord_t(t, height, y0, y1, yw); - samp->linear_texcoord_p(p, depth, z0, z1, zw); + samp->linear_texcoord_s(s, width, &x0, &x1, &xw); + samp->linear_texcoord_t(t, height, &y0, &y1, &yw); + samp->linear_texcoord_p(p, depth, &z0, &z1, &zw); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - int c; - const float *tx00 = get_texel_3d(samp, addr, x0[j], y0[j], z0[j]); - const float *tx01 = get_texel_3d(samp, addr, x1[j], y0[j], z0[j]); - const float *tx02 = get_texel_3d(samp, addr, x0[j], y1[j], z0[j]); - const float *tx03 = get_texel_3d(samp, addr, x1[j], y1[j], z0[j]); + tx00 = get_texel_3d(samp, addr, x0, y0, z0); + tx01 = get_texel_3d(samp, addr, x1, y0, z0); + tx02 = get_texel_3d(samp, addr, x0, y1, z0); + tx03 = get_texel_3d(samp, addr, x1, y1, z0); - const float *tx10 = get_texel_3d(samp, addr, x0[j], y0[j], z1[j]); - const float *tx11 = get_texel_3d(samp, addr, x1[j], y0[j], z1[j]); - const float *tx12 = get_texel_3d(samp, addr, x0[j], y1[j], z1[j]); - const float *tx13 = get_texel_3d(samp, addr, x1[j], y1[j], z1[j]); + tx10 = get_texel_3d(samp, addr, x0, y0, z1); + tx11 = get_texel_3d(samp, addr, x1, y0, z1); + tx12 = get_texel_3d(samp, addr, x0, y1, z1); + tx13 = get_texel_3d(samp, addr, x1, y1, z1); /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j], - tx00[c], tx01[c], - tx02[c], tx03[c], - tx10[c], tx11[c], - tx12[c], tx13[c]); - } - } + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_3d(xw, yw, zw, + tx00[c], tx01[c], + tx02[c], tx03[c], + tx10[c], tx11[c], + tx12[c], tx13[c]); } @@ -1575,12 +1458,11 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, { struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - int level0; - float lambda; + int j; float lod[TGSI_QUAD_SIZE]; if (control == tgsi_sampler_lod_bias) { - lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias; + float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias; compute_lod(samp->sampler, lambda, c0, lod); } else { assert(control == tgsi_sampler_lod_explicit); @@ -1588,40 +1470,31 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, memcpy(lod, c0, sizeof(lod)); } - /* XXX: Take into account all lod values. - */ - lambda = lod[0]; - level0 = samp->view->u.tex.first_level + (int)lambda; + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + int level0 = samp->view->u.tex.first_level + (int)lod[j]; - if (lambda < 0.0) { - samp->level = samp->view->u.tex.first_level; - samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); - } - else if (level0 >= texture->last_level) { - samp->level = texture->last_level; - samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); - } - else { - float levelBlend = frac(lambda); - float rgba0[4][4]; - float rgba1[4][4]; - int c,j; + if (lod[j] < 0.0) + samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); - samp->level = level0; - samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba0); + else if (level0 >= texture->last_level) + samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], texture->last_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); - samp->level = level0+1; - samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba1); + else { + float levelBlend = frac(lod[j]); + float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]; + int c; + + samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level0, samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][0]); + samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level0+1, samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][1]); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { for (c = 0; c < 4; c++) { - rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); + rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]); } } } if (DEBUG_TEX) { - print_sample(__FUNCTION__, rgba); + print_sample_4(__FUNCTION__, rgba); } } @@ -1642,11 +1515,11 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, { struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - float lambda; float lod[TGSI_QUAD_SIZE]; + int j; if (control == tgsi_sampler_lod_bias) { - lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias; + float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias; compute_lod(samp->sampler, lambda, c0, lod); } else { assert(control == tgsi_sampler_lod_explicit); @@ -1654,22 +1527,18 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, memcpy(lod, c0, sizeof(lod)); } - /* XXX: Take into account all lod values. - */ - lambda = lod[0]; - - if (lambda < 0.0) { - samp->level = samp->view->u.tex.first_level; - samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); - } - else { - samp->level = samp->view->u.tex.first_level + (int)(lambda + 0.5F) ; - samp->level = MIN2(samp->level, (int)texture->last_level); - samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + if (lod[j] < 0.0) + samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); + else { + float level = samp->view->u.tex.first_level + (int)(lod[j] + 0.5F) ; + level = MIN2(level, (int)texture->last_level); + samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); + } } if (DEBUG_TEX) { - print_sample(__FUNCTION__, rgba); + print_sample_4(__FUNCTION__, rgba); } } @@ -1684,11 +1553,11 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); - float lambda; float lod[TGSI_QUAD_SIZE]; + int j; if (control == tgsi_sampler_lod_bias) { - lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias; + float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias; compute_lod(samp->sampler, lambda, c0, lod); } else { assert(control == tgsi_sampler_lod_explicit); @@ -1696,20 +1565,34 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler, memcpy(lod, c0, sizeof(lod)); } - /* XXX: Take into account all lod values. - */ - lambda = lod[0]; - - samp->level = samp->view->u.tex.first_level; - if (lambda < 0.0) { - samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); - } - else { - samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + if (lod[j] < 0.0) { + samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); + } + else { + samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); + } } } +static void +mip_filter_none_no_filter_select(struct tgsi_sampler *tgsi_sampler, + const float s[TGSI_QUAD_SIZE], + const float t[TGSI_QUAD_SIZE], + const float p[TGSI_QUAD_SIZE], + const float c0[TGSI_QUAD_SIZE], + enum tgsi_sampler_control control, + float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) +{ + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + int j; + + for (j = 0; j < TGSI_QUAD_SIZE; j++) + samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); +} + + /* For anisotropic filtering */ #define WEIGHT_LUT_SIZE 1024 @@ -1738,7 +1621,7 @@ create_filter_table(void) /** * Elliptical weighted average (EWA) filter for producing high quality * anisotropic filtered results. - * Based on the Higher Quality Elliptical Weighted Avarage Filter + * Based on the Higher Quality Elliptical Weighted Average Filter * published by Paul S. Heckbert in his Master's Thesis * "Fundamentals of Texture Mapping and Image Warping" (1989) */ @@ -1747,7 +1630,7 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler, const float s[TGSI_QUAD_SIZE], const float t[TGSI_QUAD_SIZE], const float p[TGSI_QUAD_SIZE], - const float c0[TGSI_QUAD_SIZE], + unsigned level, enum tgsi_sampler_control control, const float dudx, const float dvdx, const float dudy, const float dvdy, @@ -1756,7 +1639,8 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler, const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - unsigned level0 = samp->level > 0 ? samp->level : 0; + // ??? Won't the image filters blow up if level is negative? + unsigned level0 = level > 0 ? level : 0; float scaling = 1.0 / (1 << level0); int width = u_minify(texture->width0, level0); int height = u_minify(texture->height0, level0); @@ -1857,9 +1741,9 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler, * img_filter_2d_nearest or one of the * accelerated img_filter_2d_nearest_XXX functions. */ - samp->min_img_filter(tgsi_sampler, s_buffer, t_buffer, p, NULL, - tgsi_sampler_lod_bias, rgba_temp); for (jj = 0; jj < buffer_next; jj++) { + samp->min_img_filter(tgsi_sampler, s_buffer[jj], t_buffer[jj], p[jj], level, samp->faces[j], + tgsi_sampler_lod_bias, &rgba_temp[0][jj]); num[0] += weight_buffer[jj] * rgba_temp[0][jj]; num[1] += weight_buffer[jj] * rgba_temp[1][jj]; num[2] += weight_buffer[jj] * rgba_temp[2][jj]; @@ -1877,10 +1761,7 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler, } /* if the tex coord buffer contains unread values, we will read - * them now. Note that in most cases we have to read more pixel - * values than required, however, as the img_filter_2d_nearest - * function(s) does not have a count parameter, we need to read - * the whole quad and ignore the unused values + * them now. */ if (buffer_next > 0) { unsigned jj; @@ -1888,9 +1769,9 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler, * img_filter_2d_nearest or one of the * accelerated img_filter_2d_nearest_XXX functions. */ - samp->min_img_filter(tgsi_sampler, s_buffer, t_buffer, p, NULL, - tgsi_sampler_lod_bias, rgba_temp); for (jj = 0; jj < buffer_next; jj++) { + samp->min_img_filter(tgsi_sampler, s_buffer[jj], t_buffer[jj], p[jj], level, samp->faces[j], + tgsi_sampler_lod_bias, &rgba_temp[0][jj]); num[0] += weight_buffer[jj] * rgba_temp[0][jj]; num[1] += weight_buffer[jj] * rgba_temp[1][jj]; num[2] += weight_buffer[jj] * rgba_temp[2][jj]; @@ -1909,8 +1790,8 @@ img_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler, rgba[2]=0; rgba[3]=0;*/ /* not enough pixels in resampling, resort to direct interpolation */ - samp->min_img_filter(tgsi_sampler, s, t, p, NULL, - tgsi_sampler_lod_bias, rgba_temp); + samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level, samp->faces[j], + tgsi_sampler_lod_bias, &rgba_temp[0][j]); den = 1; num[0] = rgba_temp[0][j]; num[1] = rgba_temp[1][j]; @@ -2005,20 +1886,20 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler, * simply return the average of the whole image. */ if (level0 >= (int) texture->last_level) { - samp->level = texture->last_level; - samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); + int j; + for (j = 0; j < TGSI_QUAD_SIZE; j++) + samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], texture->last_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); } else { /* don't bother interpolating between multiple LODs; it doesn't * seem to be worth the extra running time. */ - samp->level = level0; - img_filter_2d_ewa(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, + img_filter_2d_ewa(tgsi_sampler, s, t, p, level0, tgsi_sampler_lod_bias, dudx, dvdx, dudy, dvdy, rgba); } if (DEBUG_TEX) { - print_sample(__FUNCTION__, rgba); + print_sample_4(__FUNCTION__, rgba); } } @@ -2039,7 +1920,7 @@ mip_filter_linear_2d_linear_repeat_POT( { struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->view->texture; - int level0; + int j; float lambda; float lod[TGSI_QUAD_SIZE]; @@ -2052,42 +1933,33 @@ mip_filter_linear_2d_linear_repeat_POT( memcpy(lod, c0, sizeof(lod)); } - /* XXX: Take into account all lod values. - */ - lambda = lod[0]; - level0 = samp->view->u.tex.first_level + (int)lambda; - - /* Catches both negative and large values of level0: - */ - if ((unsigned)level0 >= texture->last_level) { - if (level0 < 0) - samp->level = samp->view->u.tex.first_level; - else - samp->level = texture->last_level; + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + int level0 = samp->view->u.tex.first_level + (int)lod[j]; - img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba); - } - else { - float levelBlend = frac(lambda); - float rgba0[4][4]; - float rgba1[4][4]; - int c,j; + /* Catches both negative and large values of level0: + */ + if ((unsigned)level0 >= texture->last_level) { + if (level0 < 0) + img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); + else + img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], samp->view->texture->last_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]); - samp->level = level0; - img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba0); + } + else { + float levelBlend = frac(lod[j]); + float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]; + int c; - samp->level = level0+1; - img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba1); + img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], level0, samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][j]); + img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], level0+1, samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][j]); - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); - } + for (c = 0; c < TGSI_NUM_CHANNELS; c++) + rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]); } } if (DEBUG_TEX) { - print_sample(__FUNCTION__, rgba); + print_sample_4(__FUNCTION__, rgba); } } @@ -2505,7 +2377,7 @@ get_lambda_func(const union sp_sampler_key key) } -static filter_func +static img_filter_func get_img_filter(const union sp_sampler_key key, unsigned filter, const struct pipe_sampler_state *sampler) @@ -2597,7 +2469,6 @@ sp_sampler_variant_bind_view( struct sp_sampler_variant *samp, samp->cache = tex_cache; samp->xpot = util_logbase2( texture->width0 ); samp->ypot = util_logbase2( texture->height0 ); - samp->level = view->u.tex.first_level; } @@ -2793,7 +2664,7 @@ sp_create_sampler_variant( const struct pipe_sampler_state *sampler, switch (sampler->min_mip_filter) { case PIPE_TEX_MIPFILTER_NONE: if (sampler->min_img_filter == sampler->mag_img_filter) - samp->mip_filter = samp->min_img_filter; + samp->mip_filter = mip_filter_none_no_filter_select; else samp->mip_filter = mip_filter_none; break; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 7fdabd4fd99..dd847af69d7 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -34,21 +34,30 @@ struct sp_sampler_variant; -typedef void (*wrap_nearest_func)(const float s[4], +typedef void (*wrap_nearest_func)(float s, unsigned size, - int icoord[4]); + int *icoord); -typedef void (*wrap_linear_func)(const float s[4], +typedef void (*wrap_linear_func)(float s, unsigned size, - int icoord0[4], - int icoord1[4], - float w[4]); + int *icoord0, + int *icoord1, + float *w); typedef float (*compute_lambda_func)(const struct sp_sampler_variant *sampler, const float s[TGSI_QUAD_SIZE], const float t[TGSI_QUAD_SIZE], const float p[TGSI_QUAD_SIZE]); +typedef void (*img_filter_func)(struct tgsi_sampler *tgsi_sampler, + float s, + float t, + float p, + unsigned level, + unsigned face_id, + enum tgsi_sampler_control control, + float *rgba); + typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler, const float s[TGSI_QUAD_SIZE], const float t[TGSI_QUAD_SIZE], @@ -98,9 +107,8 @@ struct sp_sampler_variant */ unsigned xpot; unsigned ypot; - unsigned level; - unsigned faces[4]; + unsigned faces[TGSI_QUAD_SIZE]; wrap_nearest_func nearest_texcoord_s; wrap_nearest_func nearest_texcoord_t; @@ -110,8 +118,8 @@ struct sp_sampler_variant wrap_linear_func linear_texcoord_t; wrap_linear_func linear_texcoord_p; - filter_func min_img_filter; - filter_func mag_img_filter; + img_filter_func min_img_filter; + img_filter_func mag_img_filter; compute_lambda_func compute_lambda; |