mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-25 22:25:58 +01:00
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).
This commit is contained in:
parent
31ea61b390
commit
261d6998fb
2 changed files with 38 additions and 0 deletions
|
@ -57,6 +57,7 @@ struct wlr_gles2_renderer {
|
||||||
PFNGLPOPDEBUGGROUPKHRPROC glPopDebugGroupKHR;
|
PFNGLPOPDEBUGGROUPKHRPROC glPopDebugGroupKHR;
|
||||||
PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
|
PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
|
||||||
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES;
|
PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES;
|
||||||
|
PFNGLGETGRAPHICSRESETSTATUSKHRPROC glGetGraphicsResetStatusKHR;
|
||||||
} procs;
|
} procs;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -198,6 +198,19 @@ static bool gles2_bind_buffer(struct wlr_renderer *wlr_renderer,
|
||||||
return true;
|
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,
|
static bool gles2_begin(struct wlr_renderer *wlr_renderer, uint32_t width,
|
||||||
uint32_t height) {
|
uint32_t height) {
|
||||||
struct wlr_gles2_renderer *renderer =
|
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);
|
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);
|
glViewport(0, 0, width, height);
|
||||||
renderer->viewport_width = width;
|
renderer->viewport_width = width;
|
||||||
renderer->viewport_height = height;
|
renderer->viewport_height = height;
|
||||||
|
@ -771,6 +793,21 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
"glEGLImageTargetRenderbufferStorageOES");
|
"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) {
|
if (renderer->exts.KHR_debug) {
|
||||||
glEnable(GL_DEBUG_OUTPUT_KHR);
|
glEnable(GL_DEBUG_OUTPUT_KHR);
|
||||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
||||||
|
|
Loading…
Reference in a new issue