Mesa (master): radeonsi: implement replace_buffer_storage for the threaded context

Marek Olšák mareko at kemper.freedesktop.org
Mon May 15 11:05:23 UTC 2017


Module: Mesa
Branch: master
Commit: 7166773f90d541103b85e35227d59d82b416aa45
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7166773f90d541103b85e35227d59d82b416aa45

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Sun Mar 12 14:19:31 2017 +0100

radeonsi: implement replace_buffer_storage for the threaded context

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
Tested-by: Dieter Nützel <Dieter at nuetzel-hh.de>

---

 src/gallium/drivers/radeon/r600_buffer_common.c | 23 +++++++++++++++++
 src/gallium/drivers/radeon/r600_pipe_common.h   | 11 +++++++-
 src/gallium/drivers/radeonsi/si_descriptors.c   | 34 ++++++++++++++++---------
 3 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
index 8ded99e90c..fb74b45d2f 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -273,6 +273,29 @@ r600_invalidate_buffer(struct r600_common_context *rctx,
 	return true;
 }
 
+/* Replace the storage of dst with src. */
+void r600_replace_buffer_storage(struct pipe_context *ctx,
+				 struct pipe_resource *dst,
+				 struct pipe_resource *src)
+{
+	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+	struct r600_resource *rdst = r600_resource(dst);
+	struct r600_resource *rsrc = r600_resource(src);
+	uint64_t old_gpu_address = rdst->gpu_address;
+
+	pb_reference(&rdst->buf, rsrc->buf);
+	rdst->gpu_address = rsrc->gpu_address;
+
+	assert(rdst->vram_usage == rsrc->vram_usage);
+	assert(rdst->gart_usage == rsrc->gart_usage);
+	assert(rdst->bo_size == rsrc->bo_size);
+	assert(rdst->bo_alignment == rsrc->bo_alignment);
+	assert(rdst->domains == rsrc->domains);
+	assert(rdst->flags == rsrc->flags);
+
+	rctx->rebind_buffer(ctx, dst, old_gpu_address);
+}
+
 void r600_invalidate_resource(struct pipe_context *ctx,
 			      struct pipe_resource *resource)
 {
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index a694b974ad..f9c9f115b8 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -666,6 +666,12 @@ struct r600_common_context {
 	 * the buffer is bound, including all resource descriptors. */
 	void (*invalidate_buffer)(struct pipe_context *ctx, struct pipe_resource *buf);
 
+	/* Update all resource bindings where the buffer is bound, including
+	 * all resource descriptors. This is invalidate_buffer without
+	 * the invalidation. */
+	void (*rebind_buffer)(struct pipe_context *ctx, struct pipe_resource *buf,
+			      uint64_t old_gpu_address);
+
 	/* Enable or disable occlusion queries. */
 	void (*set_occlusion_query_state)(struct pipe_context *ctx, bool enable);
 
@@ -683,7 +689,7 @@ struct r600_common_context {
 				enum ring_type ring);
 };
 
-/* r600_buffer.c */
+/* r600_buffer_common.c */
 bool r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
 				     struct pb_buffer *buf,
 				     enum radeon_bo_usage usage);
@@ -714,6 +720,9 @@ r600_buffer_from_user_memory(struct pipe_screen *screen,
 void
 r600_invalidate_resource(struct pipe_context *ctx,
 			 struct pipe_resource *resource);
+void r600_replace_buffer_storage(struct pipe_context *ctx,
+				 struct pipe_resource *dst,
+				 struct pipe_resource *src);
 
 /* r600_common_pipe.c */
 void r600_gfx_write_event_eop(struct r600_common_context *ctx,
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 8d3454194d..c92a6575ed 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -1626,25 +1626,15 @@ static void si_reset_buffer_resources(struct si_context *sctx,
 	}
 }
 
-/* Reallocate a buffer a update all resource bindings where the buffer is
- * bound.
- *
- * This is used to avoid CPU-GPU synchronizations, because it makes the buffer
- * idle by discarding its contents. Apps usually tell us when to do this using
- * map_buffer flags, for example.
- */
-static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource *buf)
+static void si_rebind_buffer(struct pipe_context *ctx, struct pipe_resource *buf,
+			     uint64_t old_va)
 {
 	struct si_context *sctx = (struct si_context*)ctx;
 	struct r600_resource *rbuffer = r600_resource(buf);
 	unsigned i, shader;
-	uint64_t old_va = rbuffer->gpu_address;
 	unsigned num_elems = sctx->vertex_elements ?
 				       sctx->vertex_elements->count : 0;
 
-	/* Reallocate the buffer in the same pipe_resource. */
-	r600_alloc_resource(&sctx->screen->b, rbuffer);
-
 	/* We changed the buffer, now we need to bind it where the old one
 	 * was bound. This consists of 2 things:
 	 *   1) Updating the resource descriptor and dirtying it.
@@ -1772,6 +1762,25 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
 	}
 }
 
+/* Reallocate a buffer a update all resource bindings where the buffer is
+ * bound.
+ *
+ * This is used to avoid CPU-GPU synchronizations, because it makes the buffer
+ * idle by discarding its contents. Apps usually tell us when to do this using
+ * map_buffer flags, for example.
+ */
+static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource *buf)
+{
+	struct si_context *sctx = (struct si_context*)ctx;
+	struct r600_resource *rbuffer = r600_resource(buf);
+	uint64_t old_va = rbuffer->gpu_address;
+
+	/* Reallocate the buffer in the same pipe_resource. */
+	r600_alloc_resource(&sctx->screen->b, rbuffer);
+
+	si_rebind_buffer(ctx, buf, old_va);
+}
+
 /* Update mutable image descriptor fields of all bound textures. */
 void si_update_all_texture_descriptors(struct si_context *sctx)
 {
@@ -2067,6 +2076,7 @@ void si_init_all_descriptors(struct si_context *sctx)
 	sctx->b.b.set_sampler_views = si_set_sampler_views;
 	sctx->b.b.set_stream_output_targets = si_set_streamout_targets;
 	sctx->b.invalidate_buffer = si_invalidate_buffer;
+	sctx->b.rebind_buffer = si_rebind_buffer;
 
 	/* Shader user data. */
 	si_init_atom(sctx, &sctx->shader_userdata.atom, &sctx->atoms.s.shader_userdata,




More information about the mesa-commit mailing list