• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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