[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