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 // See virgl_hw.h and p_defines.h 25 #define VIRGL_FORMAT_R8_UNORM 64 26 #define VIRGL_FORMAT_B8G8R8A8_UNORM 1 27 #define VIRGL_FORMAT_B5G6R5_UNORM 7 28 #define VIRGL_FORMAT_R8G8B8_UNORM 66 29 #define VIRGL_FORMAT_R8G8B8A8_UNORM 67 30 31 #define VIRGL_BIND_RENDER_TARGET (1 << 1) 32 #define VIRGL_BIND_CUSTOM (1 << 17) 33 #define PIPE_BUFFER 0 34 #define PIPE_TEXTURE_2D 2 35 36 enum VirtGpuParamId : uint32_t { 37 kParam3D = 0, 38 kParamCapsetFix = 1, 39 kParamResourceBlob = 2, 40 kParamHostVisible = 3, 41 kParamCrossDevice = 4, 42 kParamContextInit = 5, 43 kParamSupportedCapsetIds = 6, 44 kParamExplicitDebugName = 7, 45 kParamCreateGuestHandle = 8, 46 kParamMax = 9, 47 }; 48 49 enum VirtGpuExecBufferFlags : uint32_t { 50 kFenceIn = 0x0001, 51 kFenceOut = 0x0002, 52 kRingIdx = 0x0004, 53 }; 54 55 enum VirtGpuCapset { 56 kCapsetNone = 0, 57 kCapsetVirgl = 1, 58 kCapsetVirgl2 = 2, 59 kCapsetGfxStreamVulkan = 3, 60 kCapsetVenus = 4, 61 kCapsetCrossDomain = 5, 62 kCapsetDrm = 6, 63 kCapsetGfxStreamMagma = 7, 64 kCapsetGfxStreamGles = 8, 65 kCapsetGfxStreamComposer = 9, 66 }; 67 68 // Try to keep aligned with vulkan-cereal / rutabaga. 69 enum VirtGpuHandleType { 70 kMemHandleOpaqueFd = 0x0001, 71 kMemHandleDmabuf = 0x0002, 72 kMemHandleOpaqueWin32 = 0x0003, 73 kMemHandleShm = 0x0004, 74 kMemHandleZircon = 0x0008, 75 kFenceHandleOpaqueFd = 0x0010, 76 kFenceHandleSyncFd = 0x0020, 77 kFenceHandleOpaqueWin32 = 0x0040, 78 kFenceHandleZircon = 0x0080, 79 }; 80 81 enum VirtGpuBlobFlags : uint32_t { 82 kBlobFlagMappable = 0x0001, 83 kBlobFlagShareable = 0x0002, 84 kBlobFlagCrossDevice = 0x0004, 85 kBlobFlagCreateGuestHandle = 0x0008, 86 }; 87 88 enum VirtGpuBlobMem { 89 kBlobMemGuest = 0x0001, 90 kBlobMemHost3d = 0x0002, 91 kBlobMemHost3dGuest = 0x0003, 92 }; 93 94 struct VirtGpuExternalHandle { 95 int64_t osHandle; 96 enum VirtGpuHandleType type; 97 }; 98 99 struct VirtGpuExecBuffer { 100 void* command; 101 uint32_t command_size; 102 uint32_t ring_idx; 103 enum VirtGpuExecBufferFlags flags; 104 struct VirtGpuExternalHandle handle; 105 }; 106 107 struct VirtGpuParam { 108 uint64_t param; 109 const char* name; 110 uint64_t value; 111 }; 112 113 struct VirtGpuCreateBlob { 114 uint64_t size; 115 enum VirtGpuBlobFlags flags; 116 enum VirtGpuBlobMem blobMem; 117 uint64_t blobId; 118 }; 119 120 struct VirtGpuCaps { 121 uint64_t params[kParamMax]; 122 struct vulkanCapset vulkanCapset; 123 struct magmaCapset magmaCapset; 124 struct glesCapset glesCapset; 125 struct composerCapset composerCapset; 126 }; 127 128 class VirtGpuBlobMapping; 129 class VirtGpuBlob; 130 using VirtGpuBlobPtr = std::shared_ptr<VirtGpuBlob>; 131 using VirtGpuBlobMappingPtr = std::shared_ptr<VirtGpuBlobMapping>; 132 133 class VirtGpuBlob { 134 public: ~VirtGpuBlob()135 virtual ~VirtGpuBlob() {} 136 137 virtual uint32_t getResourceHandle() const = 0; 138 virtual uint32_t getBlobHandle() const = 0; 139 virtual int wait() = 0; 140 141 virtual VirtGpuBlobMappingPtr createMapping(void) = 0; 142 virtual int exportBlob(struct VirtGpuExternalHandle& handle) = 0; 143 144 virtual int transferFromHost(uint32_t offset, uint32_t size) = 0; 145 virtual int transferToHost(uint32_t offset, uint32_t size) = 0; 146 }; 147 148 class VirtGpuBlobMapping { 149 public: ~VirtGpuBlobMapping(void)150 virtual ~VirtGpuBlobMapping(void) {} 151 152 virtual uint8_t* asRawPtr(void) = 0; 153 }; 154 155 class VirtGpuDevice { 156 public: 157 static VirtGpuDevice* getInstance(enum VirtGpuCapset capset = kCapsetNone); 158 static void resetInstance(); 159 160 static void setInstanceForTesting(VirtGpuDevice* device); 161 VirtGpuDevice(enum VirtGpuCapset capset)162 VirtGpuDevice(enum VirtGpuCapset capset) : mCapset(capset) {} ~VirtGpuDevice()163 virtual ~VirtGpuDevice() {} 164 capset()165 enum VirtGpuCapset capset() { return mCapset; } 166 167 virtual int64_t getDeviceHandle(void) = 0; 168 169 virtual struct VirtGpuCaps getCaps(void) = 0; 170 171 virtual VirtGpuBlobPtr createBlob(const struct VirtGpuCreateBlob& blobCreate) = 0; 172 virtual VirtGpuBlobPtr createVirglBlob(uint32_t width, uint32_t height, uint32_t virglFormat) = 0; 173 virtual VirtGpuBlobPtr importBlob(const struct VirtGpuExternalHandle& handle) = 0; 174 175 virtual int execBuffer(struct VirtGpuExecBuffer& execbuffer, const VirtGpuBlob* blob) = 0; 176 177 private: 178 enum VirtGpuCapset mCapset; 179 }; 180 181 VirtGpuDevice* createPlatformVirtGpuDevice(enum VirtGpuCapset capset = kCapsetNone, int fd = -1); 182 183 // HACK: We can use gfxstream::guest::EnumFlags, but we'll have to do more guest 184 // refactorings to figure out our end goal. We can either depend more on base or 185 // try to transition to something else (b:202552093) [atleast for guests]. 186 constexpr enum VirtGpuBlobFlags operator |(const enum VirtGpuBlobFlags self, 187 const enum VirtGpuBlobFlags other) { 188 return (enum VirtGpuBlobFlags)(uint32_t(self) | uint32_t(other)); 189 } 190 191 constexpr enum VirtGpuExecBufferFlags operator |(const enum VirtGpuExecBufferFlags self, 192 const enum VirtGpuExecBufferFlags other) { 193 return (enum VirtGpuExecBufferFlags)(uint32_t(self) | uint32_t(other)); 194 } 195 196 #endif 197