summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_sample.c193
1 files changed, 75 insertions, 118 deletions
diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c
index ab26b184c1..f62f0abf87 100644
--- a/src/mesa/pipe/softpipe/sp_tex_sample.c
+++ b/src/mesa/pipe/softpipe/sp_tex_sample.c
@@ -428,6 +428,7 @@ compute_lambda(struct tgsi_sampler *sampler,
float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT];
dsdx = FABSF(dsdx);
dsdy = FABSF(dsdy);
+ /* XXX only multiply by width for NORMALIZEd texcoords */
rho = MAX2(dsdx, dsdy) * sampler->texture->width0;
}
if (t) {
@@ -436,6 +437,7 @@ compute_lambda(struct tgsi_sampler *sampler,
float max;
dtdx = FABSF(dtdx);
dtdy = FABSF(dtdy);
+ /* XXX only multiply by height for NORMALIZEd texcoords */
max = MAX2(dtdx, dtdy) * sampler->texture->height0;
rho = MAX2(rho, max);
}
@@ -445,6 +447,7 @@ compute_lambda(struct tgsi_sampler *sampler,
float max;
dpdx = FABSF(dpdx);
dpdy = FABSF(dpdy);
+ /* XXX only multiply by depth for NORMALIZEd texcoords */
max = MAX2(dpdx, dpdy) * sampler->texture->depth0;
rho = MAX2(rho, max);
}
@@ -458,99 +461,70 @@ compute_lambda(struct tgsi_sampler *sampler,
}
-static void
-sp_get_samples_1d(struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- struct pipe_context *pipe = (struct pipe_context *) sampler->pipe;
- struct pipe_surface *ps
- = pipe->get_tex_surface(pipe, sampler->texture, 0, 0, 0);
-
- switch (sampler->state->min_img_filter) {
- case PIPE_TEX_FILTER_NEAREST:
- {
- GLuint j;
- for (j = 0; j < QUAD_SIZE; j++) {
- GLint x = nearest_texcoord(sampler->state->wrap_s, s[j],
- sampler->texture->width0);
- float texel[4];
- ps->get_tile(ps, x, 0, 1, 1, texel);
- rgba[0][j] = texel[0];
- rgba[1][j] = texel[1];
- rgba[2][j] = texel[2];
- rgba[3][j] = texel[3];
- }
- }
- break;
- case PIPE_TEX_FILTER_LINEAR:
- {
- GLuint j;
- for (j = 0; j < QUAD_SIZE; j++) {
- float t0[4], t1[4], texel[4];
- GLint x0, x1;
- float a;
- linear_texcoord(sampler->state->wrap_s, s[j],
- sampler->texture->width0, &x0, &x1, &a);
- ps->get_tile(ps, x0, 0, 1, 1, t0);
- ps->get_tile(ps, x1, 0, 1, 1, t1);
-
- texel[0] = LERP(a, t0[0], t1[0]);
- texel[1] = LERP(a, t0[1], t1[1]);
- texel[2] = LERP(a, t0[2], t1[2]);
- texel[3] = LERP(a, t0[3], t1[3]);
- rgba[0][j] = texel[0];
- rgba[1][j] = texel[1];
- rgba[2][j] = texel[2];
- rgba[3][j] = texel[3];
- }
- }
- break;
- default:
- assert(0);
- }
-}
-
/**
- * From lambda and the min_mip_filter setting, choose the mipmap level(s)
- * that are to be sampled from.
+ * Do several things here:
+ * 1. Compute lambda from the texcoords, if needed
+ * 2. Determine if we're minifying or magnifying
+ * 3. If minifying, choose mipmap levels
+ * 4. Return image filter to use within mipmap images
*/
static void
-choose_mipmap_levels(struct tgsi_sampler *sampler, float lambda,
- unsigned *level0, unsigned *level1)
+choose_mipmap_levels(struct tgsi_sampler *sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ unsigned *level0, unsigned *level1, float *levelBlend,
+ unsigned *imgFilter)
{
- switch (sampler->state->min_mip_filter) {
- case PIPE_TEX_MIPFILTER_NONE:
+ if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
+ /* no mipmap selection needed */
+ assert(sampler->state->min_img_filter ==
+ sampler->state->mag_img_filter);
+ *imgFilter = sampler->state->mag_img_filter;
*level0 = *level1 = 0;
- return;
- case PIPE_TEX_MIPFILTER_NEAREST:
- {
- const int lvl = (int) (lambda + 0.5);
- *level0 =
- *level1 = CLAMP(lvl,
- (int) sampler->texture->first_level,
- (int) sampler->texture->last_level);
+ }
+ else {
+ float lambda;
+
+ if (1)
+ /* fragment shader */
+ lambda = compute_lambda(sampler, s, t, p, lodbias);
+ else
+ /* vertex shader */
+ lambda = lodbias; /* not really a bias, but absolute LOD */
+
+ if (lambda < 0.0) { /* XXX threshold depends on the filter */
+ /* magnifying */
+ *imgFilter = sampler->state->mag_img_filter;
+ *level0 = *level1 = 0;
}
- return;
- case PIPE_TEX_MIPFILTER_LINEAR:
- {
- const int lvl = (int) lambda;
- *level0 = CLAMP(lvl,
- (int) sampler->texture->first_level,
- (int) sampler->texture->last_level);
- *level1 = CLAMP(lvl + 1,
- (int) sampler->texture->first_level,
- (int) sampler->texture->last_level);
- assert(*level0 < 100);
- assert(*level1 < 100);
+ else {
+ /* minifying */
+ *imgFilter = sampler->state->min_img_filter;
+
+ /* choose mipmap level(s) and compute the blend factor between them */
+ if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
+ /* Nearest mipmap level */
+ const int lvl = (int) (lambda + 0.5);
+ *level0 =
+ *level1 = CLAMP(lvl,
+ (int) sampler->texture->first_level,
+ (int) sampler->texture->last_level);
+ }
+ else {
+ /* Linear interpolation between mipmap levels */
+ const int lvl = (int) lambda;
+ *level0 = CLAMP(lvl,
+ (int) sampler->texture->first_level,
+ (int) sampler->texture->last_level);
+ *level1 = CLAMP(lvl + 1,
+ (int) sampler->texture->first_level,
+ (int) sampler->texture->last_level);
+ *levelBlend = FRAC(lambda); /* blending weight between levels */
+ }
}
- return;
- default:
- assert(0);
}
}
@@ -620,6 +594,17 @@ get_texel(struct tgsi_sampler *sampler,
+static void
+sp_get_samples_1d(struct tgsi_sampler *sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+}
+
+
/**
* Called via tgsi_sampler::get_samples()
* Use the sampler's state setting to get a filtered RGBA value
@@ -642,38 +627,10 @@ sp_get_samples_2d(struct tgsi_sampler *sampler,
{
unsigned level0, level1, j, imgFilter;
int width, height;
- float mipBlend;
+ float levelBlend;
- /* compute level0 and imgFilter */
- switch (sampler->state->min_mip_filter) {
- case PIPE_TEX_MIPFILTER_NONE:
- imgFilter = sampler->state->mag_img_filter;
- level0 = level1 = 0;
- assert(sampler->state->min_img_filter ==
- sampler->state->mag_img_filter);
- break;
- default:
- {
- float lambda;
- int fragment = 1;
- if (fragment)
- lambda = compute_lambda(sampler, s, t, p, lodbias);
- else
- lambda = lodbias; /* not really a bias, but absolute LOD */
-
- if (lambda < 0.0) {
- /* magnifying */
- imgFilter = sampler->state->mag_img_filter;
- level0 = level1 = 0;
- }
- else {
- /* minifying */
- imgFilter = sampler->state->min_img_filter;
- choose_mipmap_levels(sampler, lambda, &level0, &level1);
- mipBlend = FRAC(lambda); /* blending weight between levels */
- }
- }
- }
+ choose_mipmap_levels(sampler, s, t, p, lodbias,
+ &level0, &level1, &levelBlend, &imgFilter);
width = sampler->texture->level[level0].width;
height = sampler->texture->level[level0].height;
@@ -695,7 +652,7 @@ sp_get_samples_2d(struct tgsi_sampler *sampler,
y = y / 2;
get_texel(sampler, 0, level1, 0, x, y, rgba2, j);
for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = LERP(mipBlend, rgba2[c][j], rgba[c][j]);
+ rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]);
}
}
}
@@ -732,7 +689,7 @@ sp_get_samples_2d(struct tgsi_sampler *sampler,
}
for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = LERP(mipBlend, rgba[c][j], rgba2[c][j]);
+ rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
}
}
}