[PATCH] gfxstream: refactor device initialization
authorGurchetan Singh <gurchetansingh@google.com>
Wed, 19 Mar 2025 18:02:22 +0000 (11:02 -0700)
committerTimo Aaltonen <tjaalton@debian.org>
Thu, 3 Apr 2025 10:47:45 +0000 (13:47 +0300)
Don't add unnecessary logspam if virtgpu isn't present.

Cc: mesa-stable
Reviewed-by: Aaron Ruby <aruby@qnx.com>
Gbp-Pq: Name gfxstream-refactor-device-init.diff

src/gfxstream/guest/platform/VirtGpu.cpp
src/gfxstream/guest/platform/include/VirtGpu.h
src/gfxstream/guest/platform/linux/LinuxVirtGpu.h
src/gfxstream/guest/platform/linux/LinuxVirtGpuDevice.cpp
src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp

index 930bfc62f3e05b627dcc777259a5eba981ae5a83..2f6267814e82e5996ff543a0dea0597e32f419aa 100644 (file)
@@ -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) {
index 8fee452538fc6541743e43f4d74bbfb496dc8961..f806aa2f479aad90f9c6e205959032c165182df1 100644 (file)
@@ -199,7 +199,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;
 
index 18ccb47012a9408f4566faf3b51fc298743104b5..734034f1e5ebc35500318a34730865fef44692f2 100644 (file)
@@ -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;
index d5509388fda85ce77ac3b5485dd9368eccea10a3..224f3657beb0520fd9a1cf2b3cfcb55566f2cafe 100644 (file)
 
 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;
-    }
 
-    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);
+        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;
+        mBusType = dev->bustype;
+        if (dev->bustype == DRM_BUS_PCI) {
+            mPciBusInfo = *dev->businfo.pci;
+        }
 
-    drmFreeVersion(version);
+        drmFreeVersion(version);
+        mesa_logd("using DRM device %s", node_path);
 
-    mesa_logd("using DRM device %s", node_path);
+        mDeviceHandle = static_cast<int64_t>(fd);
+        ret = 0;
+        break;
+    }
 
-    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),
@@ -129,7 +151,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}};
@@ -142,32 +164,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;
-        }
-
-        int fd = -1;
-        for (int i = 0; i < count; i++) {
-            fd = openDevice(devs[i]);
-            if (fd >= 0) break;
+        ret = openDevice();
+        if (ret < 0) {
+            mesa_logd("no virtio_gpu devices found");
+            return ret;
         }
 
-        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;
         }
     }
 
@@ -185,6 +192,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:
@@ -241,6 +249,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); }
@@ -354,7 +364,13 @@ 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) {
+        return nullptr;
+    }
+
+    return device;
 }
 
 bool LinuxVirtGpuDevice::getDrmInfo(VirtGpuDrmInfo* drmInfo) {
@@ -376,6 +392,5 @@ bool LinuxVirtGpuDevice::getPciBusInfo(VirtGpuPciBusInfo* pciBusInfo) {
     pciBusInfo->bus = mPciBusInfo.bus;
     pciBusInfo->device = mPciBusInfo.dev;
     pciBusInfo->function = mPciBusInfo.func;
-
     return true;
 }
index f5e6a685fd2ac923a05a4f90a7d75cb7547b2a37..ef874b9f43d8761a4a9d860b4f294cd884525122 100644 (file)
@@ -76,7 +76,7 @@ static const char* const kMesaOnlyDeviceExtensions[] = {
 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;
     }