mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 09:30:13 +01:00
gbm: split the DRI backend into a separate library and unify backend handling
This does a few things: 1. Applications linked against a non-matching GBM can load the right version of the backend from the environment, avoiding GBM/Mesa version mismatches in many cases 2. Distros that want to split off libgbm into a separate package from the actual drivers get to not ship 40MB of libgallium_dri 3. The loader logic becomes way less complex See also: https://github.com/NixOS/nixpkgs/pull/338109 for original rationale. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31074>
This commit is contained in:
parent
67bcdbf4a1
commit
514df444eb
4 changed files with 58 additions and 106 deletions
|
|
@ -53,11 +53,15 @@
|
||||||
#include "pipe/p_screen.h"
|
#include "pipe/p_screen.h"
|
||||||
#include "dri_screen.h"
|
#include "dri_screen.h"
|
||||||
|
|
||||||
|
#include "gbm_backend_abi.h"
|
||||||
|
|
||||||
/* For importing wl_buffer */
|
/* For importing wl_buffer */
|
||||||
#if HAVE_WAYLAND_PLATFORM
|
#if HAVE_WAYLAND_PLATFORM
|
||||||
#include "wayland-drm.h"
|
#include "wayland-drm.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const struct gbm_core *core;
|
||||||
|
|
||||||
static GLboolean
|
static GLboolean
|
||||||
dri_validate_egl_image(void *image, void *data)
|
dri_validate_egl_image(void *image, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -324,7 +328,7 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
|
||||||
static int
|
static int
|
||||||
gbm_format_to_dri_format(uint32_t gbm_format)
|
gbm_format_to_dri_format(uint32_t gbm_format)
|
||||||
{
|
{
|
||||||
gbm_format = gbm_core.v0.format_canonicalize(gbm_format);
|
gbm_format = core->v0.format_canonicalize(gbm_format);
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(gbm_dri_visuals_table); i++) {
|
for (size_t i = 0; i < ARRAY_SIZE(gbm_dri_visuals_table); i++) {
|
||||||
if (gbm_dri_visuals_table[i].gbm_format == gbm_format)
|
if (gbm_dri_visuals_table[i].gbm_format == gbm_format)
|
||||||
return gbm_dri_visuals_table[i].dri_image_format;
|
return gbm_dri_visuals_table[i].dri_image_format;
|
||||||
|
|
@ -344,7 +348,7 @@ gbm_dri_is_format_supported(struct gbm_device *gbm,
|
||||||
if ((usage & GBM_BO_USE_CURSOR) && (usage & GBM_BO_USE_RENDERING))
|
if ((usage & GBM_BO_USE_CURSOR) && (usage & GBM_BO_USE_RENDERING))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
format = gbm_core.v0.format_canonicalize(format);
|
format = core->v0.format_canonicalize(format);
|
||||||
if (gbm_format_to_dri_format(format) == 0)
|
if (gbm_format_to_dri_format(format) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -380,7 +384,7 @@ gbm_dri_get_format_modifier_plane_count(struct gbm_device *gbm,
|
||||||
if (!dri->has_dmabuf_import)
|
if (!dri->has_dmabuf_import)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
format = gbm_core.v0.format_canonicalize(format);
|
format = core->v0.format_canonicalize(format);
|
||||||
if (gbm_format_to_dri_format(format) == 0)
|
if (gbm_format_to_dri_format(format) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -702,7 +706,7 @@ gbm_dri_bo_import(struct gbm_device *gbm,
|
||||||
/* GBM's GBM_FORMAT_* tokens are a strict superset of the DRI FourCC
|
/* GBM's GBM_FORMAT_* tokens are a strict superset of the DRI FourCC
|
||||||
* tokens accepted by createImageFromDmaBufs, except for not supporting
|
* tokens accepted by createImageFromDmaBufs, except for not supporting
|
||||||
* the sARGB format. */
|
* the sARGB format. */
|
||||||
fourcc = gbm_core.v0.format_canonicalize(fd_data->format);
|
fourcc = core->v0.format_canonicalize(fd_data->format);
|
||||||
|
|
||||||
image = dri2_from_dma_bufs(dri->screen,
|
image = dri2_from_dma_bufs(dri->screen,
|
||||||
fd_data->width,
|
fd_data->width,
|
||||||
|
|
@ -730,7 +734,7 @@ gbm_dri_bo_import(struct gbm_device *gbm,
|
||||||
/* GBM's GBM_FORMAT_* tokens are a strict superset of the DRI FourCC
|
/* GBM's GBM_FORMAT_* tokens are a strict superset of the DRI FourCC
|
||||||
* tokens accepted by createImageFromDmaBufs, except for not supporting
|
* tokens accepted by createImageFromDmaBufs, except for not supporting
|
||||||
* the sARGB format. */
|
* the sARGB format. */
|
||||||
fourcc = gbm_core.v0.format_canonicalize(fd_data->format);
|
fourcc = core->v0.format_canonicalize(fd_data->format);
|
||||||
|
|
||||||
image = dri2_from_dma_bufs(dri->screen, fd_data->width,
|
image = dri2_from_dma_bufs(dri->screen, fd_data->width,
|
||||||
fd_data->height, fourcc,
|
fd_data->height, fourcc,
|
||||||
|
|
@ -863,7 +867,7 @@ gbm_dri_bo_create(struct gbm_device *gbm,
|
||||||
uint64_t *mods_filtered = NULL;
|
uint64_t *mods_filtered = NULL;
|
||||||
unsigned int count_filtered = 0;
|
unsigned int count_filtered = 0;
|
||||||
|
|
||||||
format = gbm_core.v0.format_canonicalize(format);
|
format = core->v0.format_canonicalize(format);
|
||||||
|
|
||||||
if (usage & GBM_BO_USE_WRITE || !dri->has_dmabuf_export)
|
if (usage & GBM_BO_USE_WRITE || !dri->has_dmabuf_export)
|
||||||
return create_dumb(gbm, width, height, format, usage);
|
return create_dumb(gbm, width, height, format, usage);
|
||||||
|
|
@ -1095,7 +1099,7 @@ gbm_dri_surface_create(struct gbm_device *gbm,
|
||||||
surf->base.gbm = gbm;
|
surf->base.gbm = gbm;
|
||||||
surf->base.v0.width = width;
|
surf->base.v0.width = width;
|
||||||
surf->base.v0.height = height;
|
surf->base.v0.height = height;
|
||||||
surf->base.v0.format = gbm_core.v0.format_canonicalize(format);
|
surf->base.v0.format = core->v0.format_canonicalize(format);
|
||||||
surf->base.v0.flags = flags;
|
surf->base.v0.flags = flags;
|
||||||
if (!modifiers) {
|
if (!modifiers) {
|
||||||
assert(!count);
|
assert(!count);
|
||||||
|
|
@ -1153,13 +1157,6 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
|
||||||
int ret;
|
int ret;
|
||||||
bool force_sw;
|
bool force_sw;
|
||||||
|
|
||||||
/*
|
|
||||||
* Since the DRI backend is built-in to the loader, the loader ABI version is
|
|
||||||
* guaranteed to match this backend's ABI version
|
|
||||||
*/
|
|
||||||
assert(gbm_core.v0.core_version == GBM_BACKEND_ABI_VERSION);
|
|
||||||
assert(gbm_core.v0.core_version == gbm_backend_version);
|
|
||||||
|
|
||||||
dri = calloc(1, sizeof *dri);
|
dri = calloc(1, sizeof *dri);
|
||||||
if (!dri)
|
if (!dri)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1229,3 +1226,11 @@ struct gbm_backend gbm_dri_backend = {
|
||||||
.v0.backend_name = "dri",
|
.v0.backend_name = "dri",
|
||||||
.v0.create_device = dri_device_create,
|
.v0.create_device = dri_device_create,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gbm_backend * gbmint_get_backend(const struct gbm_core *gbm_core);
|
||||||
|
|
||||||
|
PUBLIC struct gbm_backend *
|
||||||
|
gbmint_get_backend(const struct gbm_core *gbm_core) {
|
||||||
|
core = gbm_core;
|
||||||
|
return &gbm_dri_backend;
|
||||||
|
};
|
||||||
|
|
|
||||||
12
src/gbm/backends/dri/meson.build
Normal file
12
src/gbm/backends/dri/meson.build
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
libgbm_dri = shared_library(
|
||||||
|
'dri_gbm',
|
||||||
|
files('gbm_dri.c', 'gbm_driint.h'),
|
||||||
|
include_directories : incs_gbm,
|
||||||
|
link_args : [ld_args_gc_sections],
|
||||||
|
link_with : [libloader, libgallium_dri],
|
||||||
|
dependencies : [deps_gbm, dep_dl, dep_thread, dep_libdrm, idep_mesautil, idep_xmlconfig],
|
||||||
|
gnu_symbol_visibility : 'hidden',
|
||||||
|
install : true,
|
||||||
|
install_dir: join_paths(get_option('libdir'), 'gbm'),
|
||||||
|
name_prefix : '',
|
||||||
|
)
|
||||||
|
|
@ -42,22 +42,12 @@
|
||||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||||
#define VER_MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define VER_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
#ifdef HAVE_DRI
|
|
||||||
extern const struct gbm_backend gbm_dri_backend;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct gbm_backend_desc {
|
struct gbm_backend_desc {
|
||||||
const char *name;
|
const char *name;
|
||||||
const struct gbm_backend *backend;
|
const struct gbm_backend *backend;
|
||||||
void *lib;
|
void *lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct gbm_backend_desc builtin_backends[] = {
|
|
||||||
#ifdef HAVE_DRI
|
|
||||||
{ "dri", &gbm_dri_backend },
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BACKEND_LIB_SUFFIX "_gbm"
|
#define BACKEND_LIB_SUFFIX "_gbm"
|
||||||
static const char *backend_search_path_vars[] = {
|
static const char *backend_search_path_vars[] = {
|
||||||
"GBM_BACKENDS_PATH",
|
"GBM_BACKENDS_PATH",
|
||||||
|
|
@ -116,8 +106,16 @@ backend_create_device(const struct gbm_backend_desc *bd, int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gbm_device *
|
static struct gbm_device *
|
||||||
load_backend(void *lib, int fd, const char *name)
|
load_backend_by_name(const char *name, int fd, bool warn_on_fail)
|
||||||
{
|
{
|
||||||
|
void *lib = loader_open_driver_lib(name, BACKEND_LIB_SUFFIX,
|
||||||
|
backend_search_path_vars,
|
||||||
|
DEFAULT_BACKENDS_PATH,
|
||||||
|
warn_on_fail);
|
||||||
|
|
||||||
|
if (!lib)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
struct gbm_device *dev = NULL;
|
struct gbm_device *dev = NULL;
|
||||||
struct gbm_backend_desc *backend_desc;
|
struct gbm_backend_desc *backend_desc;
|
||||||
const struct gbm_backend *gbm_backend;
|
const struct gbm_backend *gbm_backend;
|
||||||
|
|
@ -146,89 +144,25 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gbm_device *
|
|
||||||
find_backend(const char *name, int fd)
|
|
||||||
{
|
|
||||||
struct gbm_device *dev = NULL;
|
|
||||||
const struct gbm_backend_desc *bd;
|
|
||||||
void *lib;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(builtin_backends); ++i) {
|
|
||||||
bd = &builtin_backends[i];
|
|
||||||
|
|
||||||
if (name && strcmp(bd->name, name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dev = backend_create_device(bd, fd);
|
|
||||||
|
|
||||||
if (dev)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name && !dev) {
|
|
||||||
lib = loader_open_driver_lib(name, BACKEND_LIB_SUFFIX,
|
|
||||||
backend_search_path_vars,
|
|
||||||
DEFAULT_BACKENDS_PATH,
|
|
||||||
true);
|
|
||||||
|
|
||||||
if (lib)
|
|
||||||
dev = load_backend(lib, fd, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct gbm_device *
|
|
||||||
override_backend(int fd)
|
|
||||||
{
|
|
||||||
struct gbm_device *dev = NULL;
|
|
||||||
const char *b;
|
|
||||||
|
|
||||||
b = getenv("GBM_BACKEND");
|
|
||||||
if (b)
|
|
||||||
dev = find_backend(b, fd);
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct gbm_device *
|
|
||||||
backend_from_driver_name(int fd)
|
|
||||||
{
|
|
||||||
struct gbm_device *dev = NULL;
|
|
||||||
drmVersionPtr v = drmGetVersion(fd);
|
|
||||||
void *lib;
|
|
||||||
|
|
||||||
if (!v)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
lib = loader_open_driver_lib(v->name, BACKEND_LIB_SUFFIX,
|
|
||||||
backend_search_path_vars,
|
|
||||||
DEFAULT_BACKENDS_PATH,
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (lib)
|
|
||||||
dev = load_backend(lib, fd, v->name);
|
|
||||||
|
|
||||||
drmFreeVersion(v);
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gbm_device *
|
struct gbm_device *
|
||||||
_gbm_create_device(int fd)
|
_gbm_create_device(int fd)
|
||||||
{
|
{
|
||||||
struct gbm_device *dev;
|
struct gbm_device *dev = NULL;
|
||||||
|
|
||||||
dev = override_backend(fd);
|
const char *b = getenv("GBM_BACKEND");
|
||||||
|
if (b) {
|
||||||
|
dev = load_backend_by_name(b, fd, true);
|
||||||
|
if (dev) return dev;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dev)
|
drmVersionPtr v = drmGetVersion(fd);
|
||||||
dev = backend_from_driver_name(fd);
|
if (v) {
|
||||||
|
dev = load_backend_by_name(v->name, fd, false);
|
||||||
|
drmFreeVersion(v);
|
||||||
|
if (dev) return dev;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dev)
|
return load_backend_by_name("dri", fd, true);
|
||||||
dev = find_backend(NULL, fd);
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,15 @@ incs_gbm = [
|
||||||
# TODO: fix includes to delete this
|
# TODO: fix includes to delete this
|
||||||
incs_gbm += inc_mesa
|
incs_gbm += inc_mesa
|
||||||
|
|
||||||
if with_dri2
|
|
||||||
files_gbm += files('backends/dri/gbm_dri.c', 'backends/dri/gbm_driint.h')
|
|
||||||
endif
|
|
||||||
if with_platform_wayland
|
if with_platform_wayland
|
||||||
deps_gbm += dep_wayland_server
|
deps_gbm += dep_wayland_server
|
||||||
incs_gbm += inc_wayland_drm
|
incs_gbm += inc_wayland_drm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if with_dri2
|
||||||
|
subdir('backends/dri')
|
||||||
|
endif
|
||||||
|
|
||||||
libgbm_name = 'gbm'
|
libgbm_name = 'gbm'
|
||||||
|
|
||||||
if with_platform_android and get_option('platform-sdk-version') >= 30
|
if with_platform_android and get_option('platform-sdk-version') >= 30
|
||||||
|
|
@ -42,7 +43,7 @@ libgbm = shared_library(
|
||||||
include_directories : incs_gbm,
|
include_directories : incs_gbm,
|
||||||
c_args : [args_gbm],
|
c_args : [args_gbm],
|
||||||
link_args : [ld_args_gc_sections],
|
link_args : [ld_args_gc_sections],
|
||||||
link_with : [libloader, libgallium_dri],
|
link_with : [libloader],
|
||||||
dependencies : [deps_gbm, dep_dl, dep_thread, dep_libdrm, idep_mesautil, idep_xmlconfig],
|
dependencies : [deps_gbm, dep_dl, dep_thread, dep_libdrm, idep_mesautil, idep_xmlconfig],
|
||||||
gnu_symbol_visibility : 'hidden',
|
gnu_symbol_visibility : 'hidden',
|
||||||
version : '1.0.0',
|
version : '1.0.0',
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue