[Mesa-dev] [PATCH 07/19] radeonsi: track buffer bind history

Marek Olšák maraeo at gmail.com
Sun Oct 2 21:09:22 UTC 2016


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

similar to gl_buffer_object::UsageHistory
---
 src/gallium/drivers/radeon/r600_buffer_common.c |  1 +
 src/gallium/drivers/radeon/r600_pipe_common.h   |  1 +
 src/gallium/drivers/radeonsi/si_descriptors.c   | 11 ++++++++++-
 src/gallium/drivers/radeonsi/si_state.c         | 15 +++++++++++----
 4 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
index 784522d..228674a 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -509,20 +509,21 @@ r600_alloc_buffer_struct(struct pipe_screen *screen,
 	struct r600_resource *rbuffer;
 
 	rbuffer = MALLOC_STRUCT(r600_resource);
 
 	rbuffer->b.b = *templ;
 	rbuffer->b.b.next = NULL;
 	pipe_reference_init(&rbuffer->b.b.reference, 1);
 	rbuffer->b.b.screen = screen;
 	rbuffer->b.vtbl = &r600_buffer_vtbl;
 	rbuffer->buf = NULL;
+	rbuffer->bind_history = 0;
 	rbuffer->TC_L2_dirty = false;
 	rbuffer->is_shared = false;
 	util_range_init(&rbuffer->valid_buffer_range);
 	return rbuffer;
 }
 
 struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
 					 const struct pipe_resource *templ,
 					 unsigned alignment)
 {
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 038c7c7..cea1f22 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -173,20 +173,21 @@ struct r600_resource {
 	uint64_t			gpu_address;
 	/* Memory usage if the buffer placement is optimal. */
 	uint64_t			vram_usage;
 	uint64_t			gart_usage;
 
 	/* Resource properties. */
 	uint64_t			bo_size;
 	unsigned			bo_alignment;
 	enum radeon_bo_domain		domains;
 	enum radeon_bo_flag		flags;
+	unsigned			bind_history;
 
 	/* The buffer range which is initialized (with a write transfer,
 	 * streamout, DMA, or as a random access target). The rest of
 	 * the buffer is considered invalid and can be mapped unsynchronized.
 	 *
 	 * This allows unsychronized mapping of a buffer range which hasn't
 	 * been used yet. It's for applications which forget to use
 	 * the unsynchronized map flag and expect the driver to figure it out.
          */
 	struct util_range		valid_buffer_range;
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 693233d..43bef81 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -407,21 +407,23 @@ static void si_set_sampler_view(struct si_context *sctx,
 		return;
 
 	if (view) {
 		struct r600_texture *rtex = (struct r600_texture *)view->texture;
 		uint32_t *desc = descs->list + slot * 16;
 
 		assert(rtex); /* NULL views aren't supported */
 		pipe_sampler_view_reference(&views->views[slot], view);
 		memcpy(desc, rview->state, 8*4);
 
-		if (rtex->resource.b.b.target != PIPE_BUFFER) {
+		if (rtex->resource.b.b.target == PIPE_BUFFER) {
+			rtex->resource.bind_history |= PIPE_BIND_SAMPLER_VIEW;
+		} else {
 			bool is_separate_stencil =
 				rtex->db_compatible &&
 				rview->is_stencil_sampler;
 
 			si_set_mutable_tex_desc_fields(rtex,
 						       rview->base_level_info,
 						       rview->base_level,
 						       rview->base.u.tex.first_level,
 						       rview->block_width,
 						       is_separate_stencil,
@@ -633,20 +635,21 @@ static void si_set_shader_image(struct si_context *ctx,
 	if (res->b.b.target == PIPE_BUFFER) {
 		if (view->access & PIPE_IMAGE_ACCESS_WRITE)
 			si_mark_image_range_valid(view);
 
 		si_make_buffer_descriptor(screen, res,
 					  view->format,
 					  view->u.buf.offset,
 					  view->u.buf.size,
 					  descs->list + slot * 8);
 		images->compressed_colortex_mask &= ~(1 << slot);
+		res->bind_history |= PIPE_BIND_SHADER_IMAGE;
 	} else {
 		static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
 		struct r600_texture *tex = (struct r600_texture *)res;
 		unsigned level = view->u.tex.level;
 		unsigned width, height, depth;
 		uint32_t *desc = descs->list + slot * 8;
 		bool uses_dcc = tex->dcc_offset &&
 				tex->surface.level[level].dcc_enabled;
 
 		assert(!tex->is_depth);
@@ -1025,20 +1028,22 @@ static void si_set_constant_buffer(struct si_context *sctx,
 					       input->buffer_size, &buffer_offset);
 			if (!buffer) {
 				/* Just unbind on failure. */
 				si_set_constant_buffer(sctx, buffers, descriptors_idx, slot, NULL);
 				return;
 			}
 			va = r600_resource(buffer)->gpu_address + buffer_offset;
 		} else {
 			pipe_resource_reference(&buffer, input->buffer);
 			va = r600_resource(buffer)->gpu_address + input->buffer_offset;
+			/* Only track usage for non-user buffers. */
+			r600_resource(buffer)->bind_history |= PIPE_BIND_CONSTANT_BUFFER;
 		}
 
 		/* Set the descriptor. */
 		uint32_t *desc = descs->list + slot*4;
 		desc[0] = va;
 		desc[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
 			  S_008F04_STRIDE(0);
 		desc[2] = input->buffer_size;
 		desc[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
 			  S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
@@ -1150,20 +1155,22 @@ static void si_set_shader_buffers(struct pipe_context *ctx,
 			  S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
 			  S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
 			  S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
 			  S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
 			  S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
 
 		pipe_resource_reference(&buffers->buffers[slot], &buf->b.b);
 		radeon_add_to_buffer_list_check_mem(&sctx->b, &sctx->b.gfx, buf,
 						    buffers->shader_usage,
 						    buffers->priority, true);
+		buf->bind_history |= PIPE_BIND_SHADER_BUFFER;
+
 		buffers->enabled_mask |= 1u << slot;
 		descs->dirty_mask |= 1u << slot;
 		sctx->descriptors_dirty |=
 			1u << si_shader_buffer_descriptors_idx(shader);
 	}
 }
 
 void si_get_shader_buffers(struct si_context *sctx, uint shader,
 			   uint start_slot, uint count,
 			   struct pipe_shader_buffer *sbuf)
@@ -1356,20 +1363,22 @@ static void si_set_streamout_targets(struct pipe_context *ctx,
 				  S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
 
 			/* Set the resource. */
 			pipe_resource_reference(&buffers->buffers[bufidx],
 						buffer);
 			radeon_add_to_buffer_list_check_mem(&sctx->b, &sctx->b.gfx,
 							    (struct r600_resource*)buffer,
 							    buffers->shader_usage,
 							    RADEON_PRIO_SHADER_RW_BUFFER,
 							    true);
+			r600_resource(buffer)->bind_history |= PIPE_BIND_STREAM_OUTPUT;
+
 			buffers->enabled_mask |= 1u << bufidx;
 		} else {
 			/* Clear the descriptor and unset the resource. */
 			memset(descs->list + bufidx*4, 0,
 			       sizeof(uint32_t) * 4);
 			pipe_resource_reference(&buffers->buffers[bufidx],
 						NULL);
 			buffers->enabled_mask &= ~(1u << bufidx);
 		}
 		descs->dirty_mask |= 1u << bufidx;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 0376693..92f8d90 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3297,43 +3297,50 @@ static void si_set_vertex_buffers(struct pipe_context *ctx,
 	struct si_context *sctx = (struct si_context *)ctx;
 	struct pipe_vertex_buffer *dst = sctx->vertex_buffer + start_slot;
 	int i;
 
 	assert(start_slot + count <= ARRAY_SIZE(sctx->vertex_buffer));
 
 	if (buffers) {
 		for (i = 0; i < count; i++) {
 			const struct pipe_vertex_buffer *src = buffers + i;
 			struct pipe_vertex_buffer *dsti = dst + i;
+			struct pipe_resource *buf = src->buffer;
 
-			pipe_resource_reference(&dsti->buffer, src->buffer);
+			pipe_resource_reference(&dsti->buffer, buf);
 			dsti->buffer_offset = src->buffer_offset;
 			dsti->stride = src->stride;
-			r600_context_add_resource_size(ctx, src->buffer);
+			r600_context_add_resource_size(ctx, buf);
+			if (buf)
+				r600_resource(buf)->bind_history |= PIPE_BIND_VERTEX_BUFFER;
 		}
 	} else {
 		for (i = 0; i < count; i++) {
 			pipe_resource_reference(&dst[i].buffer, NULL);
 		}
 	}
 	sctx->vertex_buffers_dirty = true;
 }
 
 static void si_set_index_buffer(struct pipe_context *ctx,
 				const struct pipe_index_buffer *ib)
 {
 	struct si_context *sctx = (struct si_context *)ctx;
 
 	if (ib) {
-		pipe_resource_reference(&sctx->index_buffer.buffer, ib->buffer);
+		struct pipe_resource *buf = ib->buffer;
+
+		pipe_resource_reference(&sctx->index_buffer.buffer, buf);
 	        memcpy(&sctx->index_buffer, ib, sizeof(*ib));
-		r600_context_add_resource_size(ctx, ib->buffer);
+		r600_context_add_resource_size(ctx, buf);
+		if (buf)
+			r600_resource(buf)->bind_history |= PIPE_BIND_INDEX_BUFFER;
 	} else {
 		pipe_resource_reference(&sctx->index_buffer.buffer, NULL);
 	}
 }
 
 /*
  * Misc
  */
 
 static void si_set_tess_state(struct pipe_context *ctx,
-- 
2.7.4



More information about the mesa-dev mailing list