diff options
author | Simon Ser <contact@emersion.fr> | 2022-01-12 18:56:08 +0100 |
---|---|---|
committer | Simon Zeni <simon@bl4ckb0ne.ca> | 2022-11-15 15:50:19 +0000 |
commit | 261d6998fb7461fcdf6cf66a57863b8ed505a67c (patch) | |
tree | 77bd847376c8e48abf1489fb3228747418fa804f | |
parent | 31ea61b390a3295248458ab7e8388848fb6810d0 (diff) |
render/gles2: query glGetGraphicsResetStatusKHR
Call glGetGraphicsResetStatusKHR in wlr_renderer_begin to figure
out when a GPU reset occurs. Destroy the renderer when this
happens (the OpenGL context is defunct).
-rw-r--r-- | include/render/gles2.h | 1 | ||||
-rw-r--r-- | render/gles2/renderer.c | 37 |
2 files changed, 38 insertions, 0 deletions
diff --git a/include/render/gles2.h b/include/render/gles2.h index 6631d34c..ff39206c 100644 --- a/include/render/gles2.h +++ b/include/render/gles2.h @@ -57,6 +57,7 @@ struct wlr_gles2_renderer { PFNGLPOPDEBUGGROUPKHRPROC glPopDebugGroupKHR; PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR; PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES; + PFNGLGETGRAPHICSRESETSTATUSKHRPROC glGetGraphicsResetStatusKHR; } procs; struct { diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index ee4f60e8..47c58b19 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -198,6 +198,19 @@ static bool gles2_bind_buffer(struct wlr_renderer *wlr_renderer, return true; } +static const char *reset_status_str(GLenum status) { + switch (status) { + case GL_GUILTY_CONTEXT_RESET_KHR: + return "guilty"; + case GL_INNOCENT_CONTEXT_RESET_KHR: + return "innocent"; + case GL_UNKNOWN_CONTEXT_RESET_KHR: + return "unknown"; + default: + return "<invalid>"; + } +} + static bool gles2_begin(struct wlr_renderer *wlr_renderer, uint32_t width, uint32_t height) { struct wlr_gles2_renderer *renderer = @@ -205,6 +218,15 @@ static bool gles2_begin(struct wlr_renderer *wlr_renderer, uint32_t width, push_gles2_debug(renderer); + if (renderer->procs.glGetGraphicsResetStatusKHR) { + GLenum status = renderer->procs.glGetGraphicsResetStatusKHR(); + if (status != GL_NO_ERROR) { + wlr_log(WLR_ERROR, "GPU reset (%s)", reset_status_str(status)); + wl_signal_emit_mutable(&wlr_renderer->events.lost, NULL); + return false; + } + } + glViewport(0, 0, width, height); renderer->viewport_width = width; renderer->viewport_height = height; @@ -771,6 +793,21 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { "glEGLImageTargetRenderbufferStorageOES"); } + if (check_gl_ext(exts_str, "GL_KHR_robustness")) { + GLint notif_strategy = 0; + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_KHR, ¬if_strategy); + switch (notif_strategy) { + case GL_LOSE_CONTEXT_ON_RESET_KHR: + wlr_log(WLR_DEBUG, "GPU reset notifications are enabled"); + load_gl_proc(&renderer->procs.glGetGraphicsResetStatusKHR, + "glGetGraphicsResetStatusKHR"); + break; + case GL_NO_RESET_NOTIFICATION_KHR: + wlr_log(WLR_DEBUG, "GPU reset notifications are disabled"); + break; + } + } + if (renderer->exts.KHR_debug) { glEnable(GL_DEBUG_OUTPUT_KHR); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR); |