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);