summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2012-04-25 10:42:42 -0600
committerBrian Paul <[email protected]>2012-05-01 11:42:58 -0600
commit92d899303a0498e53b66fe19658a2f7fd6dc9a26 (patch)
tree1ec133bf479af98b0113190be2a08704b137ffde /src
parent7b610d55160cf77b8d8de0a7bc58c75985ba8747 (diff)
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index d54e02e40cd..83d9be8a024 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -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];
}