Browse Source

radeonsi: extract IB and bo list saving into separate functions

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
tags/13.0-branchpoint
Nicolai Hähnle 9 years ago
parent
commit
ad8438403b

+ 53
- 0
src/gallium/drivers/radeon/r600_pipe_common.c View File

@@ -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;

+ 12
- 0
src/gallium/drivers/radeon/r600_pipe_common.h View File

@@ -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);

+ 18
- 21
src/gallium/drivers/radeonsi/si_debug.c View File

@@ -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)

+ 2
- 23
src/gallium/drivers/radeonsi/si_hw_context.c View File

@@ -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. */

+ 2
- 6
src/gallium/drivers/radeonsi/si_pipe.c View File

@@ -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);
}


+ 1
- 4
src/gallium/drivers/radeonsi/si_pipe.h View File

@@ -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;

Loading…
Cancel
Save