From: Nicolai Hähnle Date: Fri, 30 Sep 2016 13:21:00 +0000 (+0200) Subject: gallium/radeon: implement set_device_reset_callback X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b5cd7dfe3e9a04bf6edd5d100f7c74b8fcb5c277;p=mesa.git 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 Reviewed-by: Marek Olšák --- diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index dc5ad7537b9..bc6217ad223 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -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 */ diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 3a5a854a9aa..6f71ef60eca 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -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); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 4ee7daaa38c..54991e87f4c 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -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); diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index 3373fb8386e..7c11bafcb29 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -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);