aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeonsi/si_debug.c110
-rw-r--r--src/gallium/drivers/radeonsi/si_hw_context.c15
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c5
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h2
4 files changed, 131 insertions, 1 deletions
diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c
index 3d127236831..7d41e8d00e0 100644
--- a/src/gallium/drivers/radeonsi/si_debug.c
+++ b/src/gallium/drivers/radeonsi/si_debug.c
@@ -420,6 +420,114 @@ static void si_dump_last_ib(struct si_context *sctx, FILE *f)
r600_resource_reference(&sctx->last_trace_buf, NULL);
}
+static const char *priority_to_string(enum radeon_bo_priority priority)
+{
+#define ITEM(x) [RADEON_PRIO_##x] = #x
+ static const char *table[64] = {
+ ITEM(FENCE),
+ ITEM(TRACE),
+ ITEM(SO_FILLED_SIZE),
+ ITEM(QUERY),
+ ITEM(IB1),
+ ITEM(IB2),
+ ITEM(DRAW_INDIRECT),
+ ITEM(INDEX_BUFFER),
+ ITEM(CP_DMA),
+ ITEM(VCE),
+ ITEM(UVD),
+ ITEM(SDMA_BUFFER),
+ ITEM(SDMA_TEXTURE),
+ ITEM(USER_SHADER),
+ ITEM(INTERNAL_SHADER),
+ ITEM(CONST_BUFFER),
+ ITEM(DESCRIPTORS),
+ ITEM(BORDER_COLORS),
+ ITEM(SAMPLER_BUFFER),
+ ITEM(VERTEX_BUFFER),
+ ITEM(SHADER_RW_BUFFER),
+ ITEM(RINGS_STREAMOUT),
+ ITEM(SCRATCH_BUFFER),
+ ITEM(COMPUTE_GLOBAL),
+ ITEM(SAMPLER_TEXTURE),
+ ITEM(SHADER_RW_IMAGE),
+ ITEM(SAMPLER_TEXTURE_MSAA),
+ ITEM(COLOR_BUFFER),
+ ITEM(DEPTH_BUFFER),
+ ITEM(COLOR_BUFFER_MSAA),
+ ITEM(DEPTH_BUFFER_MSAA),
+ ITEM(CMASK),
+ ITEM(DCC),
+ ITEM(HTILE),
+ };
+#undef ITEM
+
+ assert(priority < ARRAY_SIZE(table));
+ return table[priority];
+}
+
+static int bo_list_compare_va(const struct radeon_bo_list_item *a,
+ const struct radeon_bo_list_item *b)
+{
+ return a->vm_address < b->vm_address ? -1 :
+ a->vm_address > b->vm_address ? 1 : 0;
+}
+
+static void si_dump_last_bo_list(struct si_context *sctx, FILE *f)
+{
+ unsigned i,j;
+
+ if (!sctx->last_bo_list)
+ return;
+
+ /* Sort the list according to VM adddresses first. */
+ qsort(sctx->last_bo_list, sctx->last_bo_count,
+ sizeof(sctx->last_bo_list[0]), (void*)bo_list_compare_va);
+
+ fprintf(f, "Buffer list (in units of pages = 4kB):\n"
+ COLOR_YELLOW " Size VM start page "
+ "VM end page Usage" COLOR_RESET "\n");
+
+ for (i = 0; i < sctx->last_bo_count; i++) {
+ /* Note: Buffer sizes are expected to be aligned to 4k by the winsys. */
+ const unsigned page_size = 4096;
+ uint64_t va = sctx->last_bo_list[i].vm_address;
+ uint64_t size = sctx->last_bo_list[i].buf->size;
+ bool hit = false;
+
+ /* If there's unused virtual memory between 2 buffers, print it. */
+ if (i) {
+ uint64_t previous_va_end = sctx->last_bo_list[i-1].vm_address +
+ sctx->last_bo_list[i-1].buf->size;
+
+ if (va > previous_va_end) {
+ fprintf(f, " %10"PRIu64" -- hole --\n",
+ (va - previous_va_end) / page_size);
+ }
+ }
+
+ /* Print the buffer. */
+ fprintf(f, " %10"PRIu64" 0x%013"PRIx64" 0x%013"PRIx64" ",
+ size / page_size, va / page_size, (va + size) / page_size);
+
+ /* Print the usage. */
+ for (j = 0; j < 64; j++) {
+ if (!(sctx->last_bo_list[i].priority_usage & (1llu << j)))
+ continue;
+
+ fprintf(f, "%s%s", !hit ? "" : ", ", priority_to_string(j));
+ hit = true;
+ }
+ fprintf(f, "\n");
+ }
+ fprintf(f, "\nNote: The holes represent memory not used by the IB.\n"
+ " Other buffers can still be allocated there.\n\n");
+
+ for (i = 0; i < sctx->last_bo_count; i++)
+ pb_reference(&sctx->last_bo_list[i].buf, NULL);
+ free(sctx->last_bo_list);
+ sctx->last_bo_list = NULL;
+}
+
static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
unsigned flags)
{
@@ -434,6 +542,7 @@ static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
si_dump_shader(sctx->gs_shader, "Geometry", f);
si_dump_shader(sctx->ps_shader, "Fragment", f);
+ si_dump_last_bo_list(sctx, f);
si_dump_last_ib(sctx, f);
fprintf(f, "Done.\n");
@@ -538,6 +647,7 @@ void si_check_vm_faults(struct si_context *sctx)
fprintf(f, "Device name: %s\n\n", screen->get_name(screen));
fprintf(f, "Failing VM page: 0x%08x\n\n", addr);
+ si_dump_last_bo_list(sctx, f);
si_dump_last_ib(sctx, f);
fclose(f);
diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c
index de95d12f000..17d89d16e24 100644
--- a/src/gallium/drivers/radeonsi/si_hw_context.c
+++ b/src/gallium/drivers/radeonsi/si_hw_context.c
@@ -85,14 +85,27 @@ void si_context_gfx_flush(void *context, unsigned flags,
if (ctx->trace_buf)
si_trace_emit(ctx);
- /* Save the IB for debug contexts. */
if (ctx->is_debug) {
+ unsigned i;
+
+ /* Save the IB for debug contexts. */
free(ctx->last_ib);
ctx->last_ib_dw_size = cs->cdw;
ctx->last_ib = malloc(cs->cdw * 4);
memcpy(ctx->last_ib, cs->buf, cs->cdw * 4);
r600_resource_reference(&ctx->last_trace_buf, ctx->trace_buf);
r600_resource_reference(&ctx->trace_buf, NULL);
+
+ /* Save the buffer list. */
+ if (ctx->last_bo_list) {
+ for (i = 0; i < ctx->last_bo_count; i++)
+ pb_reference(&ctx->last_bo_list[i].buf, NULL);
+ free(ctx->last_bo_list);
+ }
+ ctx->last_bo_count = ws->cs_get_buffer_list(cs, NULL);
+ ctx->last_bo_list = calloc(ctx->last_bo_count,
+ sizeof(ctx->last_bo_list[0]));
+ ws->cs_get_buffer_list(cs, ctx->last_bo_list);
}
/* Flush the CS. */
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 5a2b60620e3..cdd33aa0831 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -81,6 +81,11 @@ static void si_destroy_context(struct pipe_context *context)
r600_resource_reference(&sctx->trace_buf, NULL);
r600_resource_reference(&sctx->last_trace_buf, NULL);
free(sctx->last_ib);
+ if (sctx->last_bo_list) {
+ for (i = 0; i < sctx->last_bo_count; i++)
+ pb_reference(&sctx->last_bo_list[i].buf, NULL);
+ free(sctx->last_bo_list);
+ }
FREE(sctx);
}
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 1c26022bb1b..41b2832322c 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -277,6 +277,8 @@ struct si_context {
struct r600_resource *trace_buf;
unsigned trace_id;
uint64_t dmesg_timestamp;
+ unsigned last_bo_count;
+ struct radeon_bo_list_item *last_bo_list;
};
/* cik_sdma.c */