From: Nicolai Hähnle Date: Mon, 20 Jun 2016 14:30:29 +0000 (+0200) Subject: radeonsi: extract IB and bo list saving into separate functions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ad8438403b32088260ec845fc2e7304586328913;p=mesa.git radeonsi: extract IB and bo list saving into separate functions Reviewed-by: Marek Olšák --- diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 5d4a6799729..289fb364963 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -302,6 +302,59 @@ static void r600_flush_dma_ring(void *ctx, unsigned flags, rctx->ws->fence_reference(fence, rctx->last_sdma_fence); } +/** + * Store a linearized copy of all chunks of \p cs together with the buffer + * list in \p saved. + */ +void radeon_save_cs(struct radeon_winsys *ws, struct radeon_winsys_cs *cs, + struct radeon_saved_cs *saved) +{ + void *buf; + unsigned i; + + /* Save the IB chunks. */ + saved->num_dw = cs->prev_dw + cs->current.cdw; + saved->ib = MALLOC(4 * saved->num_dw); + if (!saved->ib) + goto oom; + + buf = saved->ib; + for (i = 0; i < cs->num_prev; ++i) { + memcpy(buf, cs->prev[i].buf, cs->prev[i].cdw * 4); + buf += cs->prev[i].cdw; + } + memcpy(buf, cs->current.buf, cs->current.cdw * 4); + + /* Save the buffer list. */ + saved->bo_count = ws->cs_get_buffer_list(cs, NULL); + saved->bo_list = CALLOC(saved->bo_count, + sizeof(saved->bo_list[0])); + if (!saved->bo_list) { + FREE(saved->ib); + goto oom; + } + ws->cs_get_buffer_list(cs, saved->bo_list); + + return; + +oom: + fprintf(stderr, "%s: out of memory\n", __func__); + memset(saved, 0, sizeof(*saved)); +} + +void radeon_clear_saved_cs(struct radeon_saved_cs *saved) +{ + unsigned i; + + FREE(saved->ib); + + for (i = 0; i < saved->bo_count; i++) + pb_reference(&saved->bo_list[i].buf, NULL); + FREE(saved->bo_list); + + memset(saved, 0, sizeof(*saved)); +} + static enum pipe_reset_status r600_get_reset_status(struct pipe_context *ctx) { struct r600_common_context *rctx = (struct r600_common_context *)ctx; diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index c0e4282c23f..78421e34968 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -459,6 +459,15 @@ struct r600_ring { struct pipe_fence_handle **fence); }; +/* Saved CS data for debugging features. */ +struct radeon_saved_cs { + uint32_t *ib; + unsigned num_dw; + + struct radeon_bo_list_item *bo_list; + unsigned bo_count; +}; + struct r600_common_context { struct pipe_context b; /* base class */ @@ -624,6 +633,9 @@ const char *r600_get_llvm_processor_name(enum radeon_family family); void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw, struct r600_resource *dst, struct r600_resource *src); void r600_dma_emit_wait_idle(struct r600_common_context *rctx); +void radeon_save_cs(struct radeon_winsys *ws, struct radeon_winsys_cs *cs, + struct radeon_saved_cs *saved); +void radeon_clear_saved_cs(struct radeon_saved_cs *saved); /* r600_gpu_load.c */ void r600_gpu_load_kill_thread(struct r600_common_screen *rscreen); diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c index b551c725752..176a195e740 100644 --- a/src/gallium/drivers/radeonsi/si_debug.c +++ b/src/gallium/drivers/radeonsi/si_debug.c @@ -508,7 +508,7 @@ static void si_dump_last_ib(struct si_context *sctx, FILE *f) { int last_trace_id = -1; - if (!sctx->last_ib) + if (!sctx->last_gfx.ib) return; if (sctx->last_trace_buf) { @@ -533,11 +533,8 @@ static void si_dump_last_ib(struct si_context *sctx, FILE *f) sctx->init_config_gs_rings->ndw, -1, "IB2: Init GS rings"); - si_parse_ib(f, sctx->last_ib, sctx->last_ib_dw_size, + si_parse_ib(f, sctx->last_gfx.ib, sctx->last_gfx.num_dw, last_trace_id, "IB"); - free(sctx->last_ib); /* dump only once */ - sctx->last_ib = NULL; - r600_resource_reference(&sctx->last_trace_buf, NULL); } static const char *priority_to_string(enum radeon_bo_priority priority) @@ -592,32 +589,33 @@ static int bo_list_compare_va(const struct radeon_bo_list_item *a, a->vm_address > b->vm_address ? 1 : 0; } -static void si_dump_last_bo_list(struct si_context *sctx, FILE *f) +static void si_dump_bo_list(struct si_context *sctx, + const struct radeon_saved_cs *saved, FILE *f) { unsigned i,j; - if (!sctx->last_bo_list) + if (!saved->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); + qsort(saved->bo_list, saved->bo_count, + sizeof(saved->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++) { + for (i = 0; i < saved->bo_count; i++) { /* Note: Buffer sizes are expected to be aligned to 4k by the winsys. */ const unsigned page_size = sctx->b.screen->info.gart_page_size; - uint64_t va = sctx->last_bo_list[i].vm_address; - uint64_t size = sctx->last_bo_list[i].buf->size; + uint64_t va = saved->bo_list[i].vm_address; + uint64_t size = saved->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; + uint64_t previous_va_end = saved->bo_list[i-1].vm_address + + saved->bo_list[i-1].buf->size; if (va > previous_va_end) { fprintf(f, " %10"PRIu64" -- hole --\n", @@ -631,7 +629,7 @@ static void si_dump_last_bo_list(struct si_context *sctx, FILE *f) /* Print the usage. */ for (j = 0; j < 64; j++) { - if (!(sctx->last_bo_list[i].priority_usage & (1llu << j))) + if (!(saved->bo_list[i].priority_usage & (1llu << j))) continue; fprintf(f, "%s%s", !hit ? "" : ", ", priority_to_string(j)); @@ -641,11 +639,6 @@ static void si_dump_last_bo_list(struct si_context *sctx, FILE *f) } 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_framebuffer(struct si_context *sctx, FILE *f) @@ -687,10 +680,14 @@ static void si_dump_debug_state(struct pipe_context *ctx, FILE *f, si_dump_shader(sctx->screen, &sctx->gs_shader, f); si_dump_shader(sctx->screen, &sctx->ps_shader, f); - si_dump_last_bo_list(sctx, f); + si_dump_bo_list(sctx, &sctx->last_gfx, f); si_dump_last_ib(sctx, f); fprintf(f, "Done.\n"); + + /* dump only once */ + radeon_clear_saved_cs(&sctx->last_gfx); + r600_resource_reference(&sctx->last_trace_buf, NULL); } static bool si_vm_fault_occured(struct si_context *sctx, uint32_t *out_addr) diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index d1b98513e84..696217d0bb5 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -130,32 +130,11 @@ void si_context_gfx_flush(void *context, unsigned flags, si_trace_emit(ctx); if (ctx->is_debug) { - uint32_t *buf; - unsigned i; - /* Save the IB for debug contexts. */ - free(ctx->last_ib); - ctx->last_ib_dw_size = cs->prev_dw + cs->current.cdw; - ctx->last_ib = malloc(ctx->last_ib_dw_size * 4); - buf = ctx->last_ib; - for (i = 0; i < cs->num_prev; ++i) { - memcpy(buf, cs->prev[i].buf, cs->prev[i].cdw * 4); - buf += cs->prev[i].cdw; - } - memcpy(buf, cs->current.buf, cs->current.cdw * 4); + radeon_clear_saved_cs(&ctx->last_gfx); + radeon_save_cs(ws, cs, &ctx->last_gfx); 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 0de25b9576a..3259d5f42b2 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -90,12 +90,8 @@ 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); - } + radeon_clear_saved_cs(&sctx->last_gfx); + FREE(sctx); } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 7e68bb707de..81ad570edc9 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -321,14 +321,11 @@ struct si_context { /* Debug state. */ bool is_debug; - uint32_t *last_ib; - unsigned last_ib_dw_size; + struct radeon_saved_cs last_gfx; struct r600_resource *last_trace_buf; struct r600_resource *trace_buf; unsigned trace_id; uint64_t dmesg_timestamp; - unsigned last_bo_count; - struct radeon_bo_list_item *last_bo_list; /* Other state */ bool need_check_render_feedback;