mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-07 04:58:16 +02:00
clients/simple-egl: Support robust context
This was added for testing GPU recovery of the GL renderer. Detailed steps can be found at the following link: https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1662#note_2907234 Signed-off-by: Trigger Huang <Trigger.Huang@amd.com>
This commit is contained in:
parent
1668434d81
commit
d79f32810d
1 changed files with 92 additions and 6 deletions
|
|
@ -39,6 +39,8 @@
|
|||
#include <wayland-cursor.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <GLES3/gl32.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
|
|
@ -86,6 +88,7 @@ struct display {
|
|||
|
||||
PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;
|
||||
PFNEGLQUERYSUPPORTEDCOMPRESSIONRATESEXTPROC query_compression_rates;
|
||||
PFNGLGETGRAPHICSRESETSTATUSEXTPROC get_graphics_reset_status;
|
||||
};
|
||||
|
||||
struct geometry {
|
||||
|
|
@ -106,6 +109,9 @@ struct window {
|
|||
GLuint rotation_uniform;
|
||||
GLuint pos;
|
||||
GLuint col;
|
||||
GLuint frag;
|
||||
GLuint vert;
|
||||
GLuint program;
|
||||
} gl;
|
||||
|
||||
uint32_t frames;
|
||||
|
|
@ -200,7 +206,9 @@ init_egl(struct display *display, struct window *window)
|
|||
};
|
||||
|
||||
static const EGLint context_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||
EGL_LOSE_CONTEXT_ON_RESET_KHR,
|
||||
EGL_NONE
|
||||
};
|
||||
const char *extensions;
|
||||
|
|
@ -310,6 +318,18 @@ init_egl(struct display *display, struct window *window)
|
|||
eglGetProcAddress("eglQuerySupportedCompressionRatesEXT");
|
||||
printf("has EGL_EXT_surface_compression\n");
|
||||
}
|
||||
|
||||
if (extensions &&
|
||||
weston_check_egl_extension(extensions,
|
||||
"EGL_EXT_create_context_robustness")) {
|
||||
display->get_graphics_reset_status =
|
||||
(PFNGLGETGRAPHICSRESETSTATUSEXTPROC)
|
||||
eglGetProcAddress("glGetGraphicsResetStatusEXT");
|
||||
if (display->get_graphics_reset_status)
|
||||
printf("glGetGraphicsResetStatusEXT is valid!\n");
|
||||
else
|
||||
printf("glGetGraphicsResetStatusEXT is invalid!\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -319,6 +339,21 @@ fini_egl(struct display *display)
|
|||
eglReleaseThread();
|
||||
}
|
||||
|
||||
static void
|
||||
fini_gl(struct window *window)
|
||||
{
|
||||
glDeleteShader(window->gl.frag);
|
||||
glDeleteShader(window->gl.vert);
|
||||
glDeleteProgram(window->gl.program);
|
||||
|
||||
eglMakeCurrent(window->display->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
|
||||
weston_platform_destroy_egl_surface(window->display->egl.dpy,
|
||||
window->egl_surface);
|
||||
wl_egl_window_destroy(window->native);
|
||||
}
|
||||
|
||||
static GLuint
|
||||
create_shader(struct window *window, const char *source, GLenum shader_type)
|
||||
{
|
||||
|
|
@ -477,6 +512,7 @@ init_gl(struct window *window)
|
|||
EGLBoolean ret;
|
||||
EGLint attribs[5] = { EGL_NONE };
|
||||
uint32_t num_attribs = 0;
|
||||
GLint strategy = 0;
|
||||
|
||||
if (window->needs_buffer_geometry_update)
|
||||
update_buffer_geometry(window);
|
||||
|
|
@ -561,12 +597,21 @@ init_gl(struct window *window)
|
|||
|
||||
window->gl.pos = 0;
|
||||
window->gl.col = 1;
|
||||
window->gl.frag = frag;
|
||||
window->gl.vert = vert;
|
||||
window->gl.program = program;
|
||||
|
||||
glBindAttribLocation(program, window->gl.pos, "pos");
|
||||
glBindAttribLocation(program, window->gl.col, "color");
|
||||
|
||||
window->gl.rotation_uniform =
|
||||
glGetUniformLocation(program, "rotation");
|
||||
|
||||
glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_EXT, &strategy);
|
||||
if (strategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
|
||||
printf("Create GL robust context successfully!\n");
|
||||
else
|
||||
printf("Failed to create GL robust context successfully!\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -902,7 +947,37 @@ destroy_surface(struct window *window)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
static int
|
||||
check_gpu_reset_status(struct display *display)
|
||||
{
|
||||
bool has_reset = false;
|
||||
int i;
|
||||
|
||||
if (!display->get_graphics_reset_status)
|
||||
return 0;
|
||||
|
||||
/* Assume GPU reset should be finished within 5s. */
|
||||
for (i = 0; i < 100000; i++) {
|
||||
unsigned status;
|
||||
|
||||
status = display->get_graphics_reset_status();
|
||||
if (status == GL_NO_ERROR)
|
||||
break;
|
||||
|
||||
has_reset = true;
|
||||
usleep(50);
|
||||
}
|
||||
|
||||
if (!has_reset)
|
||||
return 0;
|
||||
|
||||
/* If GPU reset has not completed, nothing we can do. */
|
||||
assert(i < 100000);
|
||||
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static int
|
||||
redraw(struct window *window)
|
||||
{
|
||||
struct display *display = window->display;
|
||||
|
|
@ -995,6 +1070,8 @@ redraw(struct window *window)
|
|||
draw_triangle(window, buffer_age);
|
||||
|
||||
window->frames++;
|
||||
|
||||
return check_gpu_reset_status(display);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1469,15 +1546,12 @@ main(int argc, char **argv)
|
|||
goto out_no_xdg_shell;
|
||||
}
|
||||
|
||||
init_egl(&display, &window);
|
||||
create_surface(&window);
|
||||
|
||||
/* we already have wait_for_configure set after create_surface() */
|
||||
while (running && ret != -1 && window.wait_for_configure)
|
||||
ret = wl_display_dispatch(display.display);
|
||||
|
||||
init_gl(&window);
|
||||
|
||||
display.cursor_surface =
|
||||
wl_compositor_create_surface(display.compositor);
|
||||
|
||||
|
|
@ -1486,13 +1560,25 @@ main(int argc, char **argv)
|
|||
sigint.sa_flags = SA_RESETHAND;
|
||||
sigaction(SIGINT, &sigint, NULL);
|
||||
|
||||
init_gl_egl:
|
||||
init_egl(&display, &window);
|
||||
init_gl(&window);
|
||||
|
||||
while (running && ret != -1) {
|
||||
int draw;
|
||||
|
||||
ret = wl_display_dispatch_pending(display.display);
|
||||
redraw(&window);
|
||||
draw = redraw(&window);
|
||||
if (draw) {
|
||||
fini_gl(&window);
|
||||
fini_egl(&display);
|
||||
goto init_gl_egl;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "simple-egl exiting\n");
|
||||
|
||||
fini_gl(&window);
|
||||
destroy_surface(&window);
|
||||
fini_egl(&display);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue