Submitted by: Zeckma Date: 2026-06-13 Initial Package Version: 1.7.0 Origin: Upstream, https://gitlab.freedesktop.org/glvnd/libglvnd/-/merge_requests/298 Upstream Status: Not merged yet Description: Exposes all of the device EGL extensions if just one is advertised. Necessary for drivers that don't expose all three, but rather one or two. Required for Mesa-less. diff --git a/src/EGL/libegl.c b/src/EGL/libegl.c index 2a62f092ca2723cc42a38408423e6be789207391..311f3a071d4e9bea40770cfd9c9b78874c6d5b5a 100644 --- a/src/EGL/libegl.c +++ b/src/EGL/libegl.c @@ -59,9 +59,6 @@ */ static const char *SUPPORTED_CLIENT_EXTENSIONS = "EGL_EXT_platform_base" - " EGL_EXT_device_base" - " EGL_EXT_device_enumeration" - " EGL_EXT_device_query" " EGL_EXT_platform_device" // FIXME: Include the other platform extensions here to make testing @@ -872,6 +869,8 @@ static char *GetClientExtensionString(void) struct glvnd_list *vendorList = __eglLoadVendors(); __EGLvendorInfo *vendor; char *result = NULL; + EGLBoolean supportsDeviceEnum = EGL_FALSE; + EGLBoolean supportsDeviceQuery = EGL_FALSE; // First, find the union of all available vendor libraries. Start with an // empty string, then merge the extension string from every vendor library. @@ -890,6 +889,9 @@ static char *GetClientExtensionString(void) return NULL; } } + + supportsDeviceEnum = supportsDeviceEnum || vendor->supportsDeviceEnum; + supportsDeviceQuery = supportsDeviceQuery || vendor->supportsDeviceQuery; } // Next, take the intersection of the client extensions from the vendors @@ -902,6 +904,26 @@ static char *GetClientExtensionString(void) return NULL; } + // Add the appropriate set of device extensions. + if (supportsDeviceEnum) { + result = UnionExtensionStrings(result, "EGL_EXT_device_enumeration"); + if (result == NULL) { + return NULL; + } + } + if (supportsDeviceQuery) { + result = UnionExtensionStrings(result, "EGL_EXT_device_query"); + if (result == NULL) { + return NULL; + } + } + if (supportsDeviceEnum && supportsDeviceQuery) { + result = UnionExtensionStrings(result, "EGL_EXT_device_base"); + if (result == NULL) { + return NULL; + } + } + glvnd_list_for_each_entry(vendor, vendorList, entry) { const char *vendorString = NULL; if (vendor->eglvc.getVendorString != NULL) { @@ -963,7 +985,7 @@ static EGLBoolean QueryVendorDevices(__EGLvendorInfo *vendor, EGLint max_devices EGLint vendorCount = 0; EGLint i; - if (!vendor->supportsDevice) { + if (!vendor->supportsDeviceEnum) { return EGL_TRUE; } diff --git a/src/EGL/libeglvendor.c b/src/EGL/libeglvendor.c index acece59708ab03b9623c5b0ecd39839b6a43ced5..3cfb7065f74fe7535c295aa0e506176904f4c3fe 100644 --- a/src/EGL/libeglvendor.c +++ b/src/EGL/libeglvendor.c @@ -385,6 +385,7 @@ static void CheckVendorExtensionString(__EGLvendorInfo *vendor, const char *str) { static const char NAME_DEVICE_BASE[] = "EGL_EXT_device_base"; static const char NAME_DEVICE_ENUM[] = "EGL_EXT_device_enumeration"; + static const char NAME_DEVICE_QUERY[] = "EGL_EXT_device_query"; static const char NAME_PLATFORM_DEVICE[] = "EGL_EXT_platform_device"; static const char NAME_MESA_PLATFORM_GBM[] = "EGL_MESA_platform_gbm"; static const char NAME_KHR_PLATFORM_GBM[] = "EGL_KHR_platform_gbm"; @@ -397,10 +398,24 @@ static void CheckVendorExtensionString(__EGLvendorInfo *vendor, const char *str) return; } - if (!vendor->supportsDevice) { - if (IsTokenInString(str, NAME_DEVICE_BASE, sizeof(NAME_DEVICE_BASE) - 1, " ") - || IsTokenInString(str, NAME_DEVICE_ENUM, sizeof(NAME_DEVICE_ENUM) - 1, " ")) { - vendor->supportsDevice = EGL_TRUE; + if (!vendor->supportsDeviceEnum || !vendor->supportsDeviceQuery) { + /* + * EGL_EXT_device_base is equivalent to supporting both + * EGL_EXT_device_enumeration and EGL_EXT_device_query. + * + * Keep track of both so that we know which to include when we + * construct the client extension string. + */ + if (IsTokenInString(str, NAME_DEVICE_BASE, sizeof(NAME_DEVICE_BASE) - 1, " ")) { + vendor->supportsDeviceEnum = EGL_TRUE; + vendor->supportsDeviceQuery = EGL_TRUE; + } else { + if (IsTokenInString(str, NAME_DEVICE_ENUM, sizeof(NAME_DEVICE_ENUM) - 1, " ")) { + vendor->supportsDeviceEnum = EGL_TRUE; + } + if (IsTokenInString(str, NAME_DEVICE_QUERY, sizeof(NAME_DEVICE_QUERY) - 1, " ")) { + vendor->supportsDeviceQuery = EGL_TRUE; + } } } @@ -443,10 +458,12 @@ static void CheckVendorExtensions(__EGLvendorInfo *vendor) } if (vendor->staticDispatch.queryDevicesEXT == NULL) { - vendor->supportsDevice = EGL_FALSE; + vendor->supportsDeviceEnum = EGL_FALSE; } - if (!vendor->supportsDevice) { + if (!vendor->supportsDeviceEnum && !vendor->supportsDeviceQuery) { + // If we don't have either of the device extensions, then there's no + // way to get an EGLDeviceEXT handle from this vendor. vendor->supportsPlatformDevice = EGL_FALSE; } } diff --git a/src/EGL/libeglvendor.h b/src/EGL/libeglvendor.h index 443f285e20ff86100d7134158d740f791f710a10..bc3fdef18b831869cb44ef258e9bea573d01f86c 100644 --- a/src/EGL/libeglvendor.h +++ b/src/EGL/libeglvendor.h @@ -29,7 +29,8 @@ struct __EGLvendorInfoRec { EGLBoolean supportsGL; EGLBoolean supportsGLES; - EGLBoolean supportsDevice; + EGLBoolean supportsDeviceEnum; + EGLBoolean supportsDeviceQuery; EGLBoolean supportsPlatformDevice; EGLBoolean supportsPlatformGbm; EGLBoolean supportsPlatformX11;