Module: Mesa
Branch: main
Commit: 407e4929de9a3e4eac17f8e203173b5c1f96bc33
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=407e4929de9a3e4eac17f8e203173b5c1f96bc33

Author: Rob Clark <[email protected]>
Date:   Fri Feb 17 11:10:24 2023 -0800

turnip: Refactor device loading

1) Allow the two different entrypoints for drm vs non-drm (kgsl) to
   coexist.
2) Split the generic drm related device initialization from the msm
   specifics.  This will simplify adding support for additional drm
   based kernel mode drivers (ie. virtgpu)

Signed-off-by: Rob Clark <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21394>

---

 src/freedreno/vulkan/tu_device.c      |   3 -
 src/freedreno/vulkan/tu_knl.c         | 154 ++++++++++++++++++++++++++++++++++
 src/freedreno/vulkan/tu_knl.h         |  10 ++-
 src/freedreno/vulkan/tu_knl_drm_msm.c | 101 ++--------------------
 src/freedreno/vulkan/tu_knl_kgsl.c    |  20 +----
 5 files changed, 170 insertions(+), 118 deletions(-)

diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
index abc99259b65..7913004f5cb 100644
--- a/src/freedreno/vulkan/tu_device.c
+++ b/src/freedreno/vulkan/tu_device.c
@@ -468,12 +468,9 @@ tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
       return vk_error(NULL, result);
    }
 
-#ifndef TU_USE_KGSL
    instance->vk.physical_devices.try_create_for_drm =
       tu_physical_device_try_create;
-#else
    instance->vk.physical_devices.enumerate = tu_enumerate_devices;
-#endif
    instance->vk.physical_devices.destroy = tu_destroy_physical_device;
 
    if (TU_DEBUG(STARTUP))
diff --git a/src/freedreno/vulkan/tu_knl.c b/src/freedreno/vulkan/tu_knl.c
index 5f57b7d33f2..5542f6c0fb5 100644
--- a/src/freedreno/vulkan/tu_knl.c
+++ b/src/freedreno/vulkan/tu_knl.c
@@ -7,6 +7,18 @@
  * Copyright © 2015 Intel Corporation
  */
 
+#include <fcntl.h>
+#ifdef HAVE_LIBDRM
+#include <xf86drm.h>
+#endif
+
+#ifdef MAJOR_IN_MKDEV
+#include <sys/mkdev.h>
+#endif
+#ifdef MAJOR_IN_SYSMACROS
+#include <sys/sysmacros.h>
+#endif
+
 #include "tu_device.h"
 #include "tu_knl.h"
 
@@ -100,3 +112,145 @@ tu_queue_submit(struct vk_queue *vk_queue, struct 
vk_queue_submit *submit)
    struct tu_queue *queue = container_of(vk_queue, struct tu_queue, vk);
    return queue->device->instance->knl->queue_submit(queue, submit);
 }
+
+/**
+ * Enumeration entrypoint specific to non-drm devices (ie. kgsl)
+ */
+VkResult
+tu_enumerate_devices(struct vk_instance *vk_instance)
+{
+#ifdef TU_USE_KGSL
+   struct tu_instance *instance =
+      container_of(vk_instance, struct tu_instance, vk);
+
+   static const char path[] = "/dev/kgsl-3d0";
+   int fd;
+
+   fd = open(path, O_RDWR | O_CLOEXEC);
+   if (fd < 0) {
+      if (errno == ENOENT)
+         return VK_ERROR_INCOMPATIBLE_DRIVER;
+
+      return vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
+                       "failed to open device %s", path);
+   }
+
+   VkResult result = tu_knl_kgsl_load(instance, fd);
+   if (result != VK_SUCCESS) {
+      close(fd);
+      return result;
+   }
+
+   if (TU_DEBUG(STARTUP))
+      mesa_logi("Found compatible device '%s'.", path);
+
+   return result;
+#else
+   return VK_ERROR_INCOMPATIBLE_DRIVER;
+#endif
+}
+
+/**
+ * Enumeration entrypoint for drm devices
+ */
+VkResult
+tu_physical_device_try_create(struct vk_instance *vk_instance,
+                              struct _drmDevice *drm_device,
+                              struct vk_physical_device **out)
+{
+#ifdef HAVE_LIBDRM
+   struct tu_instance *instance =
+      container_of(vk_instance, struct tu_instance, vk);
+
+   if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)) ||
+       drm_device->bustype != DRM_BUS_PLATFORM)
+      return VK_ERROR_INCOMPATIBLE_DRIVER;
+
+   const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];
+   const char *path = drm_device->nodes[DRM_NODE_RENDER];
+   VkResult result = VK_SUCCESS;
+   drmVersionPtr version;
+   int fd;
+   int master_fd = -1;
+
+   fd = open(path, O_RDWR | O_CLOEXEC);
+   if (fd < 0) {
+      return vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
+                               "failed to open device %s", path);
+   }
+
+   version = drmGetVersion(fd);
+   if (!version) {
+      close(fd);
+      return vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
+                               "failed to query kernel driver version for 
device %s",
+                               path);
+   }
+
+   struct tu_physical_device *device = NULL;
+
+   if (strcmp(version->name, "msm") == 0) {
+      result = tu_knl_drm_msm_load(instance, fd, version, &device);
+   } else {
+      result = vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
+                                 "device %s (%s) is not compatible with 
turnip",
+                                 path, version->name);
+   }
+
+   if (result != VK_SUCCESS)
+      goto out;
+
+   assert(device);
+
+   if (instance->vk.enabled_extensions.KHR_display) {
+      master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
+   }
+
+   device->master_fd = master_fd;
+
+   struct stat st;
+
+   if (stat(primary_path, &st) == 0) {
+      device->has_master = true;
+      device->master_major = major(st.st_rdev);
+      device->master_minor = minor(st.st_rdev);
+   } else {
+      device->has_master = false;
+      device->master_major = 0;
+      device->master_minor = 0;
+   }
+
+   if (stat(path, &st) == 0) {
+      device->has_local = true;
+      device->local_major = major(st.st_rdev);
+      device->local_minor = minor(st.st_rdev);
+   } else {
+      result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
+                         "failed to stat DRM render node %s", path);
+      goto out;
+   }
+
+   result = tu_physical_device_init(device, instance);
+   if (result != VK_SUCCESS)
+      goto out;
+
+   if (TU_DEBUG(STARTUP))
+      mesa_logi("Found compatible device '%s' (%s).", path, version->name);
+
+   *out = &device->vk;
+
+out:
+   if (result != VK_SUCCESS) {
+      if (master_fd != -1)
+         close(master_fd);
+      close(fd);
+      vk_free(&instance->vk.alloc, device);
+   }
+
+   drmFreeVersion(version);
+
+   return result;
+#else
+   return VK_ERROR_INCOMPATIBLE_DRIVER;
+#endif
+}
diff --git a/src/freedreno/vulkan/tu_knl.h b/src/freedreno/vulkan/tu_knl.h
index a0c805cb667..609c4425320 100644
--- a/src/freedreno/vulkan/tu_knl.h
+++ b/src/freedreno/vulkan/tu_knl.h
@@ -123,14 +123,20 @@ tu_bo_get_ref(struct tu_bo *bo)
 }
 
 #ifdef TU_USE_KGSL
+VkResult tu_knl_kgsl_load(struct tu_instance *instance, int fd);
+#endif
+
+struct _drmVersion;
+VkResult tu_knl_drm_msm_load(struct tu_instance *instance,
+                             int fd, struct _drmVersion *version,
+                             struct tu_physical_device **out);
+
 VkResult
 tu_enumerate_devices(struct vk_instance *vk_instance);
-#else
 VkResult
 tu_physical_device_try_create(struct vk_instance *vk_instance,
                               struct _drmDevice *drm_device,
                               struct vk_physical_device **out);
-#endif
 
 int
 tu_device_get_gpu_timestamp(struct tu_device *dev,
diff --git a/src/freedreno/vulkan/tu_knl_drm_msm.c 
b/src/freedreno/vulkan/tu_knl_drm_msm.c
index 75116289be0..e3cac4f0bbf 100644
--- a/src/freedreno/vulkan/tu_knl_drm_msm.c
+++ b/src/freedreno/vulkan/tu_knl_drm_msm.c
@@ -12,13 +12,6 @@
 #include <sys/mman.h>
 #include <xf86drm.h>
 
-#ifdef MAJOR_IN_MKDEV
-#include <sys/mkdev.h>
-#endif
-#ifdef MAJOR_IN_SYSMACROS
-#include <sys/sysmacros.h>
-#endif
-
 #include "vk_util.h"
 
 #include "drm-uapi/msm_drm.h"
@@ -1187,60 +1180,24 @@ const struct vk_sync_type tu_timeline_sync_type = {
 };
 
 VkResult
-tu_physical_device_try_create(struct vk_instance *vk_instance,
-                              struct _drmDevice *drm_device,
-                              struct vk_physical_device **out)
+tu_knl_drm_msm_load(struct tu_instance *instance,
+                    int fd, struct _drmVersion *version,
+                    struct tu_physical_device **out)
 {
-   struct tu_instance *instance =
-      container_of(vk_instance, struct tu_instance, vk);
-
-   if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)) ||
-       drm_device->bustype != DRM_BUS_PLATFORM)
-      return VK_ERROR_INCOMPATIBLE_DRIVER;
-
-   const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];
-   const char *path = drm_device->nodes[DRM_NODE_RENDER];
    VkResult result = VK_SUCCESS;
-   drmVersionPtr version;
-   int fd;
-   int master_fd = -1;
-
-   fd = open(path, O_RDWR | O_CLOEXEC);
-   if (fd < 0) {
-      return vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
-                               "failed to open device %s", path);
-   }
 
    /* Version 1.6 added SYNCOBJ support. */
    const int min_version_major = 1;
    const int min_version_minor = 6;
 
-   version = drmGetVersion(fd);
-   if (!version) {
-      close(fd);
-      return vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
-                               "failed to query kernel driver version for 
device %s",
-                               path);
-   }
-
-   if (strcmp(version->name, "msm")) {
-      drmFreeVersion(version);
-      close(fd);
-      return vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
-                               "device %s does not use the msm kernel driver",
-                               path);
-   }
-
    if (version->version_major != min_version_major ||
        version->version_minor < min_version_minor) {
       result = vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
                                  "kernel driver for device %s has version 
%d.%d, "
                                  "but Vulkan requires version >= %d.%d",
-                                 path,
+                                 version->name,
                                  version->version_major, 
version->version_minor,
                                  min_version_major, min_version_minor);
-      drmFreeVersion(version);
-      close(fd);
       return result;
    }
 
@@ -1249,28 +1206,13 @@ tu_physical_device_try_create(struct vk_instance 
*vk_instance,
                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (!device) {
       result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-      drmFreeVersion(version);
       goto fail;
    }
 
    device->msm_major_version = version->version_major;
    device->msm_minor_version = version->version_minor;
 
-   drmFreeVersion(version);
-
-   if (TU_DEBUG(STARTUP))
-      mesa_logi("Found compatible device '%s'.", path);
-
    device->instance = instance;
-
-   if (instance->vk.enabled_extensions.KHR_display) {
-      master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
-      if (master_fd >= 0) {
-         /* TODO: free master_fd is accel is not working? */
-      }
-   }
-
-   device->master_fd = master_fd;
    device->local_fd = fd;
 
    if (tu_drm_get_gpu_id(device, &device->dev_id.gpu_id)) {
@@ -1311,28 +1253,6 @@ tu_physical_device_try_create(struct vk_instance 
*vk_instance,
     */
    device->has_set_iova = false;
 
-   struct stat st;
-
-   if (stat(primary_path, &st) == 0) {
-      device->has_master = true;
-      device->master_major = major(st.st_rdev);
-      device->master_minor = minor(st.st_rdev);
-   } else {
-      device->has_master = false;
-      device->master_major = 0;
-      device->master_minor = 0;
-   }
-
-   if (stat(path, &st) == 0) {
-      device->has_local = true;
-      device->local_major = major(st.st_rdev);
-      device->local_minor = minor(st.st_rdev);
-   } else {
-      result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
-                         "failed to stat DRM render node %s", path);
-      goto fail;
-   }
-
    int ret = tu_drm_get_param(device, MSM_PARAM_FAULTS, &device->fault_count);
    if (ret != 0) {
       result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
@@ -1357,18 +1277,11 @@ tu_physical_device_try_create(struct vk_instance 
*vk_instance,
 
    instance->knl = &msm_knl_funcs;
 
-   result = tu_physical_device_init(device, instance);
+   *out = device;
 
-   if (result == VK_SUCCESS) {
-      *out = &device->vk;
-      return result;
-   }
+   return VK_SUCCESS;
 
 fail:
-   if (device)
-      vk_free(&instance->vk.alloc, device);
-   close(fd);
-   if (master_fd != -1)
-      close(master_fd);
+   vk_free(&instance->vk.alloc, device);
    return result;
 }
diff --git a/src/freedreno/vulkan/tu_knl_kgsl.c 
b/src/freedreno/vulkan/tu_knl_kgsl.c
index 558623a1248..75c41335185 100644
--- a/src/freedreno/vulkan/tu_knl_kgsl.c
+++ b/src/freedreno/vulkan/tu_knl_kgsl.c
@@ -827,28 +827,13 @@ static const struct tu_knl kgsl_knl_funcs = {
 };
 
 VkResult
-tu_enumerate_devices(struct vk_instance *vk_instance)
+tu_knl_kgsl_load(struct tu_instance *instance, int fd)
 {
-   struct tu_instance *instance =
-      container_of(vk_instance, struct tu_instance, vk);
-
-   static const char path[] = "/dev/kgsl-3d0";
-   int fd;
-
    if (instance->vk.enabled_extensions.KHR_display) {
       return vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
                        "I can't KHR_display");
    }
 
-   fd = open(path, O_RDWR | O_CLOEXEC);
-   if (fd < 0) {
-      if (errno == ENOENT)
-         return VK_ERROR_INCOMPATIBLE_DRIVER;
-
-      return vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
-                       "failed to open device %s", path);
-   }
-
    struct tu_physical_device *device =
       vk_zalloc(&instance->vk.alloc, sizeof(*device), 8,
                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
@@ -867,9 +852,6 @@ tu_enumerate_devices(struct vk_instance *vk_instance)
 
    /* kgsl version check? */
 
-   if (TU_DEBUG(STARTUP))
-      mesa_logi("Found compatible device '%s'.", path);
-
    device->instance = instance;
    device->master_fd = -1;
    device->local_fd = fd;

Reply via email to