diff options
author | Brian Paul <[email protected]> | 2012-04-25 10:42:42 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2012-05-01 11:42:58 -0600 |
commit | 92d899303a0498e53b66fe19658a2f7fd6dc9a26 (patch) | |
tree | 1ec133bf479af98b0113190be2a08704b137ffde /src | |
parent | 7b610d55160cf77b8d8de0a7bc58c75985ba8747 (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.c | 45 |
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]; } |