gfxstream: refactor device initialization
Don't add unnecessary logspam if virtgpu isn't present. Cc: mesa-stable Reviewed-by: Aaron Ruby <aruby@qnx.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34090>
This commit is contained in:
committed by
Marge Bot
parent
5503d97bf6
commit
ef84cd928e
@@ -29,9 +29,9 @@ VirtGpuDevice* VirtGpuDevice::getInstance(enum VirtGpuCapset capset, int32_t des
|
||||
// Otherwise, the created device's capset must match the requested capset.
|
||||
// We could support multiple capsets with a map of devices but that case isn't needed
|
||||
// currently, and with multiple devices it's unclear how to handle kCapsetNone.
|
||||
if (capset != kCapsetNone && sDevice && sDevice->capset() != capset) {
|
||||
if (capset != kCapsetNone && sDevice && sDevice->getCapset() != capset) {
|
||||
mesa_loge("Requested VirtGpuDevice capset %u, already created capset %u", capset,
|
||||
sDevice->capset());
|
||||
sDevice->getCapset());
|
||||
return nullptr;
|
||||
}
|
||||
if (!sDevice) {
|
||||
|
||||
@@ -181,7 +181,7 @@ class VirtGpuDevice {
|
||||
VirtGpuDevice(enum VirtGpuCapset capset) : mCapset(capset) {}
|
||||
virtual ~VirtGpuDevice() {}
|
||||
|
||||
enum VirtGpuCapset capset() { return mCapset; }
|
||||
enum VirtGpuCapset getCapset() { return mCapset; }
|
||||
|
||||
virtual int64_t getDeviceHandle(void) = 0;
|
||||
|
||||
|
||||
@@ -52,7 +52,9 @@ class LinuxVirtGpuResourceMapping : public VirtGpuResourceMapping {
|
||||
|
||||
class LinuxVirtGpuDevice : public VirtGpuDevice {
|
||||
public:
|
||||
LinuxVirtGpuDevice(enum VirtGpuCapset capset, int fd = -1);
|
||||
LinuxVirtGpuDevice(enum VirtGpuCapset capset);
|
||||
int32_t init(int32_t descriptor);
|
||||
|
||||
virtual ~LinuxVirtGpuDevice();
|
||||
|
||||
virtual int64_t getDeviceHandle(void);
|
||||
@@ -74,7 +76,7 @@ class LinuxVirtGpuDevice : public VirtGpuDevice {
|
||||
int64_t mDeviceHandle;
|
||||
struct VirtGpuCaps mCaps;
|
||||
|
||||
int openDevice(const drmDevicePtr dev);
|
||||
int openDevice();
|
||||
|
||||
bool mHasPrimary;
|
||||
int mPrimaryMajor;
|
||||
|
||||
@@ -38,87 +38,109 @@
|
||||
|
||||
static inline uint32_t align_up(uint32_t n, uint32_t a) { return ((n + a - 1) / a) * a; }
|
||||
|
||||
int
|
||||
LinuxVirtGpuDevice::openDevice(const drmDevicePtr dev)
|
||||
{
|
||||
bool supported_bus = false;
|
||||
|
||||
switch (dev->bustype) {
|
||||
case DRM_BUS_PCI:
|
||||
if (dev->deviceinfo.pci->vendor_id == VIRTGPU_PCI_VENDOR_ID &&
|
||||
dev->deviceinfo.pci->device_id == VIRTGPU_PCI_DEVICE_ID)
|
||||
supported_bus = true;
|
||||
break;
|
||||
case DRM_BUS_PLATFORM:
|
||||
supported_bus = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
int32_t LinuxVirtGpuDevice::openDevice() {
|
||||
drmDevicePtr devs[8];
|
||||
int32_t ret = -EINVAL;
|
||||
int count = drmGetDevices2(0, devs, ARRAY_SIZE(devs));
|
||||
if (count <= 0) {
|
||||
mesa_logd("failed to enumerate DRM devices");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!supported_bus || !(dev->available_nodes & (1 << DRM_NODE_RENDER))) {
|
||||
const char *name = "unknown";
|
||||
for (uint32_t i = 0; i < DRM_NODE_MAX; i++) {
|
||||
if (dev->available_nodes & (1 << i)) {
|
||||
name = dev->nodes[i];
|
||||
for (int i = 0; i < count; i++) {
|
||||
drmDevicePtr dev = devs[i];
|
||||
bool supported_bus = false;
|
||||
|
||||
switch (dev->bustype) {
|
||||
case DRM_BUS_PCI:
|
||||
if (dev->deviceinfo.pci->vendor_id == VIRTGPU_PCI_VENDOR_ID &&
|
||||
dev->deviceinfo.pci->device_id == VIRTGPU_PCI_DEVICE_ID)
|
||||
supported_bus = true;
|
||||
break;
|
||||
case DRM_BUS_PLATFORM:
|
||||
supported_bus = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!supported_bus || !(dev->available_nodes & (1 << DRM_NODE_RENDER))) {
|
||||
const char* name = "unknown";
|
||||
for (uint32_t i = 0; i < DRM_NODE_MAX; i++) {
|
||||
if (dev->available_nodes & (1 << i)) {
|
||||
name = dev->nodes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mesa_logd("skipping DRM device %s", name);
|
||||
continue;
|
||||
}
|
||||
mesa_logd("skipping DRM device %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *primary_path = dev->nodes[DRM_NODE_PRIMARY];
|
||||
const char *node_path = dev->nodes[DRM_NODE_RENDER];
|
||||
const char* primary_path = dev->nodes[DRM_NODE_PRIMARY];
|
||||
const char* node_path = dev->nodes[DRM_NODE_RENDER];
|
||||
|
||||
int fd = open(node_path, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
mesa_logd("failed to open %s", node_path);
|
||||
return -1;
|
||||
}
|
||||
int fd = open(node_path, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
mesa_logd("failed to open %s", node_path);
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
drmVersionPtr version = drmGetVersion(fd);
|
||||
if (!version || strcmp(version->name, "virtio_gpu") ||
|
||||
version->version_major != 0) {
|
||||
if (version) {
|
||||
mesa_logd("unknown DRM driver %s version %d",
|
||||
version->name, version->version_major);
|
||||
drmVersionPtr version = drmGetVersion(fd);
|
||||
if (!version || strcmp(version->name, "virtio_gpu") || version->version_major != 0) {
|
||||
if (version) {
|
||||
mesa_logd("unknown DRM driver %s version %d", version->name,
|
||||
version->version_major);
|
||||
} else {
|
||||
mesa_logd("failed to get DRM driver version");
|
||||
}
|
||||
|
||||
if (version) {
|
||||
drmFreeVersion(version);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
if (stat(primary_path, &st) == 0) {
|
||||
mHasPrimary = true;
|
||||
mPrimaryMajor = major(st.st_rdev);
|
||||
mPrimaryMinor = minor(st.st_rdev);
|
||||
} else {
|
||||
mesa_logd("failed to get DRM driver version");
|
||||
mHasPrimary = false;
|
||||
mPrimaryMajor = 0;
|
||||
mPrimaryMinor = 0;
|
||||
}
|
||||
if (version)
|
||||
drmFreeVersion(version);
|
||||
close(fd);
|
||||
return -1;
|
||||
|
||||
stat(node_path, &st);
|
||||
mRenderMajor = major(st.st_rdev);
|
||||
mRenderMinor = minor(st.st_rdev);
|
||||
|
||||
mBusType = dev->bustype;
|
||||
if (dev->bustype == DRM_BUS_PCI) {
|
||||
mPciBusInfo = *dev->businfo.pci;
|
||||
}
|
||||
|
||||
drmFreeVersion(version);
|
||||
mesa_logd("using DRM device %s", node_path);
|
||||
|
||||
mDeviceHandle = static_cast<int64_t>(fd);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
if (stat(primary_path, &st) == 0) {
|
||||
mHasPrimary = true;
|
||||
mPrimaryMajor = major(st.st_rdev);
|
||||
mPrimaryMinor = minor(st.st_rdev);
|
||||
} else {
|
||||
mHasPrimary = false;
|
||||
mPrimaryMajor = 0;
|
||||
mPrimaryMinor = 0;
|
||||
}
|
||||
stat(node_path, &st);
|
||||
mRenderMajor = major(st.st_rdev);
|
||||
mRenderMinor = minor(st.st_rdev);
|
||||
|
||||
mBusType = dev->bustype;
|
||||
if (dev->bustype == DRM_BUS_PCI)
|
||||
mPciBusInfo = *dev->businfo.pci;
|
||||
|
||||
drmFreeVersion(version);
|
||||
|
||||
mesa_logd("using DRM device %s", node_path);
|
||||
|
||||
return fd;
|
||||
out:
|
||||
drmFreeDevices(devs, count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LinuxVirtGpuDevice::LinuxVirtGpuDevice(enum VirtGpuCapset capset, int32_t descriptor)
|
||||
: VirtGpuDevice(capset) {
|
||||
LinuxVirtGpuDevice::LinuxVirtGpuDevice(enum VirtGpuCapset capset) : VirtGpuDevice(capset) {}
|
||||
|
||||
int32_t LinuxVirtGpuDevice::init(int32_t descriptor) {
|
||||
struct VirtGpuParam params[] = {
|
||||
PARAM(VIRTGPU_PARAM_3D_FEATURES), PARAM(VIRTGPU_PARAM_CAPSET_QUERY_FIX),
|
||||
PARAM(VIRTGPU_PARAM_RESOURCE_BLOB), PARAM(VIRTGPU_PARAM_HOST_VISIBLE),
|
||||
@@ -128,7 +150,7 @@ LinuxVirtGpuDevice::LinuxVirtGpuDevice(enum VirtGpuCapset capset, int32_t descri
|
||||
PARAM(VIRTGPU_PARAM_CREATE_GUEST_HANDLE),
|
||||
};
|
||||
|
||||
int ret;
|
||||
int ret = -EINVAL;
|
||||
struct drm_virtgpu_get_caps get_caps = {0};
|
||||
struct drm_virtgpu_context_init init = {0};
|
||||
struct drm_virtgpu_context_set_param ctx_set_params[3] = {{0}};
|
||||
@@ -141,32 +163,17 @@ LinuxVirtGpuDevice::LinuxVirtGpuDevice(enum VirtGpuCapset capset, int32_t descri
|
||||
#endif
|
||||
|
||||
if (descriptor < 0) {
|
||||
drmDevicePtr devs[8];
|
||||
int count = drmGetDevices2(0, devs, ARRAY_SIZE(devs));
|
||||
if (count < 0) {
|
||||
mesa_loge("failed to enumerate DRM devices");
|
||||
return;
|
||||
ret = openDevice();
|
||||
if (ret < 0) {
|
||||
mesa_logd("no virtio_gpu devices found");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fd = -1;
|
||||
for (int i = 0; i < count; i++) {
|
||||
fd = openDevice(devs[i]);
|
||||
if (fd >= 0) break;
|
||||
}
|
||||
|
||||
drmFreeDevices(devs, count);
|
||||
|
||||
if (fd < 0) {
|
||||
mesa_loge("Failed to open the virtio_gpu device.");
|
||||
return;
|
||||
}
|
||||
|
||||
mDeviceHandle = static_cast<int64_t>(fd);
|
||||
} else {
|
||||
mDeviceHandle = dup(descriptor);
|
||||
if (mDeviceHandle < 0) {
|
||||
mesa_loge("Failed to dup rendernode: %s", strerror(errno));
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,6 +191,7 @@ LinuxVirtGpuDevice::LinuxVirtGpuDevice(enum VirtGpuCapset capset, int32_t descri
|
||||
mCaps.params[i] = params[i].value;
|
||||
}
|
||||
|
||||
auto capset = getCapset();
|
||||
get_caps.cap_set_id = static_cast<uint32_t>(capset);
|
||||
switch (capset) {
|
||||
case kCapsetGfxStreamVulkan:
|
||||
@@ -240,6 +248,8 @@ LinuxVirtGpuDevice::LinuxVirtGpuDevice(enum VirtGpuCapset capset, int32_t descri
|
||||
mesa_loge("DRM_IOCTL_VIRTGPU_CONTEXT_INIT failed with %s, continuing without context...",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LinuxVirtGpuDevice::~LinuxVirtGpuDevice() { close(mDeviceHandle); }
|
||||
@@ -353,7 +363,14 @@ int LinuxVirtGpuDevice::execBuffer(struct VirtGpuExecBuffer& execbuffer,
|
||||
}
|
||||
|
||||
VirtGpuDevice* osCreateVirtGpuDevice(enum VirtGpuCapset capset, int32_t descriptor) {
|
||||
return new LinuxVirtGpuDevice(capset, descriptor);
|
||||
auto device = new LinuxVirtGpuDevice(capset);
|
||||
int32_t ret = device->init(descriptor);
|
||||
if (ret) {
|
||||
delete device;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
bool LinuxVirtGpuDevice::getDrmInfo(VirtGpuDrmInfo* drmInfo) {
|
||||
@@ -375,6 +392,5 @@ bool LinuxVirtGpuDevice::getPciBusInfo(VirtGpuPciBusInfo* pciBusInfo) {
|
||||
pciBusInfo->bus = mPciBusInfo.bus;
|
||||
pciBusInfo->device = mPciBusInfo.dev;
|
||||
pciBusInfo->function = mPciBusInfo.func;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ static bool isGuestEmulatedInstanceExtension(const char* name) {
|
||||
static VkResult SetupInstanceForProcess(void) {
|
||||
auto mgr = getConnectionManager();
|
||||
if (!mgr) {
|
||||
mesa_loge("vulkan: Failed to get host connection\n");
|
||||
mesa_logd("vulkan: Failed to get host connection\n");
|
||||
return VK_ERROR_DEVICE_LOST;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user