1 /*
2 * Copyright 2021 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include <errno.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <xf86drm.h>
13
14 #include "drv_priv.h"
15 #include "external/virtgpu_drm.h"
16 #include "helpers.h"
17 #include "util.h"
18 #include "virtgpu.h"
19
20 #define PARAM(x) \
21 (struct virtgpu_param) \
22 { \
23 x, #x, 0 \
24 }
25
26 struct virtgpu_param params[] = {
27 PARAM(VIRTGPU_PARAM_3D_FEATURES), PARAM(VIRTGPU_PARAM_CAPSET_QUERY_FIX),
28 PARAM(VIRTGPU_PARAM_RESOURCE_BLOB), PARAM(VIRTGPU_PARAM_HOST_VISIBLE),
29 PARAM(VIRTGPU_PARAM_CROSS_DEVICE), PARAM(VIRTGPU_PARAM_CONTEXT_INIT),
30 PARAM(VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs), PARAM(VIRTGPU_PARAM_CREATE_GUEST_HANDLE),
31 PARAM(VIRTGPU_PARAM_RESOURCE_SYNC), PARAM(VIRTGPU_PARAM_GUEST_VRAM),
32 };
33
34 extern const struct backend virtgpu_virgl;
35 extern const struct backend virtgpu_cross_domain;
36
virtgpu_init(struct driver * drv)37 static int virtgpu_init(struct driver *drv)
38 {
39 int ret = 0;
40 const struct backend *virtgpu_backends[2] = {
41 &virtgpu_cross_domain,
42 &virtgpu_virgl,
43 };
44
45 for (uint32_t i = 0; i < ARRAY_SIZE(params); i++) {
46 struct drm_virtgpu_getparam get_param = { 0 };
47
48 get_param.param = params[i].param;
49 get_param.value = (uint64_t)(uintptr_t)¶ms[i].value;
50 int ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &get_param);
51 if (ret)
52 drv_log("DRM_IOCTL_VIRTGPU_GET_PARAM failed with %s\n", strerror(errno));
53 }
54
55 for (uint32_t i = 0; i < ARRAY_SIZE(virtgpu_backends); i++) {
56 const struct backend *backend = virtgpu_backends[i];
57 ret = backend->init(drv);
58 if (ret)
59 continue;
60
61 drv->backend = backend;
62 return 0;
63 }
64
65 return ret;
66 }
67
68 const struct backend backend_virtgpu = {
69 .name = "virtio_gpu",
70 .init = virtgpu_init,
71 };
72