1 /* 2 * Copyright 2022 Google 3 * SPDX-License-Identifier: MIT 4 */ 5 #ifndef VIRTGPU_DEVICE_H 6 #define VIRTGPU_DEVICE_H 7 8 #include <cstdint> 9 #include <memory> 10 11 #include "virtgpu_gfxstream_protocol.h" 12 13 // See virgl_hw.h and p_defines.h 14 #define VIRGL_FORMAT_B8G8R8A8_UNORM 1 15 #define VIRGL_FORMAT_B5G6R5_UNORM 7 16 #define VIRGL_FORMAT_R10G10B10A2_UNORM 8 17 #define VIRGL_FORMAT_R8_UNORM 64 18 #define VIRGL_FORMAT_R8G8B8_UNORM 66 19 #define VIRGL_FORMAT_R8G8B8A8_UNORM 67 20 #define VIRGL_FORMAT_R16G16B16A16_FLOAT 94 21 #define VIRGL_FORMAT_YV12 163 22 #define VIRGL_FORMAT_YV16 164 23 #define VIRGL_FORMAT_IYUV 165 24 #define VIRGL_FORMAT_NV12 166 25 #define VIRGL_FORMAT_NV21 167 26 27 #define VIRGL_BIND_RENDER_TARGET (1 << 1) 28 #define VIRGL_BIND_CUSTOM (1 << 17) 29 #define VIRGL_BIND_LINEAR (1 << 22) 30 31 #define PIPE_BUFFER 0 32 #define PIPE_TEXTURE_2D 2 33 34 enum VirtGpuParamId : uint32_t { 35 kParam3D = 0, 36 kParamCapsetFix = 1, 37 kParamResourceBlob = 2, 38 kParamHostVisible = 3, 39 kParamCrossDevice = 4, 40 kParamContextInit = 5, 41 kParamSupportedCapsetIds = 6, 42 kParamExplicitDebugName = 7, 43 // Experimental, not in upstream Linux 44 kParamFencePassing = 8, 45 kParamCreateGuestHandle = 9, 46 kParamMax = 10, 47 }; 48 49 enum VirtGpuExecBufferFlags : uint32_t { 50 kFenceIn = 0x0001, 51 kFenceOut = 0x0002, 52 kRingIdx = 0x0004, 53 kShareableIn = 0x0008, 54 kShareableOut = 0x0010, 55 }; 56 57 enum VirtGpuCapset { 58 kCapsetNone = 0, 59 kCapsetVirgl = 1, 60 kCapsetVirgl2 = 2, 61 kCapsetGfxStreamVulkan = 3, 62 kCapsetVenus = 4, 63 kCapsetCrossDomain = 5, 64 kCapsetDrm = 6, 65 kCapsetGfxStreamMagma = 7, 66 kCapsetGfxStreamGles = 8, 67 kCapsetGfxStreamComposer = 9, 68 }; 69 70 // Try to keep aligned with vulkan-cereal / rutabaga. 71 enum VirtGpuHandleType { 72 kMemHandleOpaqueFd = 0x0001, 73 kMemHandleDmabuf = 0x0002, 74 kMemHandleOpaqueWin32 = 0x0003, 75 kMemHandleShm = 0x0004, 76 kMemHandleZircon = 0x0008, 77 kFenceHandleOpaqueFd = 0x0010, 78 kFenceHandleSyncFd = 0x0020, 79 kFenceHandleOpaqueWin32 = 0x0040, 80 kFenceHandleZircon = 0x0080, 81 }; 82 83 enum VirtGpuResourceFlags : uint32_t { 84 kBlobFlagMappable = 0x0001, 85 kBlobFlagShareable = 0x0002, 86 kBlobFlagCrossDevice = 0x0004, 87 kBlobFlagCreateGuestHandle = 0x0008, 88 }; 89 90 enum VirtGpuResourceMem { 91 kBlobMemGuest = 0x0001, 92 kBlobMemHost3d = 0x0002, 93 kBlobMemHost3dGuest = 0x0003, 94 }; 95 96 struct VirtGpuExternalHandle { 97 int64_t osHandle; 98 enum VirtGpuHandleType type; 99 }; 100 101 struct VirtGpuExecBuffer { 102 void* command; 103 uint32_t command_size; 104 uint32_t ring_idx; 105 enum VirtGpuExecBufferFlags flags; 106 struct VirtGpuExternalHandle handle; 107 }; 108 109 struct VirtGpuParam { 110 uint64_t param; 111 const char* name; 112 uint64_t value; 113 }; 114 115 struct VirtGpuCreateBlob { 116 uint64_t size; 117 enum VirtGpuResourceFlags flags; 118 enum VirtGpuResourceMem blobMem; 119 uint64_t blobId; 120 121 uint8_t* blobCmd; 122 uint32_t blobCmdSize; 123 }; 124 125 struct VirtGpuCaps { 126 uint64_t params[kParamMax]; 127 struct vulkanCapset vulkanCapset; 128 struct magmaCapset magmaCapset; 129 struct glesCapset glesCapset; 130 struct composerCapset composerCapset; 131 }; 132 133 #define INVALID_DESCRIPTOR -1 134 135 class VirtGpuResourceMapping; 136 class VirtGpuResource; 137 using VirtGpuResourcePtr = std::shared_ptr<VirtGpuResource>; 138 using VirtGpuResourceMappingPtr = std::shared_ptr<VirtGpuResourceMapping>; 139 140 class VirtGpuResource { 141 public: ~VirtGpuResource()142 virtual ~VirtGpuResource() {} 143 144 // The `intoRaw()` function drops ownerships of the OS-handle underlying 145 // the resource. It is the responsibility of the caller to manage lifetimes 146 // of the virtio-gpu resource. This function is mostly for gfxstream EGL 147 // compatibility and shouldn't be used elsewhere. intoRaw()148 virtual void intoRaw(){}; 149 150 virtual uint32_t getResourceHandle() const = 0; 151 virtual uint32_t getBlobHandle() const = 0; 152 virtual uint64_t getSize() const = 0; 153 virtual int wait() = 0; 154 155 virtual VirtGpuResourceMappingPtr createMapping(void) = 0; 156 virtual int exportBlob(struct VirtGpuExternalHandle& handle) = 0; 157 158 virtual int transferFromHost(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0; transferFromHost(uint32_t offset,uint32_t size)159 virtual int transferFromHost(uint32_t offset, uint32_t size) { 160 return transferFromHost(offset, 0, size, 1); 161 } 162 163 virtual int transferToHost(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0; transferToHost(uint32_t offset,uint32_t size)164 virtual int transferToHost(uint32_t offset, uint32_t size) { 165 return transferToHost(offset, 0, size, 1); 166 } 167 }; 168 169 class VirtGpuResourceMapping { 170 public: ~VirtGpuResourceMapping(void)171 virtual ~VirtGpuResourceMapping(void) {} 172 173 virtual uint8_t* asRawPtr(void) = 0; 174 }; 175 176 class VirtGpuDevice { 177 public: 178 static VirtGpuDevice* getInstance(enum VirtGpuCapset capset = kCapsetNone, 179 int32_t descriptor = INVALID_DESCRIPTOR); 180 static void resetInstance(); 181 VirtGpuDevice(enum VirtGpuCapset capset)182 VirtGpuDevice(enum VirtGpuCapset capset) : mCapset(capset) {} ~VirtGpuDevice()183 virtual ~VirtGpuDevice() {} 184 capset()185 enum VirtGpuCapset capset() { return mCapset; } 186 187 virtual int64_t getDeviceHandle(void) = 0; 188 189 virtual struct VirtGpuCaps getCaps(void) = 0; 190 191 virtual VirtGpuResourcePtr createBlob(const struct VirtGpuCreateBlob& blobCreate) = 0; 192 virtual VirtGpuResourcePtr createResource(uint32_t width, uint32_t height, uint32_t stride, 193 uint32_t size, uint32_t virglFormat, uint32_t target, 194 uint32_t bind) = 0; 195 virtual VirtGpuResourcePtr importBlob(const struct VirtGpuExternalHandle& handle) = 0; 196 197 virtual int execBuffer(struct VirtGpuExecBuffer& execbuffer, const VirtGpuResource* blob) = 0; 198 199 private: 200 enum VirtGpuCapset mCapset; 201 }; 202 203 VirtGpuDevice* kumquatCreateVirtGpuDevice(enum VirtGpuCapset capset = kCapsetNone, int fd = -1); 204 VirtGpuDevice* osCreateVirtGpuDevice(enum VirtGpuCapset capset = kCapsetNone, int fd = -1); 205 206 VirtGpuDevice* createPlatformVirtGpuDevice(enum VirtGpuCapset capset = kCapsetNone, int fd = -1); 207 208 // HACK: We can use gfxstream::guest::EnumFlags, but we'll have to do more guest 209 // refactorings to figure out our end goal. We can either depend more on base or 210 // try to transition to something else (b:202552093) [atleast for guests]. 211 constexpr enum VirtGpuResourceFlags operator|(const enum VirtGpuResourceFlags self, 212 const enum VirtGpuResourceFlags other) { 213 return (enum VirtGpuResourceFlags)(uint32_t(self) | uint32_t(other)); 214 } 215 216 constexpr enum VirtGpuExecBufferFlags operator |(const enum VirtGpuExecBufferFlags self, 217 const enum VirtGpuExecBufferFlags other) { 218 return (enum VirtGpuExecBufferFlags)(uint32_t(self) | uint32_t(other)); 219 } 220 221 #endif 222