[Mesa-dev] [PATCH 4/4] radeonsi: reduce overhead for resident textures which need color decompression

Samuel Pitoiset samuel.pitoiset at gmail.com
Wed Jun 14 11:55:12 UTC 2017


This is done by introducing a separate list.

si_decompress_textures() is now 5x faster.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
 src/gallium/drivers/radeonsi/si_blit.c        | 21 +++------
 src/gallium/drivers/radeonsi/si_descriptors.c | 64 ++++++++++++++++++++-------
 src/gallium/drivers/radeonsi/si_pipe.c        |  4 ++
 src/gallium/drivers/radeonsi/si_pipe.h        |  4 +-
 4 files changed, 59 insertions(+), 34 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 06a99fbc8a2..b240c4d355e 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -693,18 +693,13 @@ static void si_check_render_feedback(struct si_context *sctx)
 
 static void si_decompress_resident_textures(struct si_context *sctx)
 {
-	util_dynarray_foreach(&sctx->resident_tex_handles,
+	util_dynarray_foreach(&sctx->resident_tex_needs_color_decompress,
 			      struct si_texture_handle *, tex_handle) {
 		struct pipe_sampler_view *view = (*tex_handle)->view;
-		struct si_sampler_view *sview = (struct si_sampler_view *)view;
 		struct r600_texture *tex = (struct r600_texture *)view->texture;
 
-		if (view->texture->target == PIPE_BUFFER)
-			continue;
-
-		if ((*tex_handle)->needs_color_decompress)
-			si_decompress_color_texture(sctx, tex, view->u.tex.first_level,
-						    view->u.tex.last_level);
+		si_decompress_color_texture(sctx, tex, view->u.tex.first_level,
+					    view->u.tex.last_level);
 	}
 
 	util_dynarray_foreach(&sctx->resident_tex_needs_depth_decompress,
@@ -722,17 +717,13 @@ static void si_decompress_resident_textures(struct si_context *sctx)
 
 static void si_decompress_resident_images(struct si_context *sctx)
 {
-	util_dynarray_foreach(&sctx->resident_img_handles,
+	util_dynarray_foreach(&sctx->resident_img_needs_color_decompress,
 			      struct si_image_handle *, img_handle) {
 		struct pipe_image_view *view = &(*img_handle)->view;
 		struct r600_texture *tex = (struct r600_texture *)view->resource;
 
-		if (view->resource->target == PIPE_BUFFER)
-			continue;
-
-		if ((*img_handle)->needs_color_decompress)
-			si_decompress_color_texture(sctx, tex, view->u.tex.level,
-						    view->u.tex.level);
+		si_decompress_color_texture(sctx, tex, view->u.tex.level,
+					    view->u.tex.level);
 	}
 }
 
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index a8f54e0714a..f9e87530330 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -1617,29 +1617,41 @@ static void si_set_polygon_stipple(struct pipe_context *ctx,
 static void
 si_resident_handles_update_needs_color_decompress(struct si_context *sctx)
 {
+
+	util_dynarray_clear(&sctx->resident_tex_needs_color_decompress);
+	util_dynarray_clear(&sctx->resident_img_needs_color_decompress);
+
 	util_dynarray_foreach(&sctx->resident_tex_handles,
 			      struct si_texture_handle *, tex_handle) {
 		struct pipe_resource *res = (*tex_handle)->view->texture;
+		struct r600_texture *rtex;
 
-		if (res && res->target != PIPE_BUFFER) {
-			struct r600_texture *rtex = (struct r600_texture *)res;
+		if (!res || res->target == PIPE_BUFFER)
+			continue;
 
-			(*tex_handle)->needs_color_decompress =
-				color_needs_decompression(rtex);
-		}
+		rtex = (struct r600_texture *)res;
+		if (!color_needs_decompression(rtex))
+			continue;
+
+		util_dynarray_append(&sctx->resident_tex_needs_color_decompress,
+				     struct si_texture_handle *, *tex_handle);
 	}
 
 	util_dynarray_foreach(&sctx->resident_img_handles,
 			      struct si_image_handle *, img_handle) {
 		struct pipe_image_view *view = &(*img_handle)->view;
 		struct pipe_resource *res = view->resource;
+		struct r600_texture *rtex;
 
-		if (res && res->target != PIPE_BUFFER) {
-			struct r600_texture *rtex = (struct r600_texture *)res;
+		if (!res || res->target == PIPE_BUFFER)
+			continue;
 
-			(*img_handle)->needs_color_decompress =
-				color_needs_decompression(rtex);
-		}
+		rtex = (struct r600_texture *)res;
+		if (!color_needs_decompression(rtex))
+			continue;
+
+		util_dynarray_append(&sctx->resident_img_needs_color_decompress,
+				     struct si_image_handle *, *img_handle);
 	}
 }
 
@@ -2359,8 +2371,12 @@ static void si_make_texture_handle_resident(struct pipe_context *ctx,
 					tex_handle);
 			}
 
-			tex_handle->needs_color_decompress =
-				color_needs_decompression(rtex);
+			if (color_needs_decompression(rtex)) {
+				util_dynarray_append(
+					&sctx->resident_tex_needs_color_decompress,
+					struct si_texture_handle *,
+					tex_handle);
+			}
 
 			if (rtex->dcc_offset &&
 			    p_atomic_read(&rtex->framebuffers_bound))
@@ -2396,6 +2412,10 @@ static void si_make_texture_handle_resident(struct pipe_context *ctx,
 			util_dynarray_delete_unordered(
 				&sctx->resident_tex_needs_depth_decompress,
 				struct si_texture_handle *, tex_handle);
+
+			util_dynarray_delete_unordered(
+				&sctx->resident_tex_needs_color_decompress,
+				struct si_texture_handle *, tex_handle);
 		}
 	}
 }
@@ -2471,6 +2491,7 @@ static void si_make_image_handle_resident(struct pipe_context *ctx,
 	struct si_context *sctx = (struct si_context *)ctx;
 	struct si_image_handle *img_handle;
 	struct pipe_image_view *view;
+	struct r600_resource *res;
 	struct hash_entry *entry;
 
 	entry = _mesa_hash_table_search(sctx->img_handles, (void *)handle);
@@ -2479,17 +2500,19 @@ static void si_make_image_handle_resident(struct pipe_context *ctx,
 
 	img_handle = (struct si_image_handle *)entry->data;
 	view = &img_handle->view;
+	res = (struct r600_resource *)view->resource;
 
 	if (resident) {
-		struct r600_resource *res =
-			(struct r600_resource *)view->resource;
-
 		if (res->b.b.target != PIPE_BUFFER) {
 			struct r600_texture *rtex = (struct r600_texture *)res;
 			unsigned level = view->u.tex.level;
 
-			img_handle->needs_color_decompress =
-				color_needs_decompression(rtex);
+			if (color_needs_decompression(rtex)) {
+				util_dynarray_append(
+					&sctx->resident_img_needs_color_decompress,
+					struct si_image_handle *,
+					img_handle);
+			}
 
 			if (vi_dcc_enabled(rtex, level) &&
 			    p_atomic_read(&rtex->framebuffers_bound))
@@ -2521,6 +2544,13 @@ static void si_make_image_handle_resident(struct pipe_context *ctx,
 		util_dynarray_delete_unordered(&sctx->resident_img_handles,
 					       struct si_image_handle *,
 					       img_handle);
+
+		if (res->b.b.target != PIPE_BUFFER) {
+			util_dynarray_delete_unordered(
+				&sctx->resident_img_needs_color_decompress,
+				struct si_image_handle *,
+				img_handle);
+		}
 	}
 }
 
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index fbb410746c6..d4e6d42bc21 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -103,6 +103,8 @@ static void si_destroy_context(struct pipe_context *context)
 
 	util_dynarray_fini(&sctx->resident_tex_handles);
 	util_dynarray_fini(&sctx->resident_img_handles);
+	util_dynarray_fini(&sctx->resident_tex_needs_color_decompress);
+	util_dynarray_fini(&sctx->resident_img_needs_color_decompress);
 	util_dynarray_fini(&sctx->resident_tex_needs_depth_decompress);
 	FREE(sctx);
 }
@@ -343,6 +345,8 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen,
 
 	util_dynarray_init(&sctx->resident_tex_handles, NULL);
 	util_dynarray_init(&sctx->resident_img_handles, NULL);
+	util_dynarray_init(&sctx->resident_tex_needs_color_decompress, NULL);
+	util_dynarray_init(&sctx->resident_img_needs_color_decompress, NULL);
 	util_dynarray_init(&sctx->resident_tex_needs_depth_decompress, NULL);
 
 	return &sctx->b.b;
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 3834cea893f..afe68a3d35d 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -243,14 +243,12 @@ struct si_texture_handle
 {
 	struct si_bindless_descriptor	*desc;
 	struct pipe_sampler_view	*view;
-	bool				needs_color_decompress;
 };
 
 struct si_image_handle
 {
 	struct si_bindless_descriptor	*desc;
 	struct pipe_image_view		view;
-	bool				needs_color_decompress;
 };
 
 struct si_context {
@@ -432,6 +430,8 @@ struct si_context {
 	struct util_dynarray	resident_img_handles;
 
 	/* Resident bindless handles which need decompression */
+	struct util_dynarray	resident_tex_needs_color_decompress;
+	struct util_dynarray	resident_img_needs_color_decompress;
 	struct util_dynarray	resident_tex_needs_depth_decompress;
 
 	/* Bindless state */
-- 
2.13.1



More information about the mesa-dev mailing list