1#pragma once
2
3#include "virtgpu-utils.h"
4#include "virtgpu-shm.h"
5#include "virtgpu-apir.h"
6
7#include "backend/shared/api_remoting.h"
8#include "backend/shared/apir_cs.h"
9
10#include <fcntl.h>
11#include <stdbool.h>
12#include <stdio.h>
13#include <sys/stat.h>
14#include <sys/sysmacros.h>
15#include <threads.h>
16#include <xf86drm.h>
17
18#include <cstring>
19
20#include "ggml-remoting.h"
21
22#define VIRGL_RENDERER_UNSTABLE_APIS 1
23#include "apir_hw.h"
24#include <drm/virtgpu_drm.h>
25#include "venus_hw.h"
26
27#ifndef VIRTGPU_DRM_CAPSET_APIR
28// Will be defined include/drm/virtgpu_drm.h when
29// https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1590/diffs
30// is merged
31#define VIRTGPU_DRM_CAPSET_APIR 10
32#endif
33
34// Mesa/Virlgrenderer Venus internal. Only necessary during the
35// Venus->APIR transition in Virglrenderer
36#define VENUS_COMMAND_TYPE_LENGTH 331
37
38#ifndef VIRTGPU_DRM_CAPSET_VENUS // only available with Linux >= v6.16
39#define VIRTGPU_DRM_CAPSET_VENUS 4
40#endif
41
42typedef uint32_t virgl_renderer_capset;
43
44/* from src/virtio/vulkan/vn_renderer_virtgpu.c */
45#define VIRTGPU_PCI_VENDOR_ID 0x1af4
46#define VIRTGPU_PCI_DEVICE_ID 0x1050
47#define VIRTGPU_BLOB_MEM_GUEST_VRAM 0x0004
48#define VIRTGPU_PARAM_GUEST_VRAM 9
49
50#define SHMEM_DATA_SIZE 0x1830000 // 24MiB
51#define SHMEM_REPLY_SIZE 0x4000
52
53#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
54
55enum virt_gpu_result_t {
56 APIR_SUCCESS = 0,
57 APIR_ERROR_INITIALIZATION_FAILED = -1,
58};
59
60#define PRINTFLIKE(f, a) __attribute__((format(__printf__, f, a)))
61
62struct virtgpu {
63 bool use_apir_capset;
64
65 int fd;
66
67 struct {
68 virgl_renderer_capset id;
69 uint32_t version;
70 virgl_renderer_capset_apir data;
71 } capset;
72
73 util_sparse_array shmem_array;
74
75 /* APIR communication pages */
76 virtgpu_shmem reply_shmem;
77 virtgpu_shmem data_shmem;
78
79 /* Mutex to protect shared data_shmem buffer from concurrent access */
80 mtx_t data_shmem_mutex;
81
82 /* Cached device information to prevent memory leaks and race conditions */
83 struct {
84 char * description;
85 char * name;
86 int32_t device_count;
87 uint32_t type;
88 size_t memory_free;
89 size_t memory_total;
90 } cached_device_info;
91
92 /* Cached buffer type information to prevent memory leaks and race conditions */
93 struct {
94 apir_buffer_type_host_handle_t host_handle;
95 char * name;
96 size_t alignment;
97 size_t max_size;
98 } cached_buffer_type;
99};
100
101static inline int virtgpu_ioctl(virtgpu * gpu, unsigned long request, void * args) {
102 return drmIoctl(gpu->fd, request, args);
103}
104
105virtgpu * create_virtgpu();
106
107apir_encoder * remote_call_prepare(virtgpu * gpu, ApirCommandType apir_cmd_type, int32_t cmd_flags);
108
109uint32_t remote_call(virtgpu * gpu,
110 apir_encoder * enc,
111 apir_decoder ** dec,
112 float max_wait_ms,
113 long long * call_duration_ns);
114
115void remote_call_finish(virtgpu * gpu, apir_encoder * enc, apir_decoder * dec);