loader_dri3: Handle mismatched depth 30 formats for Prime renderoffload.
[mesa.git] / src / loader / loader.c
index bb0c392cf7c1175db80bd395ea2d62a09cfa8b8b..43275484cc2e0c845e101627ba46e994073fb46c 100644 (file)
@@ -1,45 +1,7 @@
 /*
  * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
- *
- * This code is derived from the following files.
- *
- * * src/glx/dri3_common.c
- * Copyright © 2013 Keith Packard
- *
- * * src/egl/drivers/dri2/common.c
- * * src/gbm/backends/dri/driver_name.c
- * Copyright © 2011 Intel Corporation
- *
- * Authors:
- *    Kristian Høgsberg <krh@bitplanet.net>
- *    Benjamin Franzke <benjaminfranzke@googlemail.com>
- *
- * * src/gallium/targets/egl-static/egl.c
- * Copyright (C) 2010-2011 LunarG Inc.
- *
- * Authors:
- *    Chia-I Wu <olv@lunarg.com>
- *
- * * src/gallium/state_trackers/egl/drm/native_drm.c
- * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
- *
- * * src/egl/drivers/dri2/platform_android.c
- *
- * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
- * Copyright (C) 2010-2011 LunarG Inc.
- *
- * Based on platform_x11, which has
- *
- * Copyright © 2011 Intel Corporation
- *
- * * src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
- * Copyright 2011 Intel Corporation
- * Copyright 2012 Francisco Jerez
- * All Rights Reserved.
- *
- * Authors:
- *    Kristian Høgsberg <krh@bitplanet.net>
- *    Benjamin Franzke <benjaminfranzke@googlemail.com>
+ * Copyright (C) 2014-2016 Emil Velikov <emil.l.velikov@gmail.com>
+ * Copyright (C) 2016 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -71,6 +33,8 @@
 #include <stdio.h>
 #include <stdbool.h>
 #include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
 #ifdef MAJOR_IN_MKDEV
 #include <sys/mkdev.h>
 #endif
 #include "loader.h"
 
 #ifdef HAVE_LIBDRM
-#include <stdlib.h>
-#include <unistd.h>
 #include <xf86drm.h>
 #ifdef USE_DRICONF
-#include "xmlconfig.h"
-#include "xmlpool.h"
+#include "util/xmlconfig.h"
+#include "util/xmlpool.h"
 #endif
 #endif
 
@@ -148,18 +110,43 @@ static char *loader_get_dri_config_device_id(void)
 
 static char *drm_construct_id_path_tag(drmDevicePtr device)
 {
-/* Length of "pci-xxxx_xx_xx_x\0" */
-#define PCI_ID_PATH_TAG_LENGTH 17
    char *tag = NULL;
 
    if (device->bustype == DRM_BUS_PCI) {
-        tag = calloc(PCI_ID_PATH_TAG_LENGTH, sizeof(char));
-        if (tag == NULL)
-            return NULL;
+      if (asprintf(&tag, "pci-%04x_%02x_%02x_%1u",
+                   device->businfo.pci->domain,
+                   device->businfo.pci->bus,
+                   device->businfo.pci->dev,
+                   device->businfo.pci->func) < 0) {
+         return NULL;
+      }
+   } else if (device->bustype == DRM_BUS_PLATFORM ||
+              device->bustype == DRM_BUS_HOST1X) {
+      char *fullname, *name, *address;
+
+      if (device->bustype == DRM_BUS_PLATFORM)
+         fullname = device->businfo.platform->fullname;
+      else
+         fullname = device->businfo.host1x->fullname;
+
+      name = strrchr(fullname, '/');
+      if (!name)
+         name = strdup(fullname);
+      else
+         name = strdup(name + 1);
+
+      address = strchr(name, '@');
+      if (address) {
+         *address++ = '\0';
+
+         if (asprintf(&tag, "platform-%s_%s", address, name) < 0)
+            tag = NULL;
+      } else {
+         if (asprintf(&tag, "platform-%s", name) < 0)
+            tag = NULL;
+      }
 
-        snprintf(tag, PCI_ID_PATH_TAG_LENGTH, "pci-%04x_%02x_%02x_%1u",
-                 device->businfo.pci->domain, device->businfo.pci->bus,
-                 device->businfo.pci->dev, device->businfo.pci->func);
+      free(name);
    }
    return tag;
 }
@@ -183,7 +170,7 @@ static char *drm_get_id_path_tag_for_fd(int fd)
    drmDevicePtr device;
    char *tag;
 
-   if (drmGetDevice(fd, &device) != 0)
+   if (drmGetDevice2(fd, 0, &device) != 0)
        return NULL;
 
    tag = drm_construct_id_path_tag(device);
@@ -191,7 +178,7 @@ static char *drm_get_id_path_tag_for_fd(int fd)
    return tag;
 }
 
-int loader_get_user_preferred_fd(int default_fd, int *different_device)
+int loader_get_user_preferred_fd(int default_fd, bool *different_device)
 {
 /* Arbitrary "maximum" value of drm devices. */
 #define MAX_DRM_DEVICES 32
@@ -209,7 +196,7 @@ int loader_get_user_preferred_fd(int default_fd, int *different_device)
 #endif
 
    if (prime == NULL) {
-      *different_device = 0;
+      *different_device = false;
       return default_fd;
    }
 
@@ -217,7 +204,7 @@ int loader_get_user_preferred_fd(int default_fd, int *different_device)
    if (default_tag == NULL)
       goto err;
 
-   num_devices = drmGetDevices(devices, MAX_DRM_DEVICES);
+   num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
    if (num_devices < 0)
       goto err;
 
@@ -268,43 +255,20 @@ int loader_get_user_preferred_fd(int default_fd, int *different_device)
    return fd;
 
  err:
-   *different_device = 0;
+   *different_device = false;
 
    free(default_tag);
    free(prime);
    return default_fd;
 }
 #else
-int loader_get_user_preferred_fd(int default_fd, int *different_device)
+int loader_get_user_preferred_fd(int default_fd, bool *different_device)
 {
-   *different_device = 0;
+   *different_device = false;
    return default_fd;
 }
 #endif
 
-#if defined(HAVE_LIBDRM)
-static int
-dev_node_from_fd(int fd, unsigned int *maj, unsigned int *min)
-{
-   struct stat buf;
-
-   if (fstat(fd, &buf) < 0) {
-      log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d\n", fd);
-      return -1;
-   }
-
-   if (!S_ISCHR(buf.st_mode)) {
-      log_(_LOADER_WARNING, "MESA-LOADER: fd %d not a character device\n", fd);
-      return -1;
-   }
-
-   *maj = major(buf.st_rdev);
-   *min = minor(buf.st_rdev);
-
-   return 0;
-}
-#endif
-
 #if defined(HAVE_LIBDRM)
 
 static int
@@ -313,14 +277,14 @@ drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
    drmDevicePtr device;
    int ret;
 
-   if (drmGetDevice(fd, &device) == 0) {
+   if (drmGetDevice2(fd, 0, &device) == 0) {
       if (device->bustype == DRM_BUS_PCI) {
          *vendor_id = device->deviceinfo.pci->vendor_id;
          *chip_id = device->deviceinfo.pci->device_id;
          ret = 1;
       }
       else {
-         log_(_LOADER_WARNING, "MESA-LOADER: device is not located on the PCI bus\n");
+         log_(_LOADER_DEBUG, "MESA-LOADER: device is not located on the PCI bus\n");
          ret = 0;
       }
       drmFreeDevice(&device);
@@ -345,46 +309,34 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
    return 0;
 }
 
-
-#if defined(HAVE_LIBDRM)
-static char *
-drm_get_device_name_for_fd(int fd)
-{
-   unsigned int maj, min;
-   char buf[0x40];
-   int n;
-
-   if (dev_node_from_fd(fd, &maj, &min) < 0)
-      return NULL;
-
-   n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, min);
-   if (n == -1 || n >= sizeof(buf))
-      return NULL;
-
-   return strdup(buf);
-}
-#endif
-
 char *
 loader_get_device_name_for_fd(int fd)
 {
    char *result = NULL;
 
 #if HAVE_LIBDRM
-   if ((result = drm_get_device_name_for_fd(fd)))
-      return result;
+   result = drmGetDeviceNameFromFd2(fd);
 #endif
+
    return result;
 }
 
 char *
-loader_get_driver_for_fd(int fd, unsigned driver_types)
+loader_get_driver_for_fd(int fd)
 {
    int vendor_id, chip_id, i, j;
    char *driver = NULL;
 
-   if (!driver_types)
-      driver_types = _LOADER_GALLIUM | _LOADER_DRI;
+   /* Allow an environment variable to force choosing a different driver
+    * binary.  If that driver binary can't survive on this FD, that's the
+    * user's problem, but this allows vc4 simulator to run on an i965 host,
+    * and may be useful for some touch testing of i915 on an i965 host.
+    */
+   if (geteuid() == getuid()) {
+      driver = getenv("MESA_LOADER_DRIVER_OVERRIDE");
+      if (driver)
+         return strdup(driver);
+   }
 
    if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {
 
@@ -410,9 +362,6 @@ loader_get_driver_for_fd(int fd, unsigned driver_types)
       if (vendor_id != driver_map[i].vendor_id)
          continue;
 
-      if (!(driver_types & driver_map[i].driver_types))
-         continue;
-
       if (driver_map[i].predicate && !driver_map[i].predicate(fd))
          continue;
 
@@ -440,3 +389,28 @@ loader_set_logger(void (*logger)(int level, const char *fmt, ...))
 {
    log_ = logger;
 }
+
+/* XXX: Local definition to avoid pulling the heavyweight GL/gl.h and
+ * GL/internal/dri_interface.h
+ */
+
+#ifndef __DRI_DRIVER_GET_EXTENSIONS
+#define __DRI_DRIVER_GET_EXTENSIONS "__driDriverGetExtensions"
+#endif
+
+char *
+loader_get_extensions_name(const char *driver_name)
+{
+   char *name = NULL;
+
+   if (asprintf(&name, "%s_%s", __DRI_DRIVER_GET_EXTENSIONS, driver_name) < 0)
+      return NULL;
+
+   const size_t len = strlen(name);
+   for (size_t i = 0; i < len; i++) {
+          if (name[i] == '-')
+                  name[i] = '_';
+   }
+
+   return name;
+}