gallium: rename 'state tracker' to 'frontend'
[mesa.git] / src / gallium / auxiliary / pipe-loader / pipe_loader_drm.c
index b5dfc56f49d98924b4271519514775da315faefc..5d6865be1b09dd6f596b015319bdfbabd8ecaaf7 100644 (file)
 
 #include <fcntl.h>
 #include <stdio.h>
+#include <string.h>
 #include <xf86drm.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include "loader.h"
 #include "target-helpers/drm_helper_public.h"
-#include "state_tracker/drm_driver.h"
+#include "frontend/drm_driver.h"
 #include "pipe_loader_priv.h"
 
 #include "util/u_memory.h"
@@ -63,110 +65,118 @@ struct pipe_loader_drm_device {
 static const struct pipe_loader_ops pipe_loader_drm_ops;
 
 #ifdef GALLIUM_STATIC_TARGETS
-static const struct drm_conf_ret throttle_ret = {
-   DRM_CONF_INT,
-   {2},
-};
-
-static const struct drm_conf_ret share_fd_ret = {
-   DRM_CONF_BOOL,
-   {true},
-};
-
-static inline const struct drm_conf_ret *
-configuration_query(enum drm_conf conf)
-{
-   switch (conf) {
-   case DRM_CONF_THROTTLE:
-      return &throttle_ret;
-   case DRM_CONF_SHARE_FD:
-      return &share_fd_ret;
-   default:
-      break;
-   }
-   return NULL;
-}
-
 static const struct drm_driver_descriptor driver_descriptors[] = {
     {
-        .name = "i915",
         .driver_name = "i915",
         .create_screen = pipe_i915_create_screen,
-        .configuration = configuration_query,
     },
     {
-        .name = "i965",
-        .driver_name = "i915",
-        .create_screen = pipe_ilo_create_screen,
-        .configuration = configuration_query,
+        .driver_name = "iris",
+        .create_screen = pipe_iris_create_screen,
+        .driconf_xml = &iris_driconf_xml,
     },
     {
-        .name = "nouveau",
         .driver_name = "nouveau",
         .create_screen = pipe_nouveau_create_screen,
-        .configuration = configuration_query,
     },
     {
-        .name = "r300",
-        .driver_name = "radeon",
+        .driver_name = "r300",
         .create_screen = pipe_r300_create_screen,
-        .configuration = configuration_query,
     },
     {
-        .name = "r600",
-        .driver_name = "radeon",
+        .driver_name = "r600",
         .create_screen = pipe_r600_create_screen,
-        .configuration = configuration_query,
     },
     {
-        .name = "radeonsi",
-        .driver_name = "radeon",
+        .driver_name = "radeonsi",
         .create_screen = pipe_radeonsi_create_screen,
-        .configuration = configuration_query,
+        .driconf_xml = &radeonsi_driconf_xml,
     },
     {
-        .name = "vmwgfx",
         .driver_name = "vmwgfx",
         .create_screen = pipe_vmwgfx_create_screen,
-        .configuration = configuration_query,
     },
     {
-        .name = "kgsl",
-        .driver_name = "freedreno",
+        .driver_name = "kgsl",
         .create_screen = pipe_freedreno_create_screen,
-        .configuration = configuration_query,
     },
     {
-        .name = "msm",
-        .driver_name = "freedreno",
+        .driver_name = "msm",
         .create_screen = pipe_freedreno_create_screen,
-        .configuration = configuration_query,
     },
     {
-        .name = "virtio_gpu",
-        .driver_name = "virtio-gpu",
+        .driver_name = "virtio_gpu",
         .create_screen = pipe_virgl_create_screen,
-        .configuration = configuration_query,
+        .driconf_xml = &virgl_driconf_xml,
     },
     {
-        .name = "vc4",
-        .driver_name = "vc4",
-        .create_screen = pipe_vc4_create_screen,
-        .configuration = configuration_query,
+        .driver_name = "v3d",
+        .create_screen = pipe_v3d_create_screen,
+        .driconf_xml = &v3d_driconf_xml,
     },
-#ifdef USE_VC4_SIMULATOR
     {
-        .name = "i965",
         .driver_name = "vc4",
         .create_screen = pipe_vc4_create_screen,
-        .configuration = configuration_query,
+        .driconf_xml = &v3d_driconf_xml,
     },
-#endif
+    {
+        .driver_name = "panfrost",
+        .create_screen = pipe_panfrost_create_screen,
+    },
+    {
+        .driver_name = "etnaviv",
+        .create_screen = pipe_etna_create_screen,
+    },
+    {
+        .driver_name = "tegra",
+        .create_screen = pipe_tegra_create_screen,
+    },
+    {
+        .driver_name = "lima",
+        .create_screen = pipe_lima_create_screen,
+    },
+    {
+        .driver_name = "zink",
+        .create_screen = pipe_zink_create_screen,
+    },
+};
+
+static const struct drm_driver_descriptor default_driver_descriptor = {
+        .driver_name = "kmsro",
+        .create_screen = pipe_kmsro_create_screen,
+        .driconf_xml = &v3d_driconf_xml,
 };
+
 #endif
 
-bool
-pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
+static const struct drm_driver_descriptor *
+get_driver_descriptor(const char *driver_name, struct util_dl_library **plib)
+{
+#ifdef GALLIUM_STATIC_TARGETS
+   for (int i = 0; i < ARRAY_SIZE(driver_descriptors); i++) {
+      if (strcmp(driver_descriptors[i].driver_name, driver_name) == 0)
+         return &driver_descriptors[i];
+   }
+   return &default_driver_descriptor;
+#else
+   *plib = pipe_loader_find_module(driver_name, PIPE_SEARCH_DIR);
+   if (!*plib)
+      return NULL;
+
+   const struct drm_driver_descriptor *dd =
+         (const struct drm_driver_descriptor *)
+         util_dl_get_proc_address(*plib, "driver_descriptor");
+
+   /* sanity check on the driver name */
+   if (dd && strcmp(dd->driver_name, driver_name) == 0)
+      return dd;
+#endif
+
+   return NULL;
+}
+
+static bool
+pipe_loader_drm_probe_fd_nodup(struct pipe_loader_device **dev, int fd)
 {
    struct pipe_loader_drm_device *ddev = CALLOC_STRUCT(pipe_loader_drm_device);
    int vendor_id, chip_id;
@@ -184,31 +194,31 @@ pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
    ddev->base.ops = &pipe_loader_drm_ops;
    ddev->fd = fd;
 
-   ddev->base.driver_name = loader_get_driver_for_fd(fd, _LOADER_GALLIUM);
+   ddev->base.driver_name = loader_get_driver_for_fd(fd);
    if (!ddev->base.driver_name)
       goto fail;
 
-#ifdef GALLIUM_STATIC_TARGETS
-   for (int i = 0; i < ARRAY_SIZE(driver_descriptors); i++) {
-      if (strcmp(driver_descriptors[i].name, ddev->base.driver_name) == 0) {
-         ddev->dd = &driver_descriptors[i];
-         break;
-      }
+   /* For the closed source AMD OpenGL driver, we want libgbm to load
+    * "amdgpu_dri.so", but we want Gallium multimedia drivers to load
+    * "radeonsi". So change amdgpu to radeonsi for Gallium.
+    */
+   if (strcmp(ddev->base.driver_name, "amdgpu") == 0) {
+      FREE(ddev->base.driver_name);
+      ddev->base.driver_name = strdup("radeonsi");
    }
-   if (!ddev->dd)
-      goto fail;
-#else
-   ddev->lib = pipe_loader_find_module(&ddev->base, PIPE_SEARCH_DIR);
-   if (!ddev->lib)
-      goto fail;
 
-   ddev->dd = (const struct drm_driver_descriptor *)
-      util_dl_get_proc_address(ddev->lib, "driver_descriptor");
+   struct util_dl_library **plib = NULL;
+#ifndef GALLIUM_STATIC_TARGETS
+   plib = &ddev->lib;
+#endif
+   ddev->dd = get_driver_descriptor(ddev->base.driver_name, plib);
+
+   /* kmsro supports lots of drivers, try as a fallback */
+   if (!ddev->dd)
+      ddev->dd = get_driver_descriptor("kmsro", plib);
 
-   /* sanity check on the name */
-   if (!ddev->dd || strcmp(ddev->dd->name, ddev->base.driver_name) != 0)
+   if (!ddev->dd)
       goto fail;
-#endif
 
    *dev = &ddev->base;
    return true;
@@ -218,10 +228,27 @@ pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
    if (ddev->lib)
       util_dl_close(ddev->lib);
 #endif
+   FREE(ddev->base.driver_name);
    FREE(ddev);
    return false;
 }
 
+bool
+pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
+{
+   bool ret;
+   int new_fd;
+
+   if (fd < 0 || (new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0)
+     return false;
+
+   ret = pipe_loader_drm_probe_fd_nodup(dev, new_fd);
+   if (!ret)
+      close(new_fd);
+
+   return ret;
+}
+
 static int
 open_drm_render_node_minor(int minor)
 {
@@ -244,7 +271,7 @@ pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev)
       if (fd < 0)
          continue;
 
-      if (!pipe_loader_drm_probe_fd(&dev, fd)) {
+      if (!pipe_loader_drm_probe_fd_nodup(&dev, fd)) {
          close(fd);
          continue;
       }
@@ -273,32 +300,47 @@ pipe_loader_drm_release(struct pipe_loader_device **dev)
 
    close(ddev->fd);
    FREE(ddev->base.driver_name);
-   FREE(ddev);
-   *dev = NULL;
+   pipe_loader_base_release(dev);
 }
 
-static const struct drm_conf_ret *
-pipe_loader_drm_configuration(struct pipe_loader_device *dev,
-                              enum drm_conf conf)
+static const char *
+pipe_loader_drm_get_driconf_xml(struct pipe_loader_device *dev)
 {
    struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);
 
-   if (!ddev->dd->configuration)
+   if (!ddev->dd->driconf_xml)
       return NULL;
 
-   return ddev->dd->configuration(conf);
+   return *ddev->dd->driconf_xml;
 }
 
 static struct pipe_screen *
-pipe_loader_drm_create_screen(struct pipe_loader_device *dev)
+pipe_loader_drm_create_screen(struct pipe_loader_device *dev,
+                              const struct pipe_screen_config *config)
 {
    struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);
 
-   return ddev->dd->create_screen(ddev->fd);
+   return ddev->dd->create_screen(ddev->fd, config);
+}
+
+char *
+pipe_loader_drm_get_driinfo_xml(const char *driver_name)
+{
+   char *xml = NULL;
+   struct util_dl_library *lib = NULL;
+   const struct drm_driver_descriptor *dd =
+      get_driver_descriptor(driver_name, &lib);
+
+   if (dd && dd->driconf_xml && *dd->driconf_xml)
+      xml = strdup(*dd->driconf_xml);
+
+   if (lib)
+      util_dl_close(lib);
+   return xml;
 }
 
 static const struct pipe_loader_ops pipe_loader_drm_ops = {
    .create_screen = pipe_loader_drm_create_screen,
-   .configuration = pipe_loader_drm_configuration,
+   .get_driconf_xml = pipe_loader_drm_get_driconf_xml,
    .release = pipe_loader_drm_release
 };