{
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
- return rctx->ws->ctx_query_reset_status(rctx->ctx, false, NULL);
+ return rctx->ws->ctx_query_reset_status(rctx->ctx, false, NULL, NULL);
}
static void r600_set_debug_callback(struct pipe_context *ctx,
* while si_get_reset_status can't. */
if (!(ctx->context_flags & SI_CONTEXT_FLAG_AUX) &&
ctx->device_reset_callback.reset) {
- enum pipe_reset_status status = ctx->ws->ctx_query_reset_status(ctx->ctx, true, NULL);
+ enum pipe_reset_status status = ctx->ws->ctx_query_reset_status(ctx->ctx, true, NULL, NULL);
if (status != PIPE_NO_RESET)
ctx->device_reset_callback.reset(ctx->device_reset_callback.data, status);
}
if (sctx->context_flags & SI_CONTEXT_FLAG_AUX)
return PIPE_NO_RESET;
- bool needs_reset;
- enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(sctx->ctx, false, &needs_reset);
+ bool needs_reset, reset_completed;
+ enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(sctx->ctx, false,
+ &needs_reset, &reset_completed);
- if (status != PIPE_NO_RESET && needs_reset && !(sctx->context_flags & SI_CONTEXT_FLAG_AUX)) {
- /* Call the gallium frontend to set a no-op API dispatch. */
- if (sctx->device_reset_callback.reset) {
- sctx->device_reset_callback.reset(sctx->device_reset_callback.data, status);
+ if (status != PIPE_NO_RESET) {
+ if (sctx->has_reset_been_notified && reset_completed)
+ return PIPE_NO_RESET;
+
+ sctx->has_reset_been_notified = true;
+
+ if (!(sctx->context_flags & SI_CONTEXT_FLAG_AUX)) {
+ /* Call the gallium frontend to set a no-op API dispatch. */
+ if (needs_reset && sctx->device_reset_callback.reset)
+ sctx->device_reset_callback.reset(sctx->device_reset_callback.data, status);
}
}
return status;
struct si_context *saux = si_get_aux_context(sscreen);
enum pipe_reset_status status = sctx->ws->ctx_query_reset_status(
- saux->ctx, true, NULL);
+ saux->ctx, true, NULL, NULL);
if (status != PIPE_NO_RESET) {
/* We lost the aux_context, create a new one */
struct u_log_context *aux_log = (saux)->log;
bool dpbb_force_off_profile_ps;
bool vs_writes_viewport_index;
bool vs_disables_clipping_viewport;
+ bool has_reset_been_notified;
/* Precomputed IA_MULTI_VGT_PARAM */
union si_vgt_param_key ia_multi_vgt_param_key;
*/
enum pipe_reset_status (*ctx_query_reset_status)(struct radeon_winsys_ctx *ctx,
bool full_reset_only,
- bool *needs_reset);
+ bool *needs_reset, bool *reset_completed);
/**
* Create a command stream.
static enum pipe_reset_status
amdgpu_ctx_query_reset_status(struct radeon_winsys_ctx *rwctx, bool full_reset_only,
- bool *needs_reset)
+ bool *needs_reset, bool *reset_completed)
{
struct amdgpu_ctx *ctx = (struct amdgpu_ctx*)rwctx;
int r;
if (needs_reset)
*needs_reset = false;
+ if (reset_completed)
+ *reset_completed = false;
/* Return a failure due to a GPU hang. */
if (ctx->ws->info.drm_minor >= 24) {
}
if (flags & AMDGPU_CTX_QUERY2_FLAGS_RESET) {
+ if (reset_completed) {
+ /* The ARB_robustness spec says:
+ *
+ * If a reset status other than NO_ERROR is returned and subsequent
+ * calls return NO_ERROR, the context reset was encountered and
+ * completed. If a reset status is repeatedly returned, the context may
+ * be in the process of resetting.
+ *
+ */
+ if (!(flags & AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS))
+ *reset_completed = true;
+ }
if (needs_reset)
*needs_reset = flags & AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
if (flags & AMDGPU_CTX_QUERY2_FLAGS_GUILTY)
static enum pipe_reset_status
radeon_drm_ctx_query_reset_status(struct radeon_winsys_ctx *rctx, bool full_reset_only,
- bool *needs_reset)
+ bool *needs_reset, bool *reset_completed)
{
struct radeon_ctx *ctx = (struct radeon_ctx*)rctx;
if (ctx->gpu_reset_counter == latest) {
if (needs_reset)
*needs_reset = false;
+ if (reset_completed)
+ *reset_completed = false;
return PIPE_NO_RESET;
}
if (needs_reset)
*needs_reset = true;
+ if (reset_completed)
+ *reset_completed = true;
ctx->gpu_reset_counter = latest;
return PIPE_UNKNOWN_CONTEXT_RESET;