blob: 6bf976d2e0f66cce8f817e04c8ef375918f18ac5 [file] [log] [blame]
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef VIRTGPU_DEVICE_H
#define VIRTGPU_DEVICE_H
#include <cstdint>
#include <memory>
enum VirtGpuParamId {
kParam3D,
kParamCapsetFix,
kParamResourceBlob,
kParamHostVisible,
kParamCrossDevice,
kParamContextInit,
kParamSupportedCapsetIds,
kParamMax
};
enum VirtGpuExecBufferFlags : uint32_t {
kFenceIn = 0x0001,
kFenceOut = 0x0002,
kRingIdx = 0x0004,
};
enum VirtGpuCapset {
kCapsetNone = 0,
kCapsetVirgl = 1,
kCapsetVirgl2 = 2,
kCapsetGfxStream = 3,
kCapsetVenus = 4,
kCapsetCrossDomain = 5,
};
// Try to keep aligned with vulkan-cereal / rutabaga.
enum VirtGpuHandleType {
kMemHandleOpaqueFd = 0x0001,
kMemHandleDmabuf = 0x0002,
kMemHandleOpaqueWin32 = 0x0003,
kMemHandleShm = 0x0004,
kMemHandleZircon = 0x0008,
kFenceHandleOpaqueFd = 0x0010,
kFenceHandleSyncFd = 0x0020,
kFenceHandleOpaqueWin32 = 0x0040,
kFenceHandleZircon = 0x0080,
};
enum VirtGpuBlobFlags : uint32_t {
kBlobFlagMappable = 0x0001,
kBlobFlagShareable = 0x0002,
kBlobFlagCrossDevice = 0x0004
};
enum VirtGpuBlobMem {
kBlobMemGuest = 0x0001,
kBlobMemHost3d = 0x0002,
kBlobMemHost3dGuest = 0x0003,
};
struct VirtGpuExternalHandle {
int64_t osHandle;
enum VirtGpuHandleType type;
};
struct VirtGpuExecBuffer {
void* command;
uint32_t command_size;
enum VirtGpuExecBufferFlags flags;
struct VirtGpuExternalHandle handle;
};
struct VirtGpuParam {
uint64_t param;
const char* name;
uint64_t value;
};
struct VirtGpuCreateBlob {
uint64_t size;
enum VirtGpuBlobFlags flags;
enum VirtGpuBlobMem blobMem;
uint64_t blobId;
};
class VirtGpuBlobMapping;
class VirtGpuBlob;
using VirtGpuBlobPtr = std::shared_ptr<VirtGpuBlob>;
using VirtGpuBlobMappingPtr = std::shared_ptr<VirtGpuBlobMapping>;
class VirtGpuBlob : public std::enable_shared_from_this<VirtGpuBlob> {
public:
VirtGpuBlob(int64_t deviceHandle, uint32_t blobHandle, uint32_t resourceHandle, uint64_t size);
~VirtGpuBlob();
uint32_t getResourceHandle(void);
uint32_t getBlobHandle(void);
int wait(void);
VirtGpuBlobMappingPtr createMapping(void);
int exportBlob(struct VirtGpuExternalHandle& handle);
private:
// Not owned. Really should use a ScopedFD for this, but doesn't matter since we have a
// singleton deviceimplemenentation anyways.
int64_t mDeviceHandle;
uint32_t mBlobHandle;
uint32_t mResourceHandle;
uint64_t mSize;
};
class VirtGpuBlobMapping {
public:
VirtGpuBlobMapping(VirtGpuBlobPtr blob, uint8_t* ptr, uint64_t size);
~VirtGpuBlobMapping(void);
uint8_t* asRawPtr(void);
private:
VirtGpuBlobPtr mBlob;
uint8_t* mPtr;
uint64_t mSize;
};
class VirtGpuDevice {
public:
static VirtGpuDevice& getInstance(enum VirtGpuCapset capset = kCapsetNone);
int64_t getDeviceHandle(void);
uint64_t getParam(enum VirtGpuParamId param);
VirtGpuBlobPtr createBlob(const struct VirtGpuCreateBlob& blobCreate);
VirtGpuBlobPtr createPipeBlob(uint32_t size);
VirtGpuBlobPtr importBlob(const struct VirtGpuExternalHandle& handle);
int execBuffer(struct VirtGpuExecBuffer& execbuffer, VirtGpuBlobPtr blob);
private:
VirtGpuDevice(enum VirtGpuCapset capset);
~VirtGpuDevice();
VirtGpuDevice(VirtGpuDevice const&);
void operator=(VirtGpuDevice const&);
static VirtGpuDevice mInstance;
int64_t mDeviceHandle;
struct VirtGpuParam mParams[kParamMax];
};
// HACK: We can use android::base::EnumFlags, but we'll have to do more guest
// refactorings to figure out our end goal. We can either depend more on base or
// try to transition to something else (b:202552093) [atleast for guests].
constexpr enum VirtGpuBlobFlags operator |(const enum VirtGpuBlobFlags self,
const enum VirtGpuBlobFlags other) {
return (enum VirtGpuBlobFlags)(uint32_t(self) | uint32_t(other));
}
constexpr enum VirtGpuExecBufferFlags operator |(const enum VirtGpuExecBufferFlags self,
const enum VirtGpuExecBufferFlags other) {
return (enum VirtGpuExecBufferFlags)(uint32_t(self) | uint32_t(other));
}
#endif