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 <Trigger.Huang@amd.com>
This commit is contained in:
Trigger Huang 2026-04-23 13:18:25 +08:00
parent e0c5b8a26b
commit f12af17337
3 changed files with 66 additions and 36 deletions

View file

@ -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),

View file

@ -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;

View file

@ -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;
}