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 +#ifdef HAVE_LIBDRM +#include +#endif + +#ifdef MAJOR_IN_MKDEV +#include +#endif +#ifdef MAJOR_IN_SYSMACROS +#include +#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 #include -#ifdef MAJOR_IN_MKDEV -#include -#endif -#ifdef MAJOR_IN_SYSMACROS -#include -#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;