1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef VIRTGPU_DEVICE_H 17 #define VIRTGPU_DEVICE_H 18 19 #include <cstdint> 20 #include <memory> 21 22 #include "virtgpu_gfxstream_protocol.h" 23 24 enum VirtGpuParamId : uint32_t { 25 kParam3D = 0, 26 kParamCapsetFix = 1, 27 kParamResourceBlob = 2, 28 kParamHostVisible = 3, 29 kParamCrossDevice = 4, 30 kParamContextInit = 5, 31 kParamSupportedCapsetIds = 6, 32 kParamCreateGuestHandle = 7, 33 kParamMax = 8, 34 }; 35 36 enum VirtGpuExecBufferFlags : uint32_t { 37 kFenceIn = 0x0001, 38 kFenceOut = 0x0002, 39 kRingIdx = 0x0004, 40 }; 41 42 enum VirtGpuCapset { 43 kCapsetNone = 0, 44 kCapsetVirgl = 1, 45 kCapsetVirgl2 = 2, 46 kCapsetGfxStream = 3, 47 kCapsetVenus = 4, 48 kCapsetCrossDomain = 5, 49 }; 50 51 // Try to keep aligned with vulkan-cereal / rutabaga. 52 enum VirtGpuHandleType { 53 kMemHandleOpaqueFd = 0x0001, 54 kMemHandleDmabuf = 0x0002, 55 kMemHandleOpaqueWin32 = 0x0003, 56 kMemHandleShm = 0x0004, 57 kMemHandleZircon = 0x0008, 58 kFenceHandleOpaqueFd = 0x0010, 59 kFenceHandleSyncFd = 0x0020, 60 kFenceHandleOpaqueWin32 = 0x0040, 61 kFenceHandleZircon = 0x0080, 62 }; 63 64 enum VirtGpuBlobFlags : uint32_t { 65 kBlobFlagMappable = 0x0001, 66 kBlobFlagShareable = 0x0002, 67 kBlobFlagCrossDevice = 0x0004, 68 kBlobFlagCreateGuestHandle = 0x0008, 69 }; 70 71 enum VirtGpuBlobMem { 72 kBlobMemGuest = 0x0001, 73 kBlobMemHost3d = 0x0002, 74 kBlobMemHost3dGuest = 0x0003, 75 }; 76 77 struct VirtGpuExternalHandle { 78 int64_t osHandle; 79 enum VirtGpuHandleType type; 80 }; 81 82 struct VirtGpuExecBuffer { 83 void* command; 84 uint32_t command_size; 85 uint32_t ring_idx; 86 enum VirtGpuExecBufferFlags flags; 87 struct VirtGpuExternalHandle handle; 88 }; 89 90 struct VirtGpuParam { 91 uint64_t param; 92 const char* name; 93 uint64_t value; 94 }; 95 96 struct VirtGpuCreateBlob { 97 uint64_t size; 98 enum VirtGpuBlobFlags flags; 99 enum VirtGpuBlobMem blobMem; 100 uint64_t blobId; 101 }; 102 103 struct VirtGpuCaps { 104 uint64_t params[kParamMax]; 105 struct gfxstreamCapset gfxstreamCapset; 106 }; 107 108 class VirtGpuBlobMapping; 109 class VirtGpuBlob; 110 using VirtGpuBlobPtr = std::shared_ptr<VirtGpuBlob>; 111 using VirtGpuBlobMappingPtr = std::shared_ptr<VirtGpuBlobMapping>; 112 113 class VirtGpuBlob : public std::enable_shared_from_this<VirtGpuBlob> { 114 public: 115 VirtGpuBlob(int64_t deviceHandle, uint32_t blobHandle, uint32_t resourceHandle, uint64_t size); 116 ~VirtGpuBlob(); 117 118 uint32_t getResourceHandle(void); 119 uint32_t getBlobHandle(void); 120 int wait(void); 121 122 VirtGpuBlobMappingPtr createMapping(void); 123 int exportBlob(struct VirtGpuExternalHandle& handle); 124 125 private: 126 // Not owned. Really should use a ScopedFD for this, but doesn't matter since we have a 127 // singleton deviceimplemenentation anyways. 128 int64_t mDeviceHandle; 129 130 uint32_t mBlobHandle; 131 uint32_t mResourceHandle; 132 uint64_t mSize; 133 }; 134 135 class VirtGpuBlobMapping { 136 public: 137 VirtGpuBlobMapping(VirtGpuBlobPtr blob, uint8_t* ptr, uint64_t size); 138 ~VirtGpuBlobMapping(void); 139 140 uint8_t* asRawPtr(void); 141 142 private: 143 VirtGpuBlobPtr mBlob; 144 uint8_t* mPtr; 145 uint64_t mSize; 146 }; 147 148 class VirtGpuDevice { 149 public: 150 static VirtGpuDevice& getInstance(enum VirtGpuCapset capset = kCapsetNone); 151 int64_t getDeviceHandle(void); 152 153 struct VirtGpuCaps getCaps(void); 154 155 VirtGpuBlobPtr createBlob(const struct VirtGpuCreateBlob& blobCreate); 156 VirtGpuBlobPtr createPipeBlob(uint32_t size); 157 VirtGpuBlobPtr importBlob(const struct VirtGpuExternalHandle& handle); 158 159 int execBuffer(struct VirtGpuExecBuffer& execbuffer, VirtGpuBlobPtr blob); 160 161 private: 162 VirtGpuDevice(enum VirtGpuCapset capset); 163 ~VirtGpuDevice(); 164 VirtGpuDevice(VirtGpuDevice const&); 165 void operator=(VirtGpuDevice const&); 166 167 static VirtGpuDevice mInstance; 168 int64_t mDeviceHandle; 169 170 struct VirtGpuCaps mCaps; 171 }; 172 173 // HACK: We can use android::base::EnumFlags, but we'll have to do more guest 174 // refactorings to figure out our end goal. We can either depend more on base or 175 // try to transition to something else (b:202552093) [atleast for guests]. 176 constexpr enum VirtGpuBlobFlags operator |(const enum VirtGpuBlobFlags self, 177 const enum VirtGpuBlobFlags other) { 178 return (enum VirtGpuBlobFlags)(uint32_t(self) | uint32_t(other)); 179 } 180 181 constexpr enum VirtGpuExecBufferFlags operator |(const enum VirtGpuExecBufferFlags self, 182 const enum VirtGpuExecBufferFlags other) { 183 return (enum VirtGpuExecBufferFlags)(uint32_t(self) | uint32_t(other)); 184 } 185 186 #endif 187