tu: Allow being preempted on a7xx
This is only tested on a7xx so far, although it should work on a6xx too. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30544>
This commit is contained in:
@@ -124,6 +124,8 @@ struct tu_physical_device
|
|||||||
bool has_cached_non_coherent_memory;
|
bool has_cached_non_coherent_memory;
|
||||||
uintptr_t level1_dcache_size;
|
uintptr_t level1_dcache_size;
|
||||||
|
|
||||||
|
bool has_preemption;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t type_count;
|
uint32_t type_count;
|
||||||
VkMemoryPropertyFlags types[VK_MAX_MEMORY_TYPES];
|
VkMemoryPropertyFlags types[VK_MAX_MEMORY_TYPES];
|
||||||
|
|||||||
@@ -121,6 +121,24 @@ tu_drm_get_va_prop(const struct tu_physical_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
tu_drm_has_preemption(const struct tu_physical_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_msm_submitqueue req = {
|
||||||
|
.flags = MSM_SUBMITQUEUE_ALLOW_PREEMPT,
|
||||||
|
.prio = dev->submitqueue_priority_count / 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
int ret = drmCommandWriteRead(dev->local_fd,
|
||||||
|
DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req));
|
||||||
|
if (ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
drmCommandWrite(dev->local_fd, DRM_MSM_SUBMITQUEUE_CLOSE, &req.id,
|
||||||
|
sizeof(req.id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
tu_drm_get_priorities(const struct tu_physical_device *dev)
|
tu_drm_get_priorities(const struct tu_physical_device *dev)
|
||||||
{
|
{
|
||||||
@@ -214,7 +232,9 @@ msm_submitqueue_new(struct tu_device *dev,
|
|||||||
assert(priority >= 0 &&
|
assert(priority >= 0 &&
|
||||||
priority < dev->physical_device->submitqueue_priority_count);
|
priority < dev->physical_device->submitqueue_priority_count);
|
||||||
struct drm_msm_submitqueue req = {
|
struct drm_msm_submitqueue req = {
|
||||||
.flags = 0,
|
.flags = dev->physical_device->info->chip >= 7 &&
|
||||||
|
dev->physical_device->has_preemption ?
|
||||||
|
MSM_SUBMITQUEUE_ALLOW_PREEMPT : 0,
|
||||||
.prio = priority,
|
.prio = priority,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1245,6 +1265,8 @@ tu_knl_drm_msm_load(struct tu_instance *instance,
|
|||||||
device->has_set_iova = !tu_drm_get_va_prop(device, &device->va_start,
|
device->has_set_iova = !tu_drm_get_va_prop(device, &device->va_start,
|
||||||
&device->va_size);
|
&device->va_size);
|
||||||
|
|
||||||
|
device->has_preemption = tu_drm_has_preemption(device);
|
||||||
|
|
||||||
/* Even if kernel is new enough, the GPU itself may not support it. */
|
/* Even if kernel is new enough, the GPU itself may not support it. */
|
||||||
device->has_cached_coherent_memory =
|
device->has_cached_coherent_memory =
|
||||||
(device->msm_minor_version >= 8) &&
|
(device->msm_minor_version >= 8) &&
|
||||||
|
|||||||
@@ -310,11 +310,13 @@ virtio_submitqueue_new(struct tu_device *dev,
|
|||||||
priority < dev->physical_device->submitqueue_priority_count);
|
priority < dev->physical_device->submitqueue_priority_count);
|
||||||
|
|
||||||
struct drm_msm_submitqueue req = {
|
struct drm_msm_submitqueue req = {
|
||||||
.flags = 0,
|
.flags = dev->physical_device->info->chip >= 7 &&
|
||||||
|
dev->physical_device->has_preemption ?
|
||||||
|
MSM_SUBMITQUEUE_ALLOW_PREEMPT : 0,
|
||||||
.prio = priority,
|
.prio = priority,
|
||||||
};
|
};
|
||||||
|
|
||||||
int ret = virtio_simple_ioctl(dev, DRM_IOCTL_MSM_SUBMITQUEUE_NEW, &req);
|
int ret = virtio_simple_ioctl(dev->vdev->vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_NEW, &req);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -328,6 +330,22 @@ virtio_submitqueue_close(struct tu_device *dev, uint32_t queue_id)
|
|||||||
virtio_simple_ioctl(dev->vdev->vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE, &queue_id);
|
virtio_simple_ioctl(dev->vdev->vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE, &queue_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
virtio_has_preemption(struct vdrm_device *vdrm)
|
||||||
|
{
|
||||||
|
struct drm_msm_submitqueue req = {
|
||||||
|
.flags = MSM_SUBMITQUEUE_ALLOW_PREEMPT,
|
||||||
|
.prio = vdrm->caps.u.msm.priorities / 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
int ret = virtio_simple_ioctl(vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_NEW, &req);
|
||||||
|
if (ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
virtio_simple_ioctl(vdrm, DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE, &req.id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static VkResult
|
static VkResult
|
||||||
tu_wait_fence(struct tu_device *dev,
|
tu_wait_fence(struct tu_device *dev,
|
||||||
uint32_t queue_id,
|
uint32_t queue_id,
|
||||||
@@ -1312,6 +1330,11 @@ tu_knl_drm_virtio_load(struct tu_instance *instance,
|
|||||||
|
|
||||||
caps = vdrm->caps;
|
caps = vdrm->caps;
|
||||||
|
|
||||||
|
/* TODO add something to virgl_renderer_capset_drm to avoid round-trip to
|
||||||
|
* host if virglrenderer is new enough.
|
||||||
|
*/
|
||||||
|
bool has_preemption = virtio_has_preemption(vdrm);
|
||||||
|
|
||||||
vdrm_device_close(vdrm);
|
vdrm_device_close(vdrm);
|
||||||
|
|
||||||
mesa_logd("wire_format_version: %u", caps.wire_format_version);
|
mesa_logd("wire_format_version: %u", caps.wire_format_version);
|
||||||
@@ -1367,6 +1390,7 @@ tu_knl_drm_virtio_load(struct tu_instance *instance,
|
|||||||
device->va_start = caps.u.msm.va_start;
|
device->va_start = caps.u.msm.va_start;
|
||||||
device->va_size = caps.u.msm.va_size;
|
device->va_size = caps.u.msm.va_size;
|
||||||
device->has_set_iova = true;
|
device->has_set_iova = true;
|
||||||
|
device->has_preemption = has_preemption;
|
||||||
|
|
||||||
device->gmem_size = debug_get_num_option("TU_GMEM", device->gmem_size);
|
device->gmem_size = debug_get_num_option("TU_GMEM", device->gmem_size);
|
||||||
|
|
||||||
|
|||||||
@@ -1596,6 +1596,9 @@ tu_knl_kgsl_load(struct tu_instance *instance, int fd)
|
|||||||
fd, KGSL_MEMFLAGS_IOCOHERENT |
|
fd, KGSL_MEMFLAGS_IOCOHERENT |
|
||||||
(KGSL_CACHEMODE_WRITEBACK << KGSL_CACHEMODE_SHIFT));
|
(KGSL_CACHEMODE_WRITEBACK << KGSL_CACHEMODE_SHIFT));
|
||||||
|
|
||||||
|
/* preemption is always supported on kgsl */
|
||||||
|
device->has_preemption = true;
|
||||||
|
|
||||||
instance->knl = &kgsl_knl_funcs;
|
instance->knl = &kgsl_knl_funcs;
|
||||||
|
|
||||||
result = tu_physical_device_init(device, instance);
|
result = tu_physical_device_init(device, instance);
|
||||||
|
|||||||
Reference in New Issue
Block a user