[Mesa-dev] [PATCH 3/3] gallium/radeon/gfx9: fix PBO texture uploads to compressed textures

Nicolai Hähnle nhaehnle at gmail.com
Mon Jun 12 19:33:07 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

st/mesa creates a surface that reinterprets the compressed blocks as
RGBA16UI or RGBA32UI. We have to adjust width0 & height0 accordingly to
avoid out-of-bounds memory accesses by CB.

Cc: 17.1 <mesa-stable at lists.freedesktop.org>
---
 src/gallium/drivers/radeon/r600_texture.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 32275b1..88b3403 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1960,43 +1960,48 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
 	return &surface->base;
 }
 
 static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
 						struct pipe_resource *tex,
 						const struct pipe_surface *templ)
 {
 	unsigned level = templ->u.tex.level;
 	unsigned width = u_minify(tex->width0, level);
 	unsigned height = u_minify(tex->height0, level);
+	unsigned width0 = tex->width0;
+	unsigned height0 = tex->height0;
 
 	if (tex->target != PIPE_BUFFER && templ->format != tex->format) {
 		const struct util_format_description *tex_desc
 			= util_format_description(tex->format);
 		const struct util_format_description *templ_desc
 			= util_format_description(templ->format);
 
 		assert(tex_desc->block.bits == templ_desc->block.bits);
 
 		/* Adjust size of surface if and only if the block width or
 		 * height is changed. */
 		if (tex_desc->block.width != templ_desc->block.width ||
 		    tex_desc->block.height != templ_desc->block.height) {
 			unsigned nblks_x = util_format_get_nblocksx(tex->format, width);
 			unsigned nblks_y = util_format_get_nblocksy(tex->format, height);
 
 			width = nblks_x * templ_desc->block.width;
 			height = nblks_y * templ_desc->block.height;
+
+			width0 = util_format_get_nblocksx(tex->format, width0);
+			height0 = util_format_get_nblocksy(tex->format, height0);
 		}
 	}
 
 	return r600_create_surface_custom(pipe, tex, templ,
-					  tex->width0, tex->height0,
+					  width0, height0,
 					  width, height);
 }
 
 static void r600_surface_destroy(struct pipe_context *pipe,
 				 struct pipe_surface *surface)
 {
 	struct r600_surface *surf = (struct r600_surface*)surface;
 	r600_resource_reference(&surf->cb_buffer_fmask, NULL);
 	r600_resource_reference(&surf->cb_buffer_cmask, NULL);
 	pipe_resource_reference(&surface->texture, NULL);
-- 
2.9.3



More information about the mesa-dev mailing list