diff --git a/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/meson.build b/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/meson.build new file mode 100644 index 0000000000..760b599a63 --- /dev/null +++ b/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/meson.build @@ -0,0 +1,65 @@ +# Copyright © 2017 Dylan Baker +# SPDX-License-Identifier: MIT + +files_pipe_loader = files( + 'pipe_loader.c', + 'pipe_loader.h', + 'pipe_loader_priv.h', + 'pipe_loader_sw.c', + 'pipe_loader_redox.c', + 'driinfo_gallium.h', +) + +libpipe_loader_defines = [] +libpipe_loader_links = [] + +if dep_libdrm.found() + files_pipe_loader += files('pipe_loader_drm.c') + libpipe_loader_links += libloader +endif + +renderonly_drivers_c_args = [] +if with_gallium_etnaviv + renderonly_drivers_c_args += '-DGALLIUM_ETNAVIV' +endif +if with_gallium_lima + renderonly_drivers_c_args += '-DGALLIUM_LIMA' +endif +if with_gallium_v3d + renderonly_drivers_c_args += '-DGALLIUM_V3D' +endif +if with_gallium_vc4 + renderonly_drivers_c_args += '-DGALLIUM_VC4' +endif +if with_gallium_freedreno + renderonly_drivers_c_args += '-DGALLIUM_FREEDRENO' +endif +if with_gallium_panfrost + renderonly_drivers_c_args += '-DGALLIUM_PANFROST' +endif +if with_gallium_asahi + renderonly_drivers_c_args += '-DGALLIUM_ASAHI' +endif +if with_gallium_rocket + renderonly_drivers_c_args += '-DGALLIUM_ROCKET' +endif +if with_gallium_ethosu + renderonly_drivers_c_args += '-DGALLIUM_ETHOSU' +endif +if with_gallium_zink + renderonly_drivers_c_args += '-DGALLIUM_ZINK' +endif + +libpipe_loader_static = static_library( + 'pipe_loader_static', + files_pipe_loader, + include_directories : [ + inc_util, inc_loader, inc_gallium, inc_include, inc_src, inc_gallium_aux, + inc_gallium_winsys, inc_gallium_drivers, + ], + c_args : [libpipe_loader_defines, renderonly_drivers_c_args], + gnu_symbol_visibility : 'hidden', + link_with : [libpipe_loader_links], + dependencies : [dep_libdrm, idep_xmlconfig, idep_mesautil], + build_by_default : false, +) diff --git a/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/pipe_loader.c b/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/pipe_loader.c new file mode 100644 index 0000000000..2b408fb966 --- /dev/null +++ b/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/pipe_loader.c @@ -0,0 +1,190 @@ +/************************************************************************** + * + * Copyright 2012 Francisco Jerez + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe_loader_priv.h" + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_string.h" +#include "util/xmlconfig.h" +#include "util/driconf.h" +#include "util/perf/cpu_trace.h" + +#include + +#ifdef _MSC_VER +#include +#define PATH_MAX _MAX_PATH +#endif + +static int (*backends[])(struct pipe_loader_device **, int) = { +#ifdef HAVE_LIBDRM + &pipe_loader_drm_probe, +#endif +#ifdef HAVE_GALLIUM_REDOX + &pipe_loader_redux_probe, +#endif + &pipe_loader_sw_probe +}; + +const driOptionDescription gallium_driconf[] = { +#include "driinfo_gallium.h" +}; + +int +pipe_loader_probe(struct pipe_loader_device **devs, int ndev, bool with_zink) +{ + int i, n = 0; + + for (i = 0; i < ARRAY_SIZE(backends); i++) + n += backends[i](&devs[n], MAX2(0, ndev - n)); + +#if defined(HAVE_ZINK) && defined(HAVE_LIBDRM) + if (with_zink) + n += pipe_loader_drm_zink_probe(&devs[n], MAX2(0, ndev - n)); +#endif + + return n; +} + +void +pipe_loader_release(struct pipe_loader_device **devs, int ndev) +{ + int i; + + for (i = 0; i < ndev; i++) + devs[i]->ops->release(&devs[i]); +} + +void +pipe_loader_base_release(struct pipe_loader_device **dev) +{ + driDestroyOptionCache(&(*dev)->option_cache); + driDestroyOptionInfo(&(*dev)->option_info); + + FREE(*dev); + *dev = NULL; +} + +static driOptionDescription * +merge_driconf(const driOptionDescription *driver_driconf, unsigned driver_count, + unsigned *merged_count) +{ + unsigned gallium_count = ARRAY_SIZE(gallium_driconf); + driOptionDescription *merged = malloc((driver_count + gallium_count) * + sizeof(*merged)); + if (!merged) { + *merged_count = 0; + return NULL; + } + + if (gallium_count) + memcpy(merged, gallium_driconf, sizeof(*merged) * gallium_count); + if (driver_count) { + memcpy(&merged[gallium_count], driver_driconf, + sizeof(*merged) * driver_count); + } + + *merged_count = driver_count + gallium_count; + return merged; +} + +/** + * Ensure that dev->option_cache is initialized appropriately for the driver. + * + * This function can be called multiple times. + * + * \param dev Device for which options should be loaded. + */ +static void +pipe_loader_load_options(struct pipe_loader_device *dev) +{ + if (dev->option_info.info) + return; + + unsigned driver_count, merged_count; + const driOptionDescription *driver_driconf = + dev->ops->get_driconf(dev, &driver_count); + + const driOptionDescription *merged_driconf = + merge_driconf(driver_driconf, driver_count, &merged_count); + driParseOptionInfo(&dev->option_info, merged_driconf, merged_count); + free((void *)merged_driconf); +} + +void +pipe_loader_config_options(struct pipe_loader_device *dev) +{ + if (!dev->option_cache.info) { + driParseConfigFiles(&dev->option_cache, &dev->option_info, 0, + dev->driver_name, NULL, NULL, NULL, 0, NULL, 0); + } +} + +char * +pipe_loader_get_driinfo_xml(const char *driver_name) +{ + unsigned driver_count = 0; + const driOptionDescription *driver_driconf = NULL; + +#ifdef HAVE_LIBDRM + driver_driconf = pipe_loader_drm_get_driconf_by_name(driver_name, + &driver_count); +#endif + + unsigned merged_count; + const driOptionDescription *merged_driconf = + merge_driconf(driver_driconf, driver_count, &merged_count); + + char *xml = driGetOptionsXml(merged_driconf, merged_count); + + free((void *)driver_driconf); + free((void *)merged_driconf); + + return xml; +} + +struct pipe_screen * +pipe_loader_create_screen_vk(struct pipe_loader_device *dev, bool sw_vk, bool driver_name_is_inferred) +{ + struct pipe_screen_config config; + + util_cpu_trace_init(); + + pipe_loader_load_options(dev); + config.driver_name_is_inferred = driver_name_is_inferred; + config.options_info = &dev->option_info; + config.options = &dev->option_cache; + + return dev->ops->create_screen(dev, &config, sw_vk); +} + +struct pipe_screen * +pipe_loader_create_screen(struct pipe_loader_device *dev, bool driver_name_is_inferred) +{ + return pipe_loader_create_screen_vk(dev, false, driver_name_is_inferred); +} diff --git a/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/pipe_loader_redox.c b/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/pipe_loader_redox.c new file mode 100644 index 0000000000..ec20ee36da --- /dev/null +++ b/local/recipes/libs/mesa/source/src/gallium/auxiliary/pipe-loader/pipe_loader_redox.c @@ -0,0 +1,177 @@ +/* + * Redox OS pipe-loader backend for Mesa. + * + * Probes /scheme/drm/card0 (the Redox DRM device scheme) and exposes + * it as a pipe_loader_device so non-EGL gallium consumers (VAAPI, + * VDPAU, drm-info, etc.) can discover and load the Redox driver + * through the standard pipe_loader_probe() entry point. + * + * The actual gallium driver is selected via the driver_name field + * set by loader_get_kernel_driver_name() (which libdrm's redox patch + * fills in from DRM_IOCTL_VERSION's name field on scheme:drm/card0). + * Currently the only valid driver is "swrast" (llvmpipe/softpipe) + * because the iris/radeonsi/radeon/etc. drivers need Linux-specific + * KMS ioctls not yet wrapped by redox-drm; they can still be loaded + * by creating pipe_loader_device directly (the EGL redox platform + * does this in platform_redox.c). + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +#include + +#include "loader.h" +#include "pipe_loader_priv.h" +#include "target-helpers/drm_helper_public.h" +#include "frontend/drm_driver.h" + +#include "util/log.h" +#include "util/u_memory.h" +#include "util/u_string.h" + +#define REDOX_DRM_DEVICE_PATH "/scheme/drm/card0" +#define REDOX_DRM_DRIVER_NAME_MAX 64 + +struct pipe_loader_redux_device { + struct pipe_loader_device base; + int fd; +}; + +#define pipe_loader_redux_device(dev) ((struct pipe_loader_redux_device *)dev) + +static const struct pipe_loader_ops pipe_loader_redux_ops; + +static bool +pipe_loader_redux_probe_nodup(struct pipe_loader_device **dev, int fd) +{ + struct pipe_loader_redux_device *rdev = CALLOC_STRUCT(pipe_loader_redux_device); + drmVersionPtr ver; + char *driver_name; + const struct drm_driver_descriptor *dd; + + if (!rdev) + return false; + + rdev->base.type = PIPE_LOADER_DEVICE_PLATFORM; + rdev->base.ops = &pipe_loader_redux_ops; + rdev->fd = fd; + + ver = drmGetVersion(fd); + if (!ver || !ver->name || ver->name_len == 0) { + if (ver) + drmFreeVersion(ver); + goto fail; + } + driver_name = strndup(ver->name, ver->name_len); + drmFreeVersion(ver); + if (!driver_name) + goto fail; + rdev->base.driver_name = driver_name; + + dd = get_driver_descriptor(driver_name); + if (!dd) + goto fail; + rdev->base.dd = dd; + + *dev = &rdev->base; + return true; + +fail: + FREE(rdev->base.driver_name); + FREE(rdev); + return false; +} + +static bool +pipe_loader_redux_probe_fd(struct pipe_loader_device **dev, int fd) +{ + bool ret; + int new_fd; + + if (fd < 0) + return false; + new_fd = os_dupfd_cloexec(fd); + if (new_fd < 0) + return false; + + ret = pipe_loader_redux_probe_nodup(dev, new_fd); + if (!ret) { + close(new_fd); + return false; + } + return true; +} + +int +pipe_loader_redux_probe(struct pipe_loader_device **devs, int ndev) +{ + int fd; + + if (devs == NULL || ndev <= 0) + return 0; + + fd = loader_open_device(REDOX_DRM_DEVICE_PATH); + if (fd < 0) + return 0; + + struct pipe_loader_device *dev = NULL; + if (!pipe_loader_redux_probe_fd(&dev, fd)) { + close(fd); + return 0; + } + + devs[0] = dev; + return 1; +} + +static struct pipe_screen * +pipe_loader_redux_create_screen(struct pipe_loader_device *dev, + const struct pipe_screen_config *config, bool sw_vk) +{ + struct pipe_loader_redux_device *rdev = pipe_loader_redux_device(dev); + struct pipe_loader_drm_device *ddev = (struct pipe_loader_drm_device *)dev; + int ret_fd = rdev->fd; + struct pipe_screen *screen; + + (void) sw_vk; + + if (!ddev->dd) + return NULL; + + screen = ddev->dd->create_screen(ret_fd, config); + if (screen) + ((struct pipe_loader_drm_device *)dev)->fd = ret_fd; + return screen; +} + +static const struct driOptionDescription * +pipe_loader_redux_get_driconf(struct pipe_loader_device *dev, unsigned *count) +{ + struct pipe_loader_drm_device *ddev = (struct pipe_loader_drm_device *)dev; + if (!ddev->dd) { + *count = 0; + return NULL; + } + *count = ddev->dd->driconf_count; + return ddev->dd->driconf; +} + +static void +pipe_loader_redux_release(struct pipe_loader_device **dev) +{ + struct pipe_loader_redux_device *rdev = pipe_loader_redux_device(*dev); + close(rdev->fd); + FREE(rdev->base.driver_name); + pipe_loader_base_release(dev); +} + +static const struct pipe_loader_ops pipe_loader_redux_ops = { + .create_screen = pipe_loader_redux_create_screen, + .get_driconf = pipe_loader_redux_get_driconf, + .release = pipe_loader_redux_release +};