From 6229b48aaa8c783fd0d4a22d326913e7858c44ca Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Mon, 28 Nov 2022 16:21:05 -0800 Subject: [PATCH] gbm: Promote dri_bind_extensions() to the loader util library. It's better than EGL's copy of it by having optional ext support in the match structs, and GLX wishes it had either of the two. Reviewed-by: Adam Jackson Acked-by: Eric Engestrom Part-of: --- src/gbm/backends/dri/gbm_dri.c | 55 ++++++---------------------------- src/loader/loader.c | 29 ++++++++++++++++++ src/loader/loader.h | 19 ++++++++++++ 3 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index a5101dc14c8..a38de440c49 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -286,13 +286,6 @@ static const __DRIextension *gbm_dri_screen_extensions[] = { NULL, }; -struct dri_extension_match { - const char *name; - int version; - int offset; - bool optional; -}; - static struct dri_extension_match dri_core_extensions[] = { { __DRI2_FLUSH, 1, offsetof(struct gbm_dri_device, flush), false }, { __DRI_IMAGE, 6, offsetof(struct gbm_dri_device, image), false }, @@ -310,36 +303,6 @@ static struct dri_extension_match gbm_swrast_device_extensions[] = { { __DRI_KOPPER, 1, offsetof(struct gbm_dri_device, kopper), true }, }; -static bool -dri_bind_extensions(struct gbm_dri_device *dri, - struct dri_extension_match *matches, size_t num_matches, - const __DRIextension **extensions) -{ - bool ret = true; - void *field; - - for (size_t i = 0; extensions[i]; i++) { - for (size_t j = 0; j < num_matches; j++) { - if (strcmp(extensions[i]->name, matches[j].name) == 0 && - extensions[i]->version >= matches[j].version) { - field = ((char *) dri + matches[j].offset); - *(const __DRIextension **) field = extensions[i]; - } - } - } - - for (size_t j = 0; j < num_matches; j++) { - field = ((char *) dri + matches[j].offset); - if ((*(const __DRIextension **) field == NULL) && !matches[j].optional) { - fprintf(stderr, "gbm: did not find extension %s version %d\n", - matches[j].name, matches[j].version); - ret = false; - } - } - - return ret; -} - static const __DRIextension ** dri_open_driver(struct gbm_dri_device *dri) { @@ -374,9 +337,9 @@ dri_load_driver(struct gbm_dri_device *dri) if (!extensions) return -1; - if (!dri_bind_extensions(dri, gbm_dri_device_extensions, - ARRAY_SIZE(gbm_dri_device_extensions), - extensions)) { + if (!loader_bind_extensions(dri, gbm_dri_device_extensions, + ARRAY_SIZE(gbm_dri_device_extensions), + extensions)) { dlclose(dri->driver); fprintf(stderr, "failed to bind extensions\n"); return -1; @@ -396,9 +359,9 @@ dri_load_driver_swrast(struct gbm_dri_device *dri) if (!extensions) return -1; - if (!dri_bind_extensions(dri, gbm_swrast_device_extensions, - ARRAY_SIZE(gbm_swrast_device_extensions), - extensions)) { + if (!loader_bind_extensions(dri, gbm_swrast_device_extensions, + ARRAY_SIZE(gbm_swrast_device_extensions), + extensions)) { dlclose(dri->driver); fprintf(stderr, "failed to bind extensions\n"); return -1; @@ -438,9 +401,9 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name) return -1; extensions = dri->core->getExtensions(dri->screen); - if (!dri_bind_extensions(dri, dri_core_extensions, - ARRAY_SIZE(dri_core_extensions), - extensions)) { + if (!loader_bind_extensions(dri, dri_core_extensions, + ARRAY_SIZE(dri_core_extensions), + extensions)) { ret = -1; goto free_screen; } diff --git a/src/loader/loader.c b/src/loader/loader.c index 7ac871cb4c2..e4c607e1c7b 100644 --- a/src/loader/loader.c +++ b/src/loader/loader.c @@ -603,6 +603,35 @@ loader_get_extensions_name(const char *driver_name) return name; } +bool +loader_bind_extensions(void *data, + const struct dri_extension_match *matches, size_t num_matches, + const __DRIextension **extensions) +{ + bool ret = true; + void *field; + + for (size_t i = 0; extensions[i]; i++) { + for (size_t j = 0; j < num_matches; j++) { + if (strcmp(extensions[i]->name, matches[j].name) == 0 && + extensions[i]->version >= matches[j].version) { + field = ((char *) data + matches[j].offset); + *(const __DRIextension **) field = extensions[i]; + } + } + } + + for (size_t j = 0; j < num_matches; j++) { + field = ((char *) data + matches[j].offset); + if ((*(const __DRIextension **) field == NULL) && !matches[j].optional) { + log_(_LOADER_FATAL, "did not find extension %s version %d\n", + matches[j].name, matches[j].version); + ret = false; + } + } + + return ret; +} /** * Opens a driver or backend using its name, returning the library handle. * diff --git a/src/loader/loader.h b/src/loader/loader.h index 0305e27dffa..68e24a1ec1d 100644 --- a/src/loader/loader.h +++ b/src/loader/loader.h @@ -29,6 +29,8 @@ #include #include +#include +#include "GL/internal/dri_interface.h" #ifdef __cplusplus extern "C" { @@ -92,6 +94,23 @@ loader_set_logger(loader_logger *logger); char * loader_get_extensions_name(const char *driver_name); +struct dri_extension_match { + /* __DRI_* extension name */ + const char *name; + + /* Required minimum version in the extension struct */ + int version; + + /* offset in the data arg at which to store a pointer to the extension */ + int offset; + + bool optional; +}; + +bool loader_bind_extensions(void *data, + const struct dri_extension_match *matches, size_t num_matches, + const __DRIextension **extensions); + #ifdef __cplusplus } #endif