Decompressing ETC2 textures was causing intermitent segfault by copying resulting 4x4 texel block to the destination texture regardless of the size of the destination texture. Issue found via application crash in GLBenchmark 3.0's Manhattan test.
v2: add more explanatory comments v3: add bugzilla reference Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=74988 Cc: "9.2 10.0 10.1" <mesa-sta...@lists.freedesktop.org <mailto:mesa-sta...@lists.freedesktop.org>> --- src/mesa/main/texcompress_etc.c | 49 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c index 28203f4..d025488 100644 --- a/src/mesa/main/texcompress_etc.c +++ b/src/mesa/main/texcompress_etc.c @@ -685,9 +685,10 @@ etc2_unpack_rgb8(uint8_t *dst_row, etc2_rgb8_parse_block(&block, src, false /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + /* be sure to stay within the bounds of the texture */ + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, false /* punchthrough_alpha */); dst[3] = 255; @@ -722,9 +723,9 @@ etc2_unpack_srgb8(uint8_t *dst_row, etc2_rgb8_parse_block(&block, src, false /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, false /* punchthrough_alpha */); /* Convert to MESA_FORMAT_SARGB8 */ @@ -765,9 +766,9 @@ etc2_unpack_rgba8(uint8_t *dst_row, for (x = 0; x < width; x+= bw) { etc2_rgba8_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_rgba8_fetch_texel(&block, i, j, dst); dst += comps; } @@ -802,9 +803,9 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row, for (x = 0; x < width; x+= bw) { etc2_rgba8_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_rgba8_fetch_texel(&block, i, j, dst); /* Convert to MESA_FORMAT_SARGB8 */ @@ -844,9 +845,9 @@ etc2_unpack_r11(uint8_t *dst_row, for (x = 0; x < width; x+= bw) { etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } @@ -880,10 +881,10 @@ etc2_unpack_rg11(uint8_t *dst_row, /* red component */ etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } @@ -891,10 +892,10 @@ etc2_unpack_rg11(uint8_t *dst_row, /* green component */ etc2_r11_parse_block(&block, src + 8); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_r11_fetch_texel(&block, i, j, dst + comp_size); dst += comps * comp_size; } @@ -927,10 +928,10 @@ etc2_unpack_signed_r11(uint8_t *dst_row, for (x = 0; x < width; x+= bw) { etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_signed_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } @@ -964,10 +965,10 @@ etc2_unpack_signed_rg11(uint8_t *dst_row, /* red component */ etc2_r11_parse_block(&block, src); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_signed_r11_fetch_texel(&block, i, j, dst); dst += comps * comp_size; } @@ -975,10 +976,10 @@ etc2_unpack_signed_rg11(uint8_t *dst_row, /* green component */ etc2_r11_parse_block(&block, src + 8); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size); dst += comps * comp_size; } @@ -1008,9 +1009,9 @@ etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row, for (x = 0; x < width; x+= bw) { etc2_rgb8_parse_block(&block, src, true /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, true /* punchthrough_alpha */); dst += comps; @@ -1043,9 +1044,9 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row, for (x = 0; x < width; x+= bw) { etc2_rgb8_parse_block(&block, src, true /* punchthrough_alpha */); - for (j = 0; j < bh; j++) { + for (j = 0; j < bh && (j+y) < height; j++) { uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < bw; i++) { + for (i = 0; i < bw && (i+x) < width; i++) { etc2_rgb8_fetch_texel(&block, i, j, dst, true /* punchthrough_alpha */); /* Convert to MESA_FORMAT_SARGB8 */ -- 1.8.3.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev