[Freedreno] [PATCH 12/12] freedreno: support discarding previous rendering in special cases

Rob Clark robdclark at gmail.com
Sat Jul 2 16:52:15 UTC 2016


Basically, to "DCE" blits triggered by resource shadowing, in cases
where the levels are immediately completely overwritten.  For example,
mid-frame texture upload to level zero triggers shadowing and back-blits
to the remaining levels, which are immediately overwritten by
glGenerateMipmap().

Signed-off-by: Rob Clark <robdclark at gmail.com>
---
 src/gallium/drivers/freedreno/freedreno_context.h  |  6 ++++++
 src/gallium/drivers/freedreno/freedreno_draw.c     | 10 ++++++++++
 src/gallium/drivers/freedreno/freedreno_resource.c | 21 ++++++++++++++++-----
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index ca3c01b..5b3d707 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -301,6 +301,12 @@ struct fd_context {
 	 */
 	bool in_shadow;
 
+	/* Ie. in blit situation where we no longer care about previous framebuffer
+	 * contents.  Main point is to eliminate blits from fd_try_shadow_resource().
+	 * For example, in case of texture upload + gen-mipmaps.
+	 */
+	bool discard;
+
 	struct pipe_debug_callback debug;
 
 	/* GMEM/tile handling fxns: */
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index 481fb3d..fd4fc08 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -84,6 +84,11 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 		return;
 	}
 
+	if (ctx->discard) {
+		fd_batch_reset(ctx->batch);
+		ctx->discard = false;
+	}
+
 	/*
 	 * Figure out the buffers/features we need:
 	 */
@@ -209,6 +214,11 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
 	if (!fd_render_condition_check(pctx))
 		return;
 
+	if (ctx->discard) {
+		fd_batch_reset(ctx->batch);
+		ctx->discard = false;
+	}
+
 	/* for bookkeeping about which buffers have been cleared (and thus
 	 * can fully or partially skip mem2gmem) we need to ignore buffers
 	 * that have already had a draw, in case apps do silly things like
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 8ff0d4a..46bb7c7 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -116,7 +116,7 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
 	util_range_set_empty(&rsc->valid_buffer_range);
 }
 
-static void fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond);
+static void fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond, bool discard);
 static void fd_blitter_pipe_end(struct fd_context *ctx);
 
 static void
@@ -125,7 +125,7 @@ do_blit(struct fd_context *ctx, const struct pipe_blit_info *blit, bool fallback
 	/* TODO size threshold too?? */
 	if ((blit->src.resource->target != PIPE_BUFFER) && !fallback) {
 		/* do blit on gpu: */
-		fd_blitter_pipe_begin(ctx, false);
+		fd_blitter_pipe_begin(ctx, false, true);
 		util_blitter_blit(ctx->blitter, blit);
 		fd_blitter_pipe_end(ctx);
 	} else {
@@ -897,7 +897,8 @@ fd_blitter_pipe_copy_region(struct fd_context *ctx,
 	if (!util_blitter_is_copy_supported(ctx->blitter, dst, src))
 		return false;
 
-	fd_blitter_pipe_begin(ctx, false);
+	/* TODO we could discard if dst box covers dst level fully.. */
+	fd_blitter_pipe_begin(ctx, false, false);
 	util_blitter_copy_texture(ctx->blitter,
 			dst, dst_level, dstx, dsty, dstz,
 			src, src_level, src_box);
@@ -967,6 +968,7 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
 {
 	struct fd_context *ctx = fd_context(pctx);
 	struct pipe_blit_info info = *blit_info;
+	bool discard = false;
 
 	if (info.src.resource->nr_samples > 1 &&
 			info.dst.resource->nr_samples <= 1 &&
@@ -979,6 +981,13 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
 	if (info.render_condition_enable && !fd_render_condition_check(pctx))
 		return;
 
+	if (!info.scissor_enable && !info.alpha_blend) {
+		discard = util_texrange_covers_whole_level(info.dst.resource,
+				info.dst.level, info.dst.box.x, info.dst.box.y,
+				info.dst.box.z, info.dst.box.width,
+				info.dst.box.height, info.dst.box.depth);
+	}
+
 	if (util_try_blit_via_copy_region(pctx, &info)) {
 		return; /* done */
 	}
@@ -995,13 +1004,13 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
 		return;
 	}
 
-	fd_blitter_pipe_begin(ctx, info.render_condition_enable);
+	fd_blitter_pipe_begin(ctx, info.render_condition_enable, discard);
 	util_blitter_blit(ctx->blitter, &info);
 	fd_blitter_pipe_end(ctx);
 }
 
 static void
-fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond)
+fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond, bool discard)
 {
 	util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
 	util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx.vtx);
@@ -1027,6 +1036,8 @@ fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond)
 			ctx->cond_query, ctx->cond_cond, ctx->cond_mode);
 
 	fd_hw_query_set_stage(ctx, ctx->batch->draw, FD_STAGE_BLIT);
+
+	ctx->discard = discard;
 }
 
 static void
-- 
2.7.4



More information about the Freedreno mailing list