gallium/ddebug: add GALLIUM_DDEBUG_SKIP option

When we know that hangs occur only very late in a reproducible run (e.g.
apitrace), we can save a lot of debugging time by skipping the flush and hang
detection for earlier draw calls.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Nicolai Hähnle
2015-12-08 06:49:12 -05:00
parent af7ba989fb
commit b86d5ccae2
3 changed files with 36 additions and 15 deletions

View File

@@ -588,8 +588,11 @@ dd_context_flush(struct pipe_context *_pipe,
static void
dd_before_draw(struct dd_context *dctx)
{
if (dd_screen(dctx->base.screen)->mode == DD_DETECT_HANGS &&
!dd_screen(dctx->base.screen)->no_flush)
struct dd_screen *dscreen = dd_screen(dctx->base.screen);
if (dscreen->mode == DD_DETECT_HANGS &&
!dscreen->no_flush &&
dctx->num_draw_calls >= dscreen->skip_count)
dd_flush_and_handle_hang(dctx, NULL, 0,
"GPU hang most likely caused by internal "
"driver commands");
@@ -598,22 +601,28 @@ dd_before_draw(struct dd_context *dctx)
static void
dd_after_draw(struct dd_context *dctx, struct dd_call *call)
{
switch (dd_screen(dctx->base.screen)->mode) {
case DD_DETECT_HANGS:
if (!dd_screen(dctx->base.screen)->no_flush &&
dd_flush_and_check_hang(dctx, NULL, 0)) {
dd_dump_call(dctx, call, PIPE_DEBUG_DEVICE_IS_HUNG);
struct dd_screen *dscreen = dd_screen(dctx->base.screen);
/* Terminate the process to prevent future hangs. */
dd_kill_process();
if (dctx->num_draw_calls >= dscreen->skip_count) {
switch (dscreen->mode) {
case DD_DETECT_HANGS:
if (!dscreen->no_flush &&
dd_flush_and_check_hang(dctx, NULL, 0)) {
dd_dump_call(dctx, call, PIPE_DEBUG_DEVICE_IS_HUNG);
/* Terminate the process to prevent future hangs. */
dd_kill_process();
}
break;
case DD_DUMP_ALL_CALLS:
dd_dump_call(dctx, call, 0);
break;
default:
assert(0);
}
break;
case DD_DUMP_ALL_CALLS:
dd_dump_call(dctx, call, 0);
break;
default:
assert(0);
}
++dctx->num_draw_calls;
}
static void

View File

@@ -45,6 +45,7 @@ struct dd_screen
unsigned timeout_ms;
enum dd_mode mode;
bool no_flush;
unsigned skip_count;
};
struct dd_query
@@ -110,6 +111,8 @@ struct dd_context
struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS];
struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
float tess_default_levels[6];
unsigned num_draw_calls;
};

View File

@@ -290,6 +290,9 @@ ddebug_screen_create(struct pipe_screen *screen)
puts(" $HOME/"DD_DIR"/ when a hang is detected.");
puts(" If 'noflush' is specified, only detect hangs in pipe->flush.");
puts("");
puts(" GALLIUM_DDEBUG_SKIP=[count]");
puts(" Skip flush and hang detection for the given initial number of draw calls.");
puts("");
exit(0);
}
@@ -349,5 +352,11 @@ ddebug_screen_create(struct pipe_screen *screen)
assert(0);
}
dscreen->skip_count = debug_get_num_option("GALLIUM_DDEBUG_SKIP", 0);
if (dscreen->skip_count > 0) {
fprintf(stderr, "Gallium debugger skipping the first %u draw calls.\n",
dscreen->skip_count);
}
return &dscreen->base;
}