turnip: drm code-motion

Move a few functions around in prep for next commit.  Only code-motion.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21394>
This commit is contained in:
Rob Clark 2023-02-16 13:22:47 -08:00 committed by Marge Bot
parent 1cb702def4
commit f84fce767d
2 changed files with 276 additions and 275 deletions

View file

@ -772,206 +772,6 @@ tu_timeline_sync_wait(struct vk_device *vk_device,
return ret;
}
const struct vk_sync_type tu_timeline_sync_type = {
.size = sizeof(struct tu_timeline_sync),
.features = VK_SYNC_FEATURE_BINARY |
VK_SYNC_FEATURE_GPU_WAIT |
VK_SYNC_FEATURE_GPU_MULTI_WAIT |
VK_SYNC_FEATURE_CPU_WAIT |
VK_SYNC_FEATURE_CPU_RESET |
VK_SYNC_FEATURE_WAIT_ANY |
VK_SYNC_FEATURE_WAIT_PENDING,
.init = tu_timeline_sync_init,
.finish = tu_timeline_sync_finish,
.reset = tu_timeline_sync_reset,
.wait_many = tu_timeline_sync_wait,
};
VkResult
tu_physical_device_try_create(struct vk_instance *vk_instance,
struct _drmDevice *drm_device,
struct vk_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->version_major, version->version_minor,
min_version_major, min_version_minor);
drmFreeVersion(version);
close(fd);
return result;
}
struct tu_physical_device *device =
vk_zalloc(&instance->vk.alloc, sizeof(*device), 8,
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)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get GPU ID");
goto fail;
}
if (tu_drm_get_param(device, MSM_PARAM_CHIP_ID, &device->dev_id.chip_id)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get CHIP ID");
goto fail;
}
if (tu_drm_get_gmem_size(device, &device->gmem_size)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get GMEM size");
goto fail;
}
device->gmem_size = debug_get_num_option("TU_GMEM", device->gmem_size);
if (tu_drm_get_gmem_base(device, &device->gmem_base)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get GMEM size");
goto fail;
}
/*
* device->has_set_iova = !tu_drm_get_va_prop(device, &device->va_start,
* &device->va_size);
*
* If BO is freed while kernel considers it busy, our VMA state gets
* desynchronized from kernel's VMA state, because kernel waits
* until BO stops being busy. And whether BO is busy decided at
* submission granularity.
*
* Disable this capability until solution is found.
*/
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,
"Failed to get initial fault count: %d", ret);
goto fail;
}
device->submitqueue_priority_count = tu_drm_get_priorities(device);
device->syncobj_type = vk_drm_syncobj_get_type(fd);
/* we don't support DRM_CAP_SYNCOBJ_TIMELINE, but drm-shim does */
if (!(device->syncobj_type.features & VK_SYNC_FEATURE_TIMELINE))
device->timeline_type = vk_sync_timeline_get_type(&tu_timeline_sync_type);
device->sync_types[0] = &device->syncobj_type;
device->sync_types[1] = &device->timeline_type.sync;
device->sync_types[2] = NULL;
device->heap.size = tu_get_system_heap_size();
device->heap.used = 0u;
device->heap.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
result = tu_physical_device_init(device, instance);
if (result == VK_SUCCESS) {
*out = &device->vk;
return result;
}
fail:
if (device)
vk_free(&instance->vk.alloc, device);
close(fd);
if (master_fd != -1)
close(master_fd);
return result;
}
static VkResult
tu_queue_submit_create_locked(struct tu_queue *queue,
struct vk_queue_submit *vk_submit,
@ -1354,3 +1154,203 @@ tu_queue_submit(struct vk_queue *vk_queue, struct vk_queue_submit *submit)
return VK_SUCCESS;
}
const struct vk_sync_type tu_timeline_sync_type = {
.size = sizeof(struct tu_timeline_sync),
.features = VK_SYNC_FEATURE_BINARY |
VK_SYNC_FEATURE_GPU_WAIT |
VK_SYNC_FEATURE_GPU_MULTI_WAIT |
VK_SYNC_FEATURE_CPU_WAIT |
VK_SYNC_FEATURE_CPU_RESET |
VK_SYNC_FEATURE_WAIT_ANY |
VK_SYNC_FEATURE_WAIT_PENDING,
.init = tu_timeline_sync_init,
.finish = tu_timeline_sync_finish,
.reset = tu_timeline_sync_reset,
.wait_many = tu_timeline_sync_wait,
};
VkResult
tu_physical_device_try_create(struct vk_instance *vk_instance,
struct _drmDevice *drm_device,
struct vk_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->version_major, version->version_minor,
min_version_major, min_version_minor);
drmFreeVersion(version);
close(fd);
return result;
}
struct tu_physical_device *device =
vk_zalloc(&instance->vk.alloc, sizeof(*device), 8,
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)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get GPU ID");
goto fail;
}
if (tu_drm_get_param(device, MSM_PARAM_CHIP_ID, &device->dev_id.chip_id)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get CHIP ID");
goto fail;
}
if (tu_drm_get_gmem_size(device, &device->gmem_size)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get GMEM size");
goto fail;
}
device->gmem_size = debug_get_num_option("TU_GMEM", device->gmem_size);
if (tu_drm_get_gmem_base(device, &device->gmem_base)) {
result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
"could not get GMEM size");
goto fail;
}
/*
* device->has_set_iova = !tu_drm_get_va_prop(device, &device->va_start,
* &device->va_size);
*
* If BO is freed while kernel considers it busy, our VMA state gets
* desynchronized from kernel's VMA state, because kernel waits
* until BO stops being busy. And whether BO is busy decided at
* submission granularity.
*
* Disable this capability until solution is found.
*/
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,
"Failed to get initial fault count: %d", ret);
goto fail;
}
device->submitqueue_priority_count = tu_drm_get_priorities(device);
device->syncobj_type = vk_drm_syncobj_get_type(fd);
/* we don't support DRM_CAP_SYNCOBJ_TIMELINE, but drm-shim does */
if (!(device->syncobj_type.features & VK_SYNC_FEATURE_TIMELINE))
device->timeline_type = vk_sync_timeline_get_type(&tu_timeline_sync_type);
device->sync_types[0] = &device->syncobj_type;
device->sync_types[1] = &device->timeline_type.sync;
device->sync_types[2] = NULL;
device->heap.size = tu_get_system_heap_size();
device->heap.used = 0u;
device->heap.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
result = tu_physical_device_init(device, instance);
if (result == VK_SUCCESS) {
*out = &device->vk;
return result;
}
fail:
if (device)
vk_free(&instance->vk.alloc, device);
close(fd);
if (master_fd != -1)
close(master_fd);
return result;
}

View file

@ -222,81 +222,6 @@ get_kgsl_prop(int fd, unsigned int type, void *value, size_t size)
return safe_ioctl(fd, IOCTL_KGSL_DEVICE_GETPROPERTY, &getprop);
}
VkResult
tu_enumerate_devices(struct vk_instance *vk_instance)
{
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);
if (!device) {
close(fd);
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
struct kgsl_devinfo info;
if (get_kgsl_prop(fd, KGSL_PROP_DEVICE_INFO, &info, sizeof(info)))
goto fail;
uint64_t gmem_iova;
if (get_kgsl_prop(fd, KGSL_PROP_UCHE_GMEM_VADDR, &gmem_iova, sizeof(gmem_iova)))
goto fail;
/* 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;
device->dev_id.gpu_id =
((info.chip_id >> 24) & 0xff) * 100 +
((info.chip_id >> 16) & 0xff) * 10 +
((info.chip_id >> 8) & 0xff);
device->dev_id.chip_id = info.chip_id;
device->gmem_size = debug_get_num_option("TU_GMEM", info.gmem_sizebytes);
device->gmem_base = gmem_iova;
device->submitqueue_priority_count = 1;
device->heap.size = tu_get_system_heap_size();
device->heap.used = 0u;
device->heap.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
if (tu_physical_device_init(device, instance) != VK_SUCCESS)
goto fail;
list_addtail(&device->vk.link, &instance->vk.physical_devices.list);
return VK_SUCCESS;
fail:
vk_free(&instance->vk.alloc, device);
close(fd);
return VK_ERROR_INITIALIZATION_FAILED;
}
static int
timestamp_to_fd(struct tu_queue *queue, uint32_t timestamp)
{
@ -831,3 +756,79 @@ tu_QueueSignalReleaseImageANDROID(VkQueue _queue,
return VK_SUCCESS;
}
#endif
VkResult
tu_enumerate_devices(struct vk_instance *vk_instance)
{
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);
if (!device) {
close(fd);
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
struct kgsl_devinfo info;
if (get_kgsl_prop(fd, KGSL_PROP_DEVICE_INFO, &info, sizeof(info)))
goto fail;
uint64_t gmem_iova;
if (get_kgsl_prop(fd, KGSL_PROP_UCHE_GMEM_VADDR, &gmem_iova, sizeof(gmem_iova)))
goto fail;
/* 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;
device->dev_id.gpu_id =
((info.chip_id >> 24) & 0xff) * 100 +
((info.chip_id >> 16) & 0xff) * 10 +
((info.chip_id >> 8) & 0xff);
device->dev_id.chip_id = info.chip_id;
device->gmem_size = debug_get_num_option("TU_GMEM", info.gmem_sizebytes);
device->gmem_base = gmem_iova;
device->submitqueue_priority_count = 1;
device->heap.size = tu_get_system_heap_size();
device->heap.used = 0u;
device->heap.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
if (tu_physical_device_init(device, instance) != VK_SUCCESS)
goto fail;
list_addtail(&device->vk.link, &instance->vk.physical_devices.list);
return VK_SUCCESS;
fail:
vk_free(&instance->vk.alloc, device);
close(fd);
return VK_ERROR_INITIALIZATION_FAILED;
}