From f12af17337ad845b086c38ab5d2eb9ba995d7a0b Mon Sep 17 00:00:00 2001 From: Trigger Huang Date: Thu, 23 Apr 2026 13:18:25 +0800 Subject: [PATCH] renderer-gl: Enable graphics reset recovery if supported Request a robust EGL context when the platform supports it and expose the GL reset status hooks so Weston can detect GPU resets instead of being aborted by the driver. Signed-off-by: Trigger Huang --- libweston/renderer-gl/egl-glue.c | 1 + libweston/renderer-gl/gl-renderer-internal.h | 80 +++++++++++--------- libweston/renderer-gl/gl-renderer.c | 21 +++++ 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/libweston/renderer-gl/egl-glue.c b/libweston/renderer-gl/egl-glue.c index f26852923..decae10c2 100644 --- a/libweston/renderer-gl/egl-glue.c +++ b/libweston/renderer-gl/egl-glue.c @@ -73,6 +73,7 @@ static const struct gl_extension_table device_table[] = { static const struct gl_extension_table display_table[] = { EXT("EGL_ANDROID_native_fence_sync", EXTENSION_ANDROID_NATIVE_FENCE_SYNC), EXT("EGL_EXT_buffer_age", EXTENSION_EXT_BUFFER_AGE), + EXT("EGL_EXT_create_context_robustness", EXTENSION_EXT_CREATE_CONTEXT_ROBUSTNESS), EXT("EGL_EXT_image_dma_buf_import", EXTENSION_EXT_IMAGE_DMA_BUF_IMPORT), EXT("EGL_EXT_image_dma_buf_import_modifiers", EXTENSION_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS), EXT("EGL_EXT_pixel_format_float", EXTENSION_EXT_PIXEL_FORMAT_FLOAT), diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index a15574f05..9c179183e 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -106,21 +106,22 @@ enum egl_device_extension_flag { enum egl_display_extension_flag { EXTENSION_ANDROID_NATIVE_FENCE_SYNC = 1ull << 0, EXTENSION_EXT_BUFFER_AGE = 1ull << 1, - EXTENSION_EXT_IMAGE_DMA_BUF_IMPORT = 1ull << 2, - EXTENSION_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS = 1ull << 3, - EXTENSION_EXT_PIXEL_FORMAT_FLOAT = 1ull << 4, - EXTENSION_EXT_SWAP_BUFFERS_WITH_DAMAGE = 1ull << 5, - EXTENSION_IMG_CONTEXT_PRIORITY = 1ull << 6, - EXTENSION_KHR_FENCE_SYNC = 1ull << 7, - EXTENSION_KHR_GET_ALL_PROC_ADDRESSES = 1ull << 8, - EXTENSION_KHR_IMAGE_BASE = 1ull << 9, - EXTENSION_KHR_NO_CONFIG_CONTEXT = 1ull << 10, - EXTENSION_KHR_PARTIAL_UPDATE = 1ull << 11, - EXTENSION_KHR_SURFACELESS_CONTEXT = 1ull << 12, - EXTENSION_KHR_SWAP_BUFFERS_WITH_DAMAGE = 1ull << 13, - EXTENSION_KHR_WAIT_SYNC = 1ull << 14, - EXTENSION_MESA_CONFIGLESS_CONTEXT = 1ull << 15, - EXTENSION_WL_BIND_WAYLAND_DISPLAY = 1ull << 16, + EXTENSION_EXT_CREATE_CONTEXT_ROBUSTNESS = 1ull << 2, + EXTENSION_EXT_IMAGE_DMA_BUF_IMPORT = 1ull << 3, + EXTENSION_EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS = 1ull << 4, + EXTENSION_EXT_PIXEL_FORMAT_FLOAT = 1ull << 5, + EXTENSION_EXT_SWAP_BUFFERS_WITH_DAMAGE = 1ull << 6, + EXTENSION_IMG_CONTEXT_PRIORITY = 1ull << 7, + EXTENSION_KHR_FENCE_SYNC = 1ull << 8, + EXTENSION_KHR_GET_ALL_PROC_ADDRESSES = 1ull << 9, + EXTENSION_KHR_IMAGE_BASE = 1ull << 10, + EXTENSION_KHR_NO_CONFIG_CONTEXT = 1ull << 11, + EXTENSION_KHR_PARTIAL_UPDATE = 1ull << 12, + EXTENSION_KHR_SURFACELESS_CONTEXT = 1ull << 13, + EXTENSION_KHR_SWAP_BUFFERS_WITH_DAMAGE = 1ull << 14, + EXTENSION_KHR_WAIT_SYNC = 1ull << 15, + EXTENSION_MESA_CONFIGLESS_CONTEXT = 1ull << 16, + EXTENSION_WL_BIND_WAYLAND_DISPLAY = 1ull << 17, }; /* Keep in sync with gl-renderer.c. */ @@ -134,27 +135,28 @@ enum gl_extension_flag { EXTENSION_EXT_EGL_IMAGE_STORAGE = 1ull << 8, EXTENSION_EXT_MAP_BUFFER_RANGE = 1ull << 9, EXTENSION_EXT_READ_FORMAT_BGRA = 1ull << 10, - EXTENSION_EXT_SHADER_FB_FETCH_NC = 1ull << 11, - EXTENSION_EXT_TEXTURE_FORMAT_BGRA8888 = 1ull << 12, - EXTENSION_EXT_TEXTURE_NORM16 = 1ull << 13, - EXTENSION_EXT_TEXTURE_RG = 1ull << 14, - EXTENSION_EXT_TEXTURE_SRGB_R8 = 1ull << 15, - EXTENSION_EXT_TEXTURE_SRGB_RG8 = 1ull << 16, - EXTENSION_EXT_TEXTURE_STORAGE = 1ull << 17, - EXTENSION_EXT_TEXTURE_TYPE_2_10_10_10_REV = 1ull << 18, - EXTENSION_EXT_UNPACK_SUBIMAGE = 1ull << 19, - EXTENSION_NV_PACKED_FLOAT = 1ull << 20, - EXTENSION_NV_PIXEL_BUFFER_OBJECT = 1ull << 21, - EXTENSION_OES_EGL_IMAGE = 1ull << 22, - EXTENSION_OES_EGL_IMAGE_EXTERNAL = 1ull << 23, - EXTENSION_OES_MAPBUFFER = 1ull << 24, - EXTENSION_OES_REQUIRED_INTERNALFORMAT = 1ull << 25, - EXTENSION_OES_RGB8_RGBA8 = 1ull << 26, - EXTENSION_OES_TEXTURE_3D = 1ull << 27, - EXTENSION_OES_TEXTURE_FLOAT = 1ull << 28, - EXTENSION_OES_TEXTURE_FLOAT_LINEAR = 1ull << 29, - EXTENSION_OES_TEXTURE_HALF_FLOAT = 1ull << 30, - EXTENSION_QCOM_RENDER_SRGB_R8_RG8 = 1ull << 31, + EXTENSION_EXT_ROBUSTNESS = 1ull << 11, + EXTENSION_EXT_SHADER_FB_FETCH_NC = 1ull << 12, + EXTENSION_EXT_TEXTURE_FORMAT_BGRA8888 = 1ull << 13, + EXTENSION_EXT_TEXTURE_NORM16 = 1ull << 14, + EXTENSION_EXT_TEXTURE_RG = 1ull << 15, + EXTENSION_EXT_TEXTURE_SRGB_R8 = 1ull << 16, + EXTENSION_EXT_TEXTURE_SRGB_RG8 = 1ull << 17, + EXTENSION_EXT_TEXTURE_STORAGE = 1ull << 18, + EXTENSION_EXT_TEXTURE_TYPE_2_10_10_10_REV = 1ull << 19, + EXTENSION_EXT_UNPACK_SUBIMAGE = 1ull << 20, + EXTENSION_NV_PACKED_FLOAT = 1ull << 21, + EXTENSION_NV_PIXEL_BUFFER_OBJECT = 1ull << 22, + EXTENSION_OES_EGL_IMAGE = 1ull << 23, + EXTENSION_OES_EGL_IMAGE_EXTERNAL = 1ull << 24, + EXTENSION_OES_MAPBUFFER = 1ull << 25, + EXTENSION_OES_REQUIRED_INTERNALFORMAT = 1ull << 26, + EXTENSION_OES_RGB8_RGBA8 = 1ull << 27, + EXTENSION_OES_TEXTURE_3D = 1ull << 28, + EXTENSION_OES_TEXTURE_FLOAT = 1ull << 29, + EXTENSION_OES_TEXTURE_FLOAT_LINEAR = 1ull << 30, + EXTENSION_OES_TEXTURE_HALF_FLOAT = 1ull << 31, + EXTENSION_QCOM_RENDER_SRGB_R8_RG8 = 1ull << 32, }; enum gl_feature_flag { @@ -208,6 +210,9 @@ enum gl_feature_flag { /* GL renderer can do blending explicitly in the fragment shader, * using framebuffer fetch and store curves. */ FEATURE_SHADER_BLENDING = 1ull << 10, + + /* The GL renderer can recover from a GPU reset. */ + FEATURE_GRAPHICS_RESET_RECOVERY = 1ull << 11, }; /* Keep the following in sync with vertex.glsl. */ @@ -521,6 +526,9 @@ struct gl_renderer { PFNGLTEXSTORAGE2DEXTPROC tex_storage_2d; PFNGLTEXSTORAGE3DEXTPROC tex_storage_3d; + /* GL_EXT_robustness */ + PFNGLGETGRAPHICSRESETSTATUSEXTPROC get_graphics_reset_status; + /* GL_EXT_shader_framebuffer_fetch_non_coherent */ PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC framebuffer_fetch_barrier; diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index cfc06a15b..b9fec8941 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -342,6 +342,7 @@ static const struct gl_extension_table extension_table[] = { EXT("GL_EXT_EGL_image_storage", EXTENSION_EXT_EGL_IMAGE_STORAGE), EXT("GL_EXT_map_buffer_range", EXTENSION_EXT_MAP_BUFFER_RANGE), EXT("GL_EXT_read_format_bgra", EXTENSION_EXT_READ_FORMAT_BGRA), + EXT("GL_EXT_robustness", EXTENSION_EXT_ROBUSTNESS), EXT("GL_EXT_shader_framebuffer_fetch_non_coherent", EXTENSION_EXT_SHADER_FB_FETCH_NC), EXT("GL_EXT_texture_format_BGRA8888", EXTENSION_EXT_TEXTURE_FORMAT_BGRA8888), EXT("GL_EXT_texture_norm16", EXTENSION_EXT_TEXTURE_NORM16), @@ -5464,6 +5465,12 @@ gl_renderer_setup(struct weston_compositor *ec) context_attribs[nattr++] = EGL_CONTEXT_PRIORITY_HIGH_IMG; } + if (egl_display_has(gr, EXTENSION_EXT_CREATE_CONTEXT_ROBUSTNESS)) { + context_attribs[nattr++] = + EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR; + context_attribs[nattr++] = EGL_LOSE_CONTEXT_ON_RESET_KHR; + } + assert(nattr < ARRAY_LENGTH(context_attribs)); context_attribs[nattr] = EGL_NONE; @@ -5525,6 +5532,18 @@ gl_renderer_setup(struct weston_compositor *ec) return -1; } + if (gl_extensions_has(gr, EXTENSION_EXT_ROBUSTNESS)) { + GET_PROC_ADDRESS(gr->get_graphics_reset_status, + "glGetGraphicsResetStatusEXT"); + if (egl_display_has(gr, EXTENSION_EXT_CREATE_CONTEXT_ROBUSTNESS)) { + GLint strategy = 0; + + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_EXT, &strategy); + if (strategy == GL_LOSE_CONTEXT_ON_RESET_EXT) + gr->features |= FEATURE_GRAPHICS_RESET_RECOVERY; + } + } + if (gl_extensions_has(gr, EXTENSION_OES_EGL_IMAGE)) { GET_PROC_ADDRESS(gr->image_target_texture_2d, "glEGLImageTargetTexture2DOES"); @@ -5705,6 +5724,8 @@ gl_renderer_setup(struct weston_compositor *ec) gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT))); weston_log_continue(STAMP_SPACE "In-shader blending: %s\n", yesno(gl_features_has(gr, FEATURE_SHADER_BLENDING))); + weston_log_continue(STAMP_SPACE "Graphics reset recovery: %s\n", + yesno(gl_features_has(gr, FEATURE_GRAPHICS_RESET_RECOVERY))); return 0; }