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
|
static void
|
||||||
dd_before_draw(struct dd_context *dctx)
|
dd_before_draw(struct dd_context *dctx)
|
||||||
{
|
{
|
||||||
if (dd_screen(dctx->base.screen)->mode == DD_DETECT_HANGS &&
|
struct dd_screen *dscreen = dd_screen(dctx->base.screen);
|
||||||
!dd_screen(dctx->base.screen)->no_flush)
|
|
||||||
|
if (dscreen->mode == DD_DETECT_HANGS &&
|
||||||
|
!dscreen->no_flush &&
|
||||||
|
dctx->num_draw_calls >= dscreen->skip_count)
|
||||||
dd_flush_and_handle_hang(dctx, NULL, 0,
|
dd_flush_and_handle_hang(dctx, NULL, 0,
|
||||||
"GPU hang most likely caused by internal "
|
"GPU hang most likely caused by internal "
|
||||||
"driver commands");
|
"driver commands");
|
||||||
@@ -598,22 +601,28 @@ dd_before_draw(struct dd_context *dctx)
|
|||||||
static void
|
static void
|
||||||
dd_after_draw(struct dd_context *dctx, struct dd_call *call)
|
dd_after_draw(struct dd_context *dctx, struct dd_call *call)
|
||||||
{
|
{
|
||||||
switch (dd_screen(dctx->base.screen)->mode) {
|
struct dd_screen *dscreen = dd_screen(dctx->base.screen);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Terminate the process to prevent future hangs. */
|
if (dctx->num_draw_calls >= dscreen->skip_count) {
|
||||||
dd_kill_process();
|
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
|
static void
|
||||||
|
@@ -45,6 +45,7 @@ struct dd_screen
|
|||||||
unsigned timeout_ms;
|
unsigned timeout_ms;
|
||||||
enum dd_mode mode;
|
enum dd_mode mode;
|
||||||
bool no_flush;
|
bool no_flush;
|
||||||
|
unsigned skip_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dd_query
|
struct dd_query
|
||||||
@@ -110,6 +111,8 @@ struct dd_context
|
|||||||
struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS];
|
struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS];
|
||||||
struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
|
struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
|
||||||
float tess_default_levels[6];
|
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(" $HOME/"DD_DIR"/ when a hang is detected.");
|
||||||
puts(" If 'noflush' is specified, only detect hangs in pipe->flush.");
|
puts(" If 'noflush' is specified, only detect hangs in pipe->flush.");
|
||||||
puts("");
|
puts("");
|
||||||
|
puts(" GALLIUM_DDEBUG_SKIP=[count]");
|
||||||
|
puts(" Skip flush and hang detection for the given initial number of draw calls.");
|
||||||
|
puts("");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,5 +352,11 @@ ddebug_screen_create(struct pipe_screen *screen)
|
|||||||
assert(0);
|
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;
|
return &dscreen->base;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user