gallium/radeon: implement set_device_reset_callback
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Fri, 30 Sep 2016 13:21:00 +0000 (15:21 +0200)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Wed, 5 Oct 2016 13:51:56 +0000 (15:51 +0200)
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>
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/r600_pipe_common.h
src/gallium/drivers/radeonsi/si_hw_context.c

index dc5ad7537b999fe87e1c37eeb7eba2cd7bdf35da..bc6217ad223574e1735ad5543490c0511cacd4b1 100644 (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 */
index 3a5a854a9aafa137b0e4665a9a4199ee6ccb7202..6f71ef60ecab54103f498f565bbe4b4a8363dbde 100644 (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);
index 4ee7daaa38c5696f2fdcce572fbda42a2ce0736e..54991e87f4cf01f315199f1ca79b5871ebbdf0f0 100644 (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);
index 3373fb8386e7bd63208288c68259d4b81623c93d..7c11bafcb29a2e7b251b2b21f261ce7ab040a6c0 100644 (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);