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 <ajax@redhat.com>
Acked-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20069>
This commit is contained in:
Emma Anholt
2022-11-28 16:21:05 -08:00
committed by Marge Bot
parent b49e7cb3f4
commit 6229b48aaa
3 changed files with 57 additions and 46 deletions
+9 -46
View File
@@ -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;
}
+29
View File
@@ -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.
*
+19
View File
@@ -29,6 +29,8 @@
#include <stdbool.h>
#include <sys/stat.h>
#include <stddef.h>
#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