tu: Add virtgpu support

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23533>
This commit is contained in:
Rob Clark 2023-05-03 11:02:06 -07:00 committed by Marge Bot
parent 006342be8b
commit f17c5297d7
6 changed files with 1664 additions and 8 deletions

View file

@ -39,6 +39,13 @@ libtu_files = files(
'tu_util.cc', 'tu_util.cc',
) )
libtu_includes = [
inc_include,
inc_src,
inc_compiler,
inc_freedreno,
]
tu_deps = [] tu_deps = []
tu_flags = [] tu_flags = []
@ -82,6 +89,13 @@ if freedreno_kmds.contains('msm')
tu_deps += dep_libdrm tu_deps += dep_libdrm
endif endif
if freedreno_kmds.contains('virtio')
tu_flags += '-DTU_HAS_VIRTIO'
libtu_files += files('tu_knl_drm_virtio.cc', 'tu_knl_drm.cc')
libtu_includes += inc_virtio_gpu
tu_deps += dep_libdrm
endif
tu_tracepoints = custom_target( tu_tracepoints = custom_target(
'tu_tracepoints.[ch]', 'tu_tracepoints.[ch]',
input: 'tu_tracepoints.py', input: 'tu_tracepoints.py',
@ -134,12 +148,7 @@ endif
libvulkan_freedreno = shared_library( libvulkan_freedreno = shared_library(
'vulkan_freedreno', 'vulkan_freedreno',
[libtu_files, tu_entrypoints, tu_tracepoints, freedreno_xml_header_files, sha1_h, u_format_pack_h], [libtu_files, tu_entrypoints, tu_tracepoints, freedreno_xml_header_files, sha1_h, u_format_pack_h],
include_directories : [ include_directories : libtu_includes,
inc_include,
inc_src,
inc_compiler,
inc_freedreno,
],
link_with : [ link_with : [
libfreedreno_ir3, libfreedreno_ir3,
libfreedreno_layout, libfreedreno_layout,

View file

@ -1579,6 +1579,7 @@ tu_queue_init(struct tu_device *device,
return result; return result;
queue->device = device; queue->device = device;
queue->priority = priority;
queue->vk.driver_submit = tu_queue_submit; queue->vk.driver_submit = tu_queue_submit;
int ret = tu_drm_submitqueue_new(device, priority, &queue->msm_queue_id); int ret = tu_drm_submitqueue_new(device, priority, &queue->msm_queue_id);

View file

@ -153,6 +153,7 @@ struct tu_queue
struct tu_device *device; struct tu_device *device;
uint32_t msm_queue_id; uint32_t msm_queue_id;
uint32_t priority;
int fence; /* timestamp/fence of the last queue submission */ int fence; /* timestamp/fence of the last queue submission */
}; };
@ -201,6 +202,9 @@ struct tu6_global
volatile uint32_t breadcrumb_cpu_sync_seqno; volatile uint32_t breadcrumb_cpu_sync_seqno;
uint32_t _pad4; uint32_t _pad4;
volatile uint32_t userspace_fence;
uint32_t _pad5;
/* note: larger global bo will be used for customBorderColors */ /* note: larger global bo will be used for customBorderColors */
struct bcolor_entry bcolor_builtin[TU_BORDER_COLOR_BUILTIN], bcolor[]; struct bcolor_entry bcolor_builtin[TU_BORDER_COLOR_BUILTIN], bcolor[];
}; };
@ -224,6 +228,8 @@ enum tu_gralloc_type
}; };
#endif #endif
struct tu_virtio_device;
struct tu_device struct tu_device
{ {
struct vk_device vk; struct vk_device vk;
@ -349,6 +355,10 @@ struct tu_device
enum tu_gralloc_type gralloc_type; enum tu_gralloc_type gralloc_type;
#endif #endif
#ifdef TU_HAS_VIRTIO
struct tu_virtio_device *vdev;
#endif
uint32_t submit_count; uint32_t submit_count;
/* Address space and global fault count for this local_fd with DRM backend */ /* Address space and global fault count for this local_fd with DRM backend */

View file

@ -173,8 +173,10 @@ tu_physical_device_try_create(struct vk_instance *vk_instance,
struct tu_instance *instance = struct tu_instance *instance =
container_of(vk_instance, struct tu_instance, vk); container_of(vk_instance, struct tu_instance, vk);
if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)) || /* Note that "msm" is a platform device, but "virtio_gpu" is a pci
drm_device->bustype != DRM_BUS_PLATFORM) * device. In general we shouldn't care about the bus type.
*/
if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)))
return VK_ERROR_INCOMPATIBLE_DRIVER; return VK_ERROR_INCOMPATIBLE_DRIVER;
const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY]; const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];
@ -203,6 +205,10 @@ tu_physical_device_try_create(struct vk_instance *vk_instance,
if (strcmp(version->name, "msm") == 0) { if (strcmp(version->name, "msm") == 0) {
#ifdef TU_HAS_MSM #ifdef TU_HAS_MSM
result = tu_knl_drm_msm_load(instance, fd, version, &device); result = tu_knl_drm_msm_load(instance, fd, version, &device);
#endif
} else if (strcmp(version->name, "virtio_gpu") == 0) {
#ifdef TU_HAS_VIRTIO
result = tu_knl_drm_virtio_load(instance, fd, version, &device);
#endif #endif
} else { } else {
result = vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, result = vk_startup_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,

View file

@ -40,6 +40,14 @@ enum tu_timeline_sync_state {
struct tu_bo { struct tu_bo {
uint32_t gem_handle; uint32_t gem_handle;
#ifdef TU_HAS_VIRTIO
/* Between the guest UMD and host native-ctx shim/proxy, guest kernel
* assigned res_id is used instead of host gem handle. This allows
* the guest to run ahead of the host without having to wait for
* response from the host when buffers are allocated.
*/
uint32_t res_id;
#endif
uint64_t size; uint64_t size;
uint64_t iova; uint64_t iova;
void *map; void *map;
@ -81,6 +89,9 @@ struct tu_knl {
struct tu_zombie_vma { struct tu_zombie_vma {
int fence; int fence;
uint32_t gem_handle; uint32_t gem_handle;
#ifdef TU_HAS_VIRTIO
uint32_t res_id;
#endif
uint64_t iova; uint64_t iova;
uint64_t size; uint64_t size;
}; };
@ -105,6 +116,8 @@ static inline VkResult
tu_bo_init_new(struct tu_device *dev, struct tu_bo **out_bo, uint64_t size, tu_bo_init_new(struct tu_device *dev, struct tu_bo **out_bo, uint64_t size,
enum tu_bo_alloc_flags flags, const char *name) enum tu_bo_alloc_flags flags, const char *name)
{ {
// TODO don't mark everything with HOST_VISIBLE !!! Anything that
// never gets CPU access should not have this bit set
return tu_bo_init_new_explicit_iova( return tu_bo_init_new_explicit_iova(
dev, out_bo, size, 0, dev, out_bo, size, 0,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
@ -143,6 +156,9 @@ struct _drmVersion;
VkResult tu_knl_drm_msm_load(struct tu_instance *instance, VkResult tu_knl_drm_msm_load(struct tu_instance *instance,
int fd, struct _drmVersion *version, int fd, struct _drmVersion *version,
struct tu_physical_device **out); struct tu_physical_device **out);
VkResult tu_knl_drm_virtio_load(struct tu_instance *instance,
int fd, struct _drmVersion *version,
struct tu_physical_device **out);
VkResult VkResult
tu_enumerate_devices(struct vk_instance *vk_instance); tu_enumerate_devices(struct vk_instance *vk_instance);

File diff suppressed because it is too large Load diff