gallium/radeon: implement set_device_reset_callback

Check for device reset on flush. It would be nicer if the kernel just
reported this as an error on the submit ioctl (and similarly for fences),
but this will do for now.

Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Nicolai Hähnle 2016-09-30 15:21:00 +02:00
parent a1fa8b731f
commit b5cd7dfe3e
4 changed files with 40 additions and 0 deletions

View File

@ -258,6 +258,9 @@ void r600_context_gfx_flush(void *context, unsigned flags,
if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size))
return;
if (r600_check_device_reset(&ctx->b))
return;
r600_preflush_suspend_features(&ctx->b);
/* flush the framebuffer cache */

View File

@ -484,6 +484,36 @@ static void r600_set_debug_callback(struct pipe_context *ctx,
memset(&rctx->debug, 0, sizeof(rctx->debug));
}
static void r600_set_device_reset_callback(struct pipe_context *ctx,
const struct pipe_device_reset_callback *cb)
{
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
if (cb)
rctx->device_reset_callback = *cb;
else
memset(&rctx->device_reset_callback, 0,
sizeof(rctx->device_reset_callback));
}
bool r600_check_device_reset(struct r600_common_context *rctx)
{
enum pipe_reset_status status;
if (!rctx->device_reset_callback.reset)
return false;
if (!rctx->b.get_device_reset_status)
return false;
status = rctx->b.get_device_reset_status(&rctx->b);
if (status == PIPE_NO_RESET)
return false;
rctx->device_reset_callback.reset(rctx->device_reset_callback.data, status);
return true;
}
bool r600_common_context_init(struct r600_common_context *rctx,
struct r600_common_screen *rscreen,
unsigned context_flags)
@ -527,6 +557,8 @@ bool r600_common_context_init(struct r600_common_context *rctx,
RADEON_GPU_RESET_COUNTER);
}
rctx->b.set_device_reset_callback = r600_set_device_reset_callback;
r600_init_context_texture_functions(rctx);
r600_init_viewport_functions(rctx);
r600_streamout_init(rctx);

View File

@ -619,6 +619,7 @@ struct r600_common_context {
} dcc_stats[5];
struct pipe_debug_callback debug;
struct pipe_device_reset_callback device_reset_callback;
void *query_result_shader;
@ -733,6 +734,7 @@ 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);
bool r600_check_device_reset(struct r600_common_context *rctx);
/* r600_gpu_load.c */
void r600_gpu_load_kill_thread(struct r600_common_screen *rscreen);

View File

@ -103,6 +103,9 @@ void si_context_gfx_flush(void *context, unsigned flags,
if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size))
return;
if (r600_check_device_reset(&ctx->b))
return;
ctx->gfx_flush_in_progress = true;
r600_preflush_suspend_features(&ctx->b);