diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-01-22 02:13:18 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-01-22 02:13:18 +0000 |
commit | fdcc03929065b5bf5dd93553db219ea3e05c8c34 (patch) | |
tree | ca90dc8d9e89febdcd4160956c1b8ec098a4efc9 /lib/mesa/src/gallium/auxiliary/driver_ddebug/dd_draw.c | |
parent | 3c9de4a7e13712b5696750bbd59a18c848742022 (diff) |
Import Mesa 19.2.8
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/driver_ddebug/dd_draw.c')
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/driver_ddebug/dd_draw.c | 171 |
1 files changed, 142 insertions, 29 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/driver_ddebug/dd_draw.c b/lib/mesa/src/gallium/auxiliary/driver_ddebug/dd_draw.c index f5b943561..1d8e57767 100644 --- a/lib/mesa/src/gallium/auxiliary/driver_ddebug/dd_draw.c +++ b/lib/mesa/src/gallium/auxiliary/driver_ddebug/dd_draw.c @@ -33,14 +33,76 @@ #include "util/u_helpers.h" #include "util/u_inlines.h" #include "util/u_memory.h" +#include "util/u_process.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_scan.h" #include "util/os_time.h" #include <inttypes.h> #include "pipe/p_config.h" +void +dd_get_debug_filename_and_mkdir(char *buf, size_t buflen, bool verbose) +{ + static unsigned index; + char proc_name[128], dir[256]; -static void + if (!os_get_process_name(proc_name, sizeof(proc_name))) { + fprintf(stderr, "dd: can't get the process name\n"); + strcpy(proc_name, "unknown"); + } + + snprintf(dir, sizeof(dir), "%s/"DD_DIR, debug_get_option("HOME", ".")); + + if (mkdir(dir, 0774) && errno != EEXIST) + fprintf(stderr, "dd: can't create a directory (%i)\n", errno); + + snprintf(buf, buflen, "%s/%s_%u_%08u", dir, proc_name, getpid(), + (unsigned int)p_atomic_inc_return(&index) - 1); + + if (verbose) + fprintf(stderr, "dd: dumping to file %s\n", buf); +} + +FILE * +dd_get_debug_file(bool verbose) +{ + char name[512]; + FILE *f; + + dd_get_debug_filename_and_mkdir(name, sizeof(name), verbose); + f = fopen(name, "w"); + if (!f) { + fprintf(stderr, "dd: can't open file %s\n", name); + return NULL; + } + + return f; +} + +void +dd_parse_apitrace_marker(const char *string, int len, unsigned *call_number) +{ + unsigned num; + char *s; + + if (len <= 0) + return; + + /* Make it zero-terminated. */ + s = alloca(len + 1); + memcpy(s, string, len); + s[len] = 0; + + /* Parse the number. */ + errno = 0; + num = strtol(s, NULL, 10); + if (errno) + return; + + *call_number = num; +} + +void dd_write_header(FILE *f, struct pipe_screen *screen, unsigned apitrace_call_number) { char cmd_line[4096]; @@ -282,6 +344,13 @@ dd_dump_shader(struct dd_draw_state *dstate, enum pipe_shader_type sh, FILE *f) } static void +dd_dump_flush(struct dd_draw_state *dstate, struct call_flush *info, FILE *f) +{ + fprintf(f, "%s:\n", __func__+8); + DUMP_M(hex, info, flags); +} + +static void dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE *f) { int sh, i; @@ -556,6 +625,9 @@ static void dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call) { switch (call->type) { + case CALL_FLUSH: + dd_dump_flush(state, &call->info.flush, f); + break; case CALL_DRAW_VBO: dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f); break; @@ -627,6 +699,8 @@ static void dd_unreference_copy_of_call(struct dd_call *dst) { switch (dst->type) { + case CALL_FLUSH: + break; case CALL_DRAW_VBO: pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, NULL); pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL); @@ -975,11 +1049,6 @@ dd_report_hang(struct dd_context *dctx) dd_write_header(f, dscreen->screen, record->draw_state.base.apitrace_call_number); dd_write_record(f, record); - if (!encountered_hang) { - dd_dump_driver_state(dctx, f, PIPE_DUMP_DEVICE_STATUS_REGISTERS); - dd_dump_dmesg(f); - } - fclose(f); } @@ -991,6 +1060,18 @@ dd_report_hang(struct dd_context *dctx) if (num_later) fprintf(stderr, "... and %u additional draws.\n", num_later); + char name[512]; + dd_get_debug_filename_and_mkdir(name, sizeof(name), false); + FILE *f = fopen(name, "w"); + if (!f) { + fprintf(stderr, "fopen failed\n"); + } else { + dd_write_header(f, dscreen->screen, 0); + dd_dump_driver_state(dctx, f, PIPE_DUMP_DEVICE_STATUS_REGISTERS); + dd_dump_dmesg(f); + fclose(f); + } + fprintf(stderr, "\nDone.\n"); dd_kill_process(); } @@ -1002,6 +1083,15 @@ dd_thread_main(void *input) struct dd_screen *dscreen = dd_screen(dctx->base.screen); struct pipe_screen *screen = dscreen->screen; + const char *process_name = util_get_process_name(); + if (process_name) { + char threadname[16]; + snprintf(threadname, sizeof(threadname), "%.*s:ddbg", + (int)MIN2(strlen(process_name), sizeof(threadname) - 6), + process_name); + u_thread_setname(threadname); + } + mtx_lock(&dctx->mutex); for (;;) { @@ -1083,13 +1173,23 @@ dd_create_record(struct dd_context *dctx) } static void -dd_context_flush(struct pipe_context *_pipe, - struct pipe_fence_handle **fence, unsigned flags) +dd_add_record(struct dd_context *dctx, struct dd_draw_record *record) { - struct dd_context *dctx = dd_context(_pipe); - struct pipe_context *pipe = dctx->pipe; + mtx_lock(&dctx->mutex); + if (unlikely(dctx->num_records > 10000)) { + dctx->api_stalled = true; + /* Since this is only a heuristic to prevent the API thread from getting + * too far ahead, we don't need a loop here. */ + cnd_wait(&dctx->cond, &dctx->mutex); + dctx->api_stalled = false; + } + + if (list_empty(&dctx->records)) + cnd_signal(&dctx->cond); - pipe->flush(pipe, fence, flags); + list_addtail(&record->list, &dctx->records); + dctx->num_records++; + mtx_unlock(&dctx->mutex); } static void @@ -1115,21 +1215,7 @@ dd_before_draw(struct dd_context *dctx, struct dd_draw_record *record) pipe->flush(pipe, NULL, 0); } - mtx_lock(&dctx->mutex); - if (unlikely(dctx->num_records > 10000)) { - dctx->api_stalled = true; - /* Since this is only a heuristic to prevent the API thread from getting - * too far ahead, we don't need a loop here. */ - cnd_wait(&dctx->cond, &dctx->mutex); - dctx->api_stalled = false; - } - - if (list_empty(&dctx->records)) - cnd_signal(&dctx->cond); - - list_addtail(&record->list, &dctx->records); - dctx->num_records++; - mtx_unlock(&dctx->mutex); + dd_add_record(dctx, record); } static void @@ -1180,6 +1266,33 @@ dd_after_draw(struct dd_context *dctx, struct dd_draw_record *record) } static void +dd_context_flush(struct pipe_context *_pipe, + struct pipe_fence_handle **fence, unsigned flags) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct dd_draw_record *record = dd_create_record(dctx); + + record->call.type = CALL_FLUSH; + record->call.info.flush.flags = flags; + + record->time_before = os_time_get_nano(); + + dd_add_record(dctx, record); + + pipe->flush(pipe, &record->bottom_of_pipe, flags); + if (fence) + screen->fence_reference(screen, fence, record->bottom_of_pipe); + + if (pipe->callback) { + pipe->callback(pipe, dd_after_draw_async, record, true); + } else { + dd_after_draw_async(record); + } +} + +static void dd_context_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) { @@ -1284,7 +1397,7 @@ dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info) dd_after_draw(dctx, record); } -static boolean +static bool dd_context_generate_mipmap(struct pipe_context *_pipe, struct pipe_resource *res, enum pipe_format format, @@ -1296,7 +1409,7 @@ dd_context_generate_mipmap(struct pipe_context *_pipe, struct dd_context *dctx = dd_context(_pipe); struct pipe_context *pipe = dctx->pipe; struct dd_draw_record *record = dd_create_record(dctx); - boolean result; + bool result; record->call.type = CALL_GENERATE_MIPMAP; record->call.info.generate_mipmap.res = NULL; @@ -1317,7 +1430,7 @@ dd_context_generate_mipmap(struct pipe_context *_pipe, static void dd_context_get_query_result_resource(struct pipe_context *_pipe, struct pipe_query *query, - boolean wait, + bool wait, enum pipe_query_value_type result_type, int index, struct pipe_resource *resource, |