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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user