softpipe: implement coord clamping for texel fetches (TXF)

The GL spec says out of bounds fetches produce undefined results.
Use clamping to avoid failed assertions or crashes.

Fixes failed assertion in https://bugs.freedesktop.org/show_bug.cgi?id=49125
but the test still fails.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
Brian Paul
2012-04-25 10:42:42 -06:00
parent 7b610d5516
commit 92d899303a
+31 -14
View File
@@ -799,7 +799,8 @@ get_texel_2d_array(const struct sp_sampler_variant *samp,
const struct pipe_resource *texture = samp->view->texture;
unsigned level = addr.bits.level;
assert(layer < texture->array_size);
assert(layer < (int) texture->array_size);
assert(layer >= 0);
if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
y < 0 || y >= (int) u_minify(texture->height0, level)) {
@@ -2630,8 +2631,12 @@ sample_get_dims(struct tgsi_sampler *tgsi_sampler, int level,
}
}
/* this function is only used for unfiltered texel gets
via the TGSI TXF opcode. */
/**
* This function is only used for getting unfiltered texels via the
* TXF opcode. The GL spec says that out-of-bounds texel fetches
* produce undefined results. Instead of crashing, lets just clamp
* coords to the texture image size.
*/
static void
sample_get_texels(struct tgsi_sampler *tgsi_sampler,
const int v_i[TGSI_QUAD_SIZE],
@@ -2650,15 +2655,22 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
samp->key.bits.swizzle_g != PIPE_SWIZZLE_GREEN ||
samp->key.bits.swizzle_b != PIPE_SWIZZLE_BLUE ||
samp->key.bits.swizzle_a != PIPE_SWIZZLE_ALPHA);
int width, height, depth, layers;
addr.value = 0;
/* TODO write a better test for LOD */
addr.bits.level = lod[0];
width = u_minify(texture->width0, addr.bits.level);
height = u_minify(texture->height0, addr.bits.level);
depth = u_minify(texture->depth0, addr.bits.level);
layers = texture->array_size;
switch(texture->target) {
case PIPE_TEXTURE_1D:
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
tx = get_texel_2d(samp, addr, v_i[j] + offset[0], 0);
int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
tx = get_texel_2d(samp, addr, x, 0);
for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c];
}
@@ -2666,8 +2678,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
break;
case PIPE_TEXTURE_1D_ARRAY:
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
tx = get_texel_1d_array(samp, addr, v_i[j] + offset[0],
v_j[j] + offset[1]);
int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
int y = CLAMP(v_j[j] + offset[1], 0, layers - 1);
tx = get_texel_1d_array(samp, addr, x, y);
for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c];
}
@@ -2676,8 +2689,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_RECT:
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
tx = get_texel_2d(samp, addr, v_i[j] + offset[0],
v_j[j] + offset[1]);
int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
tx = get_texel_2d(samp, addr, x, y);
for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c];
}
@@ -2685,9 +2699,10 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
break;
case PIPE_TEXTURE_2D_ARRAY:
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
tx = get_texel_2d_array(samp, addr, v_i[j] + offset[0],
v_j[j] + offset[1],
v_k[j] + offset[2]);
int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
int layer = CLAMP(v_k[j] + offset[2], 0, layers - 1);
tx = get_texel_2d_array(samp, addr, x, y, layer);
for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c];
}
@@ -2695,9 +2710,11 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
break;
case PIPE_TEXTURE_3D:
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
tx = get_texel_3d(samp, addr, v_i[j] + offset[0],
v_j[j] + offset[1],
v_k[j] + offset[2]);
int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
int z = CLAMP(v_k[j] + offset[2], 0, depth - 1);
tx = get_texel_3d(samp, addr, x, y, z);
for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c];
}