From: Marek Olšák Date: Sat, 26 Sep 2015 23:38:48 +0000 (+0200) Subject: radeonsi: dump buffer lists while debugging X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cc92b9037507ccfb498bdcec27b4d186e230004f;p=mesa.git radeonsi: dump buffer lists while debugging Reviewed-by: Michel Dänzer --- 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 */