This change provides a route to the host side "cross domain" allocator, which is specialized for resource sharing across domain boundaries. It uses the upcoming CONTEXT_INIT ioctl to initialize the backend when available, and multiple timelines to perform metadata queries. While it would be awesome to use the revolutionary Address Space Graphics (ASG) algorithm for metadata queries, it would be non-trivial to pull off in minigbm. Key aspects of the cross-domain allocator are: * Intelligently falls back to OpenGL texture allocation host-side when external memory is not available. The fallback path is named "virgl", even though it encompasses gfxstream and 2D mode. More refactorings will be added in the future for further clarity. * Uses host Vulkan or minigbm to perform metadata query, and uses a cache to minimize vmexits. * No shadow memory. Only zero-copy blobs will be supported if the blob is mappable. Shareable blobs may be compressed or tiled if not mappable. * A commitment to sharing code across Google projects and cross-platform GPU virtualization. The main goal here is to enable faster interation/testing, so this code is just a prototype. It should be fine to merge via minigbm, since the project has a very chill philosophy and even proudly accepts code that doesn't make any sense (crrev.com/c/2583188) [so long as existing users are not broken]. BUG=b:173630595 TEST=launch virtual machine with 2D mode TEST=launch virtual machine with 3D mode Change-Id: Ie33a46f19e5cdd82a2ac03bcf2351f4a8f294970 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2691716 Reviewed-by: Lingfeng Yang <lfy@google.com> Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org> Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
70 lines
2 KiB
C
70 lines
2 KiB
C
/*
|
|
* Copyright 2021 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <xf86drm.h>
|
|
|
|
#include "drv_priv.h"
|
|
#include "external/virtgpu_drm.h"
|
|
#include "helpers.h"
|
|
#include "util.h"
|
|
#include "virtgpu.h"
|
|
|
|
#define PARAM(x) \
|
|
(struct virtgpu_param) \
|
|
{ \
|
|
x, #x, 0 \
|
|
}
|
|
|
|
struct virtgpu_param params[] = {
|
|
PARAM(VIRTGPU_PARAM_3D_FEATURES), PARAM(VIRTGPU_PARAM_CAPSET_QUERY_FIX),
|
|
PARAM(VIRTGPU_PARAM_RESOURCE_BLOB), PARAM(VIRTGPU_PARAM_HOST_VISIBLE),
|
|
PARAM(VIRTGPU_PARAM_CROSS_DEVICE), PARAM(VIRTGPU_PARAM_CONTEXT_INIT),
|
|
PARAM(VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs),
|
|
};
|
|
|
|
extern const struct backend virtgpu_virgl;
|
|
extern const struct backend virtgpu_cross_domain;
|
|
|
|
static int virtgpu_init(struct driver *drv)
|
|
{
|
|
int ret = 0;
|
|
const struct backend *virtgpu_backends[2] = {
|
|
&virtgpu_cross_domain,
|
|
&virtgpu_virgl,
|
|
};
|
|
|
|
for (uint32_t i = 0; i < ARRAY_SIZE(params); i++) {
|
|
struct drm_virtgpu_getparam get_param = { 0 };
|
|
|
|
get_param.param = params[i].param;
|
|
get_param.value = (uint64_t)(uintptr_t)¶ms[i].value;
|
|
int ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &get_param);
|
|
if (ret)
|
|
drv_log("DRM_IOCTL_VIRTGPU_GET_PARAM failed with %s\n", strerror(errno));
|
|
}
|
|
|
|
for (uint32_t i = 0; i < ARRAY_SIZE(virtgpu_backends); i++) {
|
|
const struct backend *backend = virtgpu_backends[i];
|
|
ret = backend->init(drv);
|
|
if (ret)
|
|
continue;
|
|
|
|
drv->backend = backend;
|
|
return 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
const struct backend backend_virtgpu = {
|
|
.name = "virtio_gpu",
|
|
.init = virtgpu_init,
|
|
};
|