[Mesa-dev] [PATCH 06/13] gallium/radeon: handle TC_TRANSFER_MAP_THREADED_UNSYNC

Marek Olšák maraeo at gmail.com
Wed May 10 22:45:39 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/radeon/r600_buffer_common.c | 12 +++++++++++-
 src/gallium/drivers/radeon/r600_pipe_common.c   |  2 ++
 src/gallium/drivers/radeon/r600_pipe_common.h   |  1 +
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
index 6a4846a..4132858 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -20,20 +20,21 @@
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors:
  *      Marek Olšák
  */
 
 #include "r600_cs.h"
 #include "util/u_memory.h"
 #include "util/u_upload_mgr.h"
+#include "util/u_threaded_context.h"
 #include <inttypes.h>
 #include <stdio.h>
 
 bool r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
 				     struct pb_buffer *buf,
 				     enum radeon_bo_usage usage)
 {
 	if (ctx->ws->cs_is_buffer_referenced(ctx->gfx.cs, buf, usage)) {
 		return true;
 	}
@@ -285,21 +286,26 @@ void r600_invalidate_resource(struct pipe_context *ctx,
 
 static void *r600_buffer_get_transfer(struct pipe_context *ctx,
 				      struct pipe_resource *resource,
                                       unsigned usage,
                                       const struct pipe_box *box,
 				      struct pipe_transfer **ptransfer,
 				      void *data, struct r600_resource *staging,
 				      unsigned offset)
 {
 	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
-	struct r600_transfer *transfer = slab_alloc(&rctx->pool_transfers);
+	struct r600_transfer *transfer;
+
+	if (usage & TC_TRANSFER_MAP_THREADED_UNSYNC)
+		transfer = slab_alloc(&rctx->pool_transfers_unsync);
+	else
+		transfer = slab_alloc(&rctx->pool_transfers);
 
 	transfer->transfer.resource = NULL;
 	pipe_resource_reference(&transfer->transfer.resource, resource);
 	transfer->transfer.level = 0;
 	transfer->transfer.usage = usage;
 	transfer->transfer.box = *box;
 	transfer->transfer.stride = 0;
 	transfer->transfer.layer_stride = 0;
 	transfer->offset = offset;
 	transfer->staging = staging;
@@ -411,20 +417,21 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx,
 	}
 	/* Use a staging buffer in cached GTT for reads. */
 	else if (((usage & PIPE_TRANSFER_READ) &&
 		  !(usage & PIPE_TRANSFER_PERSISTENT) &&
 		  (rbuffer->domains & RADEON_DOMAIN_VRAM ||
 		   rbuffer->flags & RADEON_FLAG_GTT_WC) &&
 		  r600_can_dma_copy_buffer(rctx, 0, box->x, box->width)) ||
 		 (rbuffer->flags & RADEON_FLAG_SPARSE)) {
 		struct r600_resource *staging;
 
+		assert(!(usage & TC_TRANSFER_MAP_THREADED_UNSYNC));
 		staging = (struct r600_resource*) pipe_buffer_create(
 				ctx->screen, 0, PIPE_USAGE_STAGING,
 				box->width + (box->x % R600_MAP_BUFFER_ALIGNMENT));
 		if (staging) {
 			/* Copy the VRAM buffer to the staging buffer. */
 			rctx->dma_copy(ctx, &staging->b.b, 0,
 				       box->x % R600_MAP_BUFFER_ALIGNMENT,
 				       0, 0, resource, 0, box);
 
 			data = r600_buffer_map_sync_with_rings(rctx, staging,
@@ -500,20 +507,23 @@ static void r600_buffer_transfer_unmap(struct pipe_context *ctx,
 	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
 
 	if (transfer->usage & PIPE_TRANSFER_WRITE &&
 	    !(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT))
 		r600_buffer_do_flush_region(ctx, transfer, &transfer->box);
 
 	if (rtransfer->staging)
 		r600_resource_reference(&rtransfer->staging, NULL);
 
 	pipe_resource_reference(&transfer->resource, NULL);
+
+	/* Don't use pool_transfers_unsync. We are always in the driver
+	 * thread. */
 	slab_free(&rctx->pool_transfers, transfer);
 }
 
 void r600_buffer_subdata(struct pipe_context *ctx,
 			 struct pipe_resource *buffer,
 			 unsigned usage, unsigned offset,
 			 unsigned size, const void *data)
 {
 	struct pipe_transfer *transfer = NULL;
 	struct pipe_box box;
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index d4909c5..9cb767f 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -603,20 +603,21 @@ static bool r600_resource_commit(struct pipe_context *pctx,
 	assert(resource->target == PIPE_BUFFER);
 
 	return ctx->ws->buffer_commit(res->buf, box->x, box->width, commit);
 }
 
 bool r600_common_context_init(struct r600_common_context *rctx,
 			      struct r600_common_screen *rscreen,
 			      unsigned context_flags)
 {
 	slab_create_child(&rctx->pool_transfers, &rscreen->pool_transfers);
+	slab_create_child(&rctx->pool_transfers_unsync, &rscreen->pool_transfers);
 
 	rctx->screen = rscreen;
 	rctx->ws = rscreen->ws;
 	rctx->family = rscreen->family;
 	rctx->chip_class = rscreen->chip_class;
 
 	rctx->b.invalidate_resource = r600_invalidate_resource;
 	rctx->b.resource_commit = r600_resource_commit;
 	rctx->b.transfer_map = u_transfer_map_vtbl;
 	rctx->b.transfer_flush_region = u_transfer_flush_region_vtbl;
@@ -706,20 +707,21 @@ void r600_common_context_cleanup(struct r600_common_context *rctx)
 		rctx->ws->cs_destroy(rctx->dma.cs);
 	if (rctx->ctx)
 		rctx->ws->ctx_destroy(rctx->ctx);
 
 	if (rctx->b.stream_uploader)
 		u_upload_destroy(rctx->b.stream_uploader);
 	if (rctx->b.const_uploader)
 		u_upload_destroy(rctx->b.const_uploader);
 
 	slab_destroy_child(&rctx->pool_transfers);
+	slab_destroy_child(&rctx->pool_transfers_unsync);
 
 	if (rctx->allocator_zeroed_memory) {
 		u_suballocator_destroy(rctx->allocator_zeroed_memory);
 	}
 	rctx->ws->fence_reference(&rctx->last_gfx_fence, NULL);
 	rctx->ws->fence_reference(&rctx->last_sdma_fence, NULL);
 }
 
 /*
  * pipe_screen
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 3e83d37..51d797a 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -548,20 +548,21 @@ struct r600_common_context {
 	struct pipe_fence_handle	*last_gfx_fence;
 	struct pipe_fence_handle	*last_sdma_fence;
 	unsigned			num_gfx_cs_flushes;
 	unsigned			initial_gfx_cs_size;
 	unsigned			gpu_reset_counter;
 	unsigned			last_dirty_tex_counter;
 	unsigned			last_compressed_colortex_counter;
 
 	struct u_suballocator		*allocator_zeroed_memory;
 	struct slab_child_pool		pool_transfers;
+	struct slab_child_pool		pool_transfers_unsync; /* for threaded_context */
 
 	/* Current unaccounted memory usage. */
 	uint64_t			vram;
 	uint64_t			gtt;
 
 	/* States. */
 	struct r600_streamout		streamout;
 	struct r600_scissors		scissors;
 	struct r600_viewports		viewports;
 	bool				scissor_enabled;
-- 
2.7.4



More information about the mesa-dev mailing list