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:
@@ -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
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user