mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 18:10:17 +01:00
gfxstream: GrallocMinigbm uses platform_virtgpu
This removes the open-coding of virtgpu_drm access and uses the platform_virtgpu layer. Reviewed-by: Aaron Ruby <aruby@blackberry.com> Acked-by: Yonggang Luo <luoyonggang@gmail.com> Acked-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27246>
This commit is contained in:
parent
688f305cea
commit
fcf73c0ed4
11 changed files with 81 additions and 133 deletions
|
|
@ -407,13 +407,12 @@ int EmulatedAHardwareBuffer::unlock() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
EmulatedGralloc::EmulatedGralloc(VirtGpuDevice* device) : mDevice(device) {}
|
||||
|
||||
EmulatedGralloc::~EmulatedGralloc() {
|
||||
mOwned.clear();
|
||||
delete mDevice;
|
||||
EmulatedGralloc::EmulatedGralloc(int32_t descriptor) {
|
||||
mDevice.reset(createPlatformVirtGpuDevice(kCapsetNone, descriptor));
|
||||
}
|
||||
|
||||
EmulatedGralloc::~EmulatedGralloc() { mOwned.clear(); }
|
||||
|
||||
GrallocType EmulatedGralloc::getGrallocType() { return GRALLOC_TYPE_EMULATED; }
|
||||
|
||||
uint32_t EmulatedGralloc::createColorBuffer(int width, int height, uint32_t glFormat) {
|
||||
|
|
@ -577,14 +576,6 @@ int EmulatedGralloc::getId(const AHardwareBuffer* ahb, uint64_t* id) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Gralloc* createPlatformGralloc(int32_t descriptor) {
|
||||
auto device = createPlatformVirtGpuDevice(kCapsetNone, descriptor);
|
||||
if (!device) {
|
||||
ALOGE("no virtio gpu device.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new EmulatedGralloc(device);
|
||||
}
|
||||
Gralloc* createPlatformGralloc(int32_t descriptor) { return new EmulatedGralloc(descriptor); }
|
||||
|
||||
} // namespace gfxstream
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class EmulatedAHardwareBuffer {
|
|||
|
||||
class EmulatedGralloc : public Gralloc {
|
||||
public:
|
||||
EmulatedGralloc(VirtGpuDevice* device);
|
||||
EmulatedGralloc(int32_t descriptor);
|
||||
~EmulatedGralloc();
|
||||
|
||||
GrallocType getGrallocType() override;
|
||||
|
|
@ -102,7 +102,7 @@ class EmulatedGralloc : public Gralloc {
|
|||
int getId(const AHardwareBuffer* ahb, uint64_t* id) override;
|
||||
|
||||
private:
|
||||
VirtGpuDevice* mDevice;
|
||||
std::unique_ptr<VirtGpuDevice> mDevice;
|
||||
std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> mOwned;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,103 +15,23 @@
|
|||
#include "GrallocMinigbm.h"
|
||||
|
||||
#include <cros_gralloc/cros_gralloc_handle.h>
|
||||
#include <errno.h>
|
||||
#include <log/log.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/user.h>
|
||||
#include <unistd.h>
|
||||
#include <vndk/hardware_buffer.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
|
||||
#include "virtgpu_drm.h"
|
||||
|
||||
#if defined(PAGE_SIZE)
|
||||
constexpr size_t kPageSize = PAGE_SIZE;
|
||||
#else
|
||||
#include <unistd.h>
|
||||
static const size_t kPageSize = getpagesize();
|
||||
#endif
|
||||
#include "VirtGpu.h"
|
||||
|
||||
namespace gfxstream {
|
||||
namespace {
|
||||
|
||||
static inline uint32_t align_up(uint32_t n, uint32_t a) { return ((n + a - 1) / a) * a; }
|
||||
|
||||
bool getVirtioGpuResourceInfo(int fd, native_handle_t const* handle,
|
||||
struct drm_virtgpu_resource_info* info) {
|
||||
memset(info, 0x0, sizeof(*info));
|
||||
if (fd < 0) {
|
||||
ALOGE("%s: Error, rendernode fd missing\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct drm_gem_close gem_close;
|
||||
memset(&gem_close, 0x0, sizeof(gem_close));
|
||||
|
||||
cros_gralloc_handle const* cros_handle = reinterpret_cast<cros_gralloc_handle const*>(handle);
|
||||
|
||||
uint32_t prime_handle;
|
||||
int ret = drmPrimeFDToHandle(fd, cros_handle->fds[0], &prime_handle);
|
||||
if (ret) {
|
||||
ALOGE("%s: DRM_IOCTL_PRIME_FD_TO_HANDLE failed: %s (errno %d)\n", __func__, strerror(errno),
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
struct ManagedDrmGem {
|
||||
ManagedDrmGem(int fd, uint32_t handle) : m_fd(fd), m_prime_handle(handle) {}
|
||||
ManagedDrmGem(const ManagedDrmGem&) = delete;
|
||||
~ManagedDrmGem() {
|
||||
struct drm_gem_close gem_close {
|
||||
.handle = m_prime_handle, .pad = 0,
|
||||
};
|
||||
int ret = drmIoctl(m_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
|
||||
if (ret) {
|
||||
ALOGE("%s: DRM_IOCTL_GEM_CLOSE failed on handle %" PRIu32 ": %s(%d).", __func__,
|
||||
m_prime_handle, strerror(errno), errno);
|
||||
}
|
||||
}
|
||||
|
||||
int m_fd;
|
||||
uint32_t m_prime_handle;
|
||||
} managed_prime_handle(fd, prime_handle);
|
||||
|
||||
info->bo_handle = managed_prime_handle.m_prime_handle;
|
||||
|
||||
struct drm_virtgpu_3d_wait virtgpuWait {
|
||||
.handle = managed_prime_handle.m_prime_handle, .flags = 0,
|
||||
};
|
||||
// This only works for host resources by VIRTGPU_RESOURCE_CREATE ioctl.
|
||||
// We need to use a different mechanism to synchronize with the host if
|
||||
// the minigbm gralloc swiches to virtio-gpu blobs or cross-domain
|
||||
// backend.
|
||||
int retry = 0;
|
||||
do {
|
||||
if (retry > 10) {
|
||||
ALOGE("%s DRM_IOCTL_VIRTGPU_WAIT failed with EBUSY %d times.", __func__, retry);
|
||||
return false;
|
||||
}
|
||||
ret = drmIoctl(fd, DRM_IOCTL_VIRTGPU_WAIT, &virtgpuWait);
|
||||
++retry;
|
||||
} while (ret < 0 && errno == EBUSY);
|
||||
if (ret) {
|
||||
ALOGE("%s: DRM_IOCTL_VIRTGPU_WAIT failed: %s(%d)", __func__, strerror(errno), errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = drmIoctl(fd, DRM_IOCTL_VIRTGPU_RESOURCE_INFO, info);
|
||||
if (ret) {
|
||||
ALOGE("%s: DRM_IOCTL_VIRTGPU_RESOURCE_INFO failed: %s (errno %d)\n", __func__,
|
||||
strerror(errno), errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
MinigbmGralloc::MinigbmGralloc(int32_t descriptor) {
|
||||
mDevice.reset(createPlatformVirtGpuDevice(kCapsetNone, descriptor));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
GrallocType MinigbmGralloc::getGrallocType() { return GRALLOC_TYPE_MINIGBM; }
|
||||
|
||||
uint32_t MinigbmGralloc::createColorBuffer(int width, int height, uint32_t glformat) {
|
||||
|
|
@ -135,30 +55,14 @@ uint32_t MinigbmGralloc::createColorBuffer(int width, int height, uint32_t glfor
|
|||
bpp = 4;
|
||||
break;
|
||||
}
|
||||
const uint32_t kPipeTexture2D = 2; // PIPE_TEXTURE_2D
|
||||
const uint32_t kBindRenderTarget = 1 << 1; // VIRGL_BIND_RENDER_TARGET
|
||||
struct drm_virtgpu_resource_create res_create;
|
||||
memset(&res_create, 0, sizeof(res_create));
|
||||
res_create.target = kPipeTexture2D;
|
||||
res_create.format = virtgpu_format;
|
||||
res_create.bind = kBindRenderTarget;
|
||||
res_create.width = width;
|
||||
res_create.height = height;
|
||||
res_create.depth = 1;
|
||||
res_create.array_size = 1;
|
||||
res_create.last_level = 0;
|
||||
res_create.nr_samples = 0;
|
||||
res_create.stride = bpp * width;
|
||||
res_create.size = align_up(bpp * width * height, kPageSize);
|
||||
|
||||
int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &res_create);
|
||||
if (ret) {
|
||||
ALOGE("%s: DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s (%d)\n", __func__,
|
||||
strerror(errno), errno);
|
||||
abort();
|
||||
}
|
||||
uint32_t stride = bpp * width;
|
||||
auto resource = mDevice->createResource(width, height, stride, stride * height, virtgpu_format,
|
||||
PIPE_TEXTURE_2D, VIRGL_BIND_RENDER_TARGET);
|
||||
|
||||
return res_create.res_handle;
|
||||
uint32_t handle = resource->getResourceHandle();
|
||||
resource->intoRaw();
|
||||
return handle;
|
||||
}
|
||||
|
||||
int MinigbmGralloc::allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
|
||||
|
|
@ -191,13 +95,22 @@ int MinigbmGralloc::lockPlanes(AHardwareBuffer* ahb, std::vector<LockedPlane>* a
|
|||
int MinigbmGralloc::unlock(AHardwareBuffer* ahb) { return AHardwareBuffer_unlock(ahb, nullptr); }
|
||||
|
||||
uint32_t MinigbmGralloc::getHostHandle(const native_handle_t* handle) {
|
||||
struct drm_virtgpu_resource_info info;
|
||||
if (!getVirtioGpuResourceInfo(m_fd, handle, &info)) {
|
||||
ALOGE("%s: failed to get resource info", __func__);
|
||||
cros_gralloc_handle const* cros_handle = reinterpret_cast<cros_gralloc_handle const*>(handle);
|
||||
struct VirtGpuExternalHandle hnd = {
|
||||
.osHandle = dup(cros_handle->fds[0]),
|
||||
.type = kMemHandleDmabuf,
|
||||
};
|
||||
|
||||
auto resource = mDevice->importBlob(hnd);
|
||||
if (!resource) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return info.res_handle;
|
||||
if (resource->wait()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return resource->getResourceHandle();
|
||||
}
|
||||
|
||||
uint32_t MinigbmGralloc::getHostHandle(const AHardwareBuffer* ahb) {
|
||||
|
|
@ -241,12 +154,22 @@ uint32_t MinigbmGralloc::getHeight(const AHardwareBuffer* ahb) {
|
|||
}
|
||||
|
||||
size_t MinigbmGralloc::getAllocatedSize(const native_handle_t* handle) {
|
||||
struct drm_virtgpu_resource_info info;
|
||||
if (!getVirtioGpuResourceInfo(m_fd, handle, &info)) {
|
||||
ALOGE("%s: failed to get resource info\n", __func__);
|
||||
cros_gralloc_handle const* cros_handle = reinterpret_cast<cros_gralloc_handle const*>(handle);
|
||||
struct VirtGpuExternalHandle hnd = {
|
||||
.osHandle = dup(cros_handle->fds[0]),
|
||||
.type = kMemHandleDmabuf,
|
||||
};
|
||||
|
||||
auto resource = mDevice->importBlob(hnd);
|
||||
if (!resource) {
|
||||
return 0;
|
||||
}
|
||||
return info.size;
|
||||
|
||||
if (resource->wait()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return resource->getSize();
|
||||
}
|
||||
|
||||
size_t MinigbmGralloc::getAllocatedSize(const AHardwareBuffer* ahb) {
|
||||
|
|
|
|||
|
|
@ -14,12 +14,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "VirtGpu.h"
|
||||
#include "gfxstream/guest/Gralloc.h"
|
||||
|
||||
namespace gfxstream {
|
||||
|
||||
class MinigbmGralloc : public Gralloc {
|
||||
public:
|
||||
MinigbmGralloc(int32_t descriptor);
|
||||
~MinigbmGralloc(){};
|
||||
|
||||
GrallocType getGrallocType() override;
|
||||
|
||||
uint32_t createColorBuffer(int width, int height, uint32_t glformat) override;
|
||||
|
|
@ -53,10 +59,8 @@ class MinigbmGralloc : public Gralloc {
|
|||
|
||||
int getId(const AHardwareBuffer* ahb, uint64_t* id) override;
|
||||
|
||||
void setFd(int fd) { m_fd = fd; }
|
||||
|
||||
private:
|
||||
int m_fd;
|
||||
std::unique_ptr<VirtGpuDevice> mDevice;
|
||||
};
|
||||
|
||||
} // namespace gfxstream
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ class FuchsiaVirtGpuResource : public std::enable_shared_from_this<FuchsiaVirtGp
|
|||
|
||||
uint32_t getResourceHandle() const override;
|
||||
uint32_t getBlobHandle() const override;
|
||||
uint64_t getSize() const override;
|
||||
int wait() override;
|
||||
|
||||
int exportBlob(struct VirtGpuExternalHandle& handle) override;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ uint32_t FuchsiaVirtGpuResource::getResourceHandle() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint64_t FuchsiaVirtGpuResource::getSize() const {
|
||||
mesa_loge("%s: unimplemented", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
VirtGpuResourceMappingPtr FuchsiaVirtGpuResource::createMapping(void) {
|
||||
mesa_loge("%s: unimplemented", __func__);
|
||||
return nullptr;
|
||||
|
|
|
|||
|
|
@ -152,8 +152,15 @@ class VirtGpuResource {
|
|||
public:
|
||||
virtual ~VirtGpuResource() {}
|
||||
|
||||
// The `intoRaw()` function drops ownerships of the OS-handle underlying
|
||||
// the resource. It is the responsibility of the caller to manage lifetimes
|
||||
// of the virtio-gpu resource. This function is mostly for gfxstream EGL
|
||||
// compatibility and shouldn't be used elsewhere.
|
||||
virtual void intoRaw(){};
|
||||
|
||||
virtual uint32_t getResourceHandle() const = 0;
|
||||
virtual uint32_t getBlobHandle() const = 0;
|
||||
virtual uint64_t getSize() const = 0;
|
||||
virtual int wait() = 0;
|
||||
|
||||
virtual VirtGpuResourceMappingPtr createMapping(void) = 0;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ class VirtGpuKumquatResource : public std::enable_shared_from_this<VirtGpuKumqua
|
|||
|
||||
uint32_t getResourceHandle() const override;
|
||||
uint32_t getBlobHandle() const override;
|
||||
uint64_t getSize() const override;
|
||||
|
||||
int wait() override;
|
||||
|
||||
VirtGpuResourceMappingPtr createMapping(void) override;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ uint32_t VirtGpuKumquatResource::getBlobHandle() const { return mBlobHandle; }
|
|||
|
||||
uint32_t VirtGpuKumquatResource::getResourceHandle() const { return mResourceHandle; }
|
||||
|
||||
uint64_t VirtGpuKumquatResource::getSize() const { return mSize; }
|
||||
|
||||
VirtGpuResourceMappingPtr VirtGpuKumquatResource::createMapping() {
|
||||
int ret;
|
||||
struct drm_kumquat_map map {
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ class LinuxVirtGpuResource : public std::enable_shared_from_this<LinuxVirtGpuRes
|
|||
uint64_t size);
|
||||
~LinuxVirtGpuResource();
|
||||
|
||||
void intoRaw() override;
|
||||
uint32_t getResourceHandle() const override;
|
||||
uint32_t getBlobHandle() const override;
|
||||
uint64_t getSize() const override;
|
||||
int wait() override;
|
||||
|
||||
VirtGpuResourceMappingPtr createMapping(void) override;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ LinuxVirtGpuResource::LinuxVirtGpuResource(int64_t deviceHandle, uint32_t blobHa
|
|||
mSize(size) {}
|
||||
|
||||
LinuxVirtGpuResource::~LinuxVirtGpuResource() {
|
||||
if (mBlobHandle == INVALID_DESCRIPTOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct drm_gem_close gem_close {
|
||||
.handle = mBlobHandle, .pad = 0,
|
||||
};
|
||||
|
|
@ -45,10 +49,17 @@ LinuxVirtGpuResource::~LinuxVirtGpuResource() {
|
|||
}
|
||||
}
|
||||
|
||||
void LinuxVirtGpuResource::intoRaw() {
|
||||
mBlobHandle = INVALID_DESCRIPTOR;
|
||||
mResourceHandle = INVALID_DESCRIPTOR;
|
||||
}
|
||||
|
||||
uint32_t LinuxVirtGpuResource::getBlobHandle() const { return mBlobHandle; }
|
||||
|
||||
uint32_t LinuxVirtGpuResource::getResourceHandle() const { return mResourceHandle; }
|
||||
|
||||
uint64_t LinuxVirtGpuResource::getSize() const { return mSize; }
|
||||
|
||||
VirtGpuResourceMappingPtr LinuxVirtGpuResource::createMapping() {
|
||||
int ret;
|
||||
struct drm_virtgpu_map map {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue