Path: blob/21.2-virgl/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
4561 views
/**************************************************************************1*2* Copyright 2011 Intel Corporation3* Copyright 2012 Francisco Jerez4* All Rights Reserved.5*6* Permission is hereby granted, free of charge, to any person obtaining a7* copy of this software and associated documentation files (the8* "Software"), to deal in the Software without restriction, including9* without limitation the rights to use, copy, modify, merge, publish,10* distribute, sub license, and/or sell copies of the Software, and to11* permit persons to whom the Software is furnished to do so, subject to12* the following conditions:13*14* The above copyright notice and this permission notice (including the15* next paragraph) shall be included in all copies or substantial portions16* of the Software.17*18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS19* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF20* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.21* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR22* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,23* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE24* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.25*26* Authors:27* Kristian Høgsberg <[email protected]>28* Benjamin Franzke <[email protected]>29*30**************************************************************************/3132#include <fcntl.h>33#include <stdio.h>34#include <string.h>35#include <xf86drm.h>36#include <unistd.h>37#include <fcntl.h>3839#include "loader.h"40#include "target-helpers/drm_helper_public.h"41#include "frontend/drm_driver.h"42#include "pipe_loader_priv.h"4344#include "util/os_file.h"45#include "util/u_memory.h"46#include "util/u_dl.h"47#include "util/u_debug.h"48#include "util/xmlconfig.h"4950#define DRM_RENDER_NODE_DEV_NAME_FORMAT "%s/renderD%d"51#define DRM_RENDER_NODE_MAX_NODES 6352#define DRM_RENDER_NODE_MIN_MINOR 12853#define DRM_RENDER_NODE_MAX_MINOR (DRM_RENDER_NODE_MIN_MINOR + DRM_RENDER_NODE_MAX_NODES)5455struct pipe_loader_drm_device {56struct pipe_loader_device base;57const struct drm_driver_descriptor *dd;58#ifndef GALLIUM_STATIC_TARGETS59struct util_dl_library *lib;60#endif61int fd;62};6364#define pipe_loader_drm_device(dev) ((struct pipe_loader_drm_device *)dev)6566static const struct pipe_loader_ops pipe_loader_drm_ops;6768#ifdef GALLIUM_STATIC_TARGETS69static const struct drm_driver_descriptor *driver_descriptors[] = {70&i915_driver_descriptor,71&iris_driver_descriptor,72&crocus_driver_descriptor,73&nouveau_driver_descriptor,74&r300_driver_descriptor,75&r600_driver_descriptor,76&radeonsi_driver_descriptor,77&vmwgfx_driver_descriptor,78&kgsl_driver_descriptor,79&msm_driver_descriptor,80&virtio_gpu_driver_descriptor,81&v3d_driver_descriptor,82&vc4_driver_descriptor,83&panfrost_driver_descriptor,84&etnaviv_driver_descriptor,85&tegra_driver_descriptor,86&lima_driver_descriptor,87&zink_driver_descriptor,88};89#endif9091static const struct drm_driver_descriptor *92get_driver_descriptor(const char *driver_name, struct util_dl_library **plib)93{94#ifdef GALLIUM_STATIC_TARGETS95for (int i = 0; i < ARRAY_SIZE(driver_descriptors); i++) {96if (strcmp(driver_descriptors[i]->driver_name, driver_name) == 0)97return driver_descriptors[i];98}99return &kmsro_driver_descriptor;100#else101const char *search_dir = getenv("GALLIUM_PIPE_SEARCH_DIR");102if (search_dir == NULL)103search_dir = PIPE_SEARCH_DIR;104105*plib = pipe_loader_find_module(driver_name, search_dir);106if (!*plib)107return NULL;108109const struct drm_driver_descriptor *dd =110(const struct drm_driver_descriptor *)111util_dl_get_proc_address(*plib, "driver_descriptor");112113/* sanity check on the driver name */114if (dd && strcmp(dd->driver_name, driver_name) == 0)115return dd;116#endif117118return NULL;119}120121static bool122pipe_loader_drm_probe_fd_nodup(struct pipe_loader_device **dev, int fd)123{124struct pipe_loader_drm_device *ddev = CALLOC_STRUCT(pipe_loader_drm_device);125int vendor_id, chip_id;126127if (!ddev)128return false;129130if (loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {131ddev->base.type = PIPE_LOADER_DEVICE_PCI;132ddev->base.u.pci.vendor_id = vendor_id;133ddev->base.u.pci.chip_id = chip_id;134} else {135ddev->base.type = PIPE_LOADER_DEVICE_PLATFORM;136}137ddev->base.ops = &pipe_loader_drm_ops;138ddev->fd = fd;139140ddev->base.driver_name = loader_get_driver_for_fd(fd);141if (!ddev->base.driver_name)142goto fail;143144/* For the closed source AMD OpenGL driver, we want libgbm to load145* "amdgpu_dri.so", but we want Gallium multimedia drivers to load146* "radeonsi". So change amdgpu to radeonsi for Gallium.147*/148if (strcmp(ddev->base.driver_name, "amdgpu") == 0) {149FREE(ddev->base.driver_name);150ddev->base.driver_name = strdup("radeonsi");151}152153struct util_dl_library **plib = NULL;154#ifndef GALLIUM_STATIC_TARGETS155plib = &ddev->lib;156#endif157ddev->dd = get_driver_descriptor(ddev->base.driver_name, plib);158159/* vgem is a virtual device; don't try using it with kmsro */160if (strcmp(ddev->base.driver_name, "vgem") == 0)161goto fail;162163/* kmsro supports lots of drivers, try as a fallback */164if (!ddev->dd)165ddev->dd = get_driver_descriptor("kmsro", plib);166167if (!ddev->dd)168goto fail;169170*dev = &ddev->base;171return true;172173fail:174#ifndef GALLIUM_STATIC_TARGETS175if (ddev->lib)176util_dl_close(ddev->lib);177#endif178FREE(ddev->base.driver_name);179FREE(ddev);180return false;181}182183bool184pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)185{186bool ret;187int new_fd;188189if (fd < 0 || (new_fd = os_dupfd_cloexec(fd)) < 0)190return false;191192ret = pipe_loader_drm_probe_fd_nodup(dev, new_fd);193if (!ret)194close(new_fd);195196return ret;197}198199static int200open_drm_render_node_minor(int minor)201{202char path[PATH_MAX];203snprintf(path, sizeof(path), DRM_RENDER_NODE_DEV_NAME_FORMAT, DRM_DIR_NAME,204minor);205return loader_open_device(path);206}207208int209pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev)210{211int i, j, fd;212213for (i = DRM_RENDER_NODE_MIN_MINOR, j = 0;214i <= DRM_RENDER_NODE_MAX_MINOR; i++) {215struct pipe_loader_device *dev;216217fd = open_drm_render_node_minor(i);218if (fd < 0)219continue;220221if (!pipe_loader_drm_probe_fd_nodup(&dev, fd)) {222close(fd);223continue;224}225226if (j < ndev) {227devs[j] = dev;228} else {229close(fd);230dev->ops->release(&dev);231}232j++;233}234235return j;236}237238static void239pipe_loader_drm_release(struct pipe_loader_device **dev)240{241struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(*dev);242243#ifndef GALLIUM_STATIC_TARGETS244if (ddev->lib)245util_dl_close(ddev->lib);246#endif247248close(ddev->fd);249FREE(ddev->base.driver_name);250pipe_loader_base_release(dev);251}252253static const struct driOptionDescription *254pipe_loader_drm_get_driconf(struct pipe_loader_device *dev, unsigned *count)255{256struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);257258*count = ddev->dd->driconf_count;259return ddev->dd->driconf;260}261262static struct pipe_screen *263pipe_loader_drm_create_screen(struct pipe_loader_device *dev,264const struct pipe_screen_config *config, bool sw_vk)265{266struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);267268return ddev->dd->create_screen(ddev->fd, config);269}270271const struct driOptionDescription *272pipe_loader_drm_get_driconf_by_name(const char *driver_name, unsigned *count)273{274driOptionDescription *driconf = NULL;275struct util_dl_library *lib = NULL;276const struct drm_driver_descriptor *dd =277get_driver_descriptor(driver_name, &lib);278279if (!dd) {280*count = 0;281} else {282*count = dd->driconf_count;283size_t size = sizeof(*driconf) * *count;284driconf = malloc(size);285memcpy(driconf, dd->driconf, size);286}287if (lib)288util_dl_close(lib);289290return driconf;291}292293static const struct pipe_loader_ops pipe_loader_drm_ops = {294.create_screen = pipe_loader_drm_create_screen,295.get_driconf = pipe_loader_drm_get_driconf,296.release = pipe_loader_drm_release297};298299300