Show a patch.

GET /api/patches/23458/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 23458,
    "url": "https://patchwork.libcamera.org/api/patches/23458/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/23458/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20250530090815.18587-1-mzamazal@redhat.com>",
    "date": "2025-05-30T09:08:15",
    "name": "[v4] apps: cam: Skip non-display GPUs",
    "commit_ref": "663ab2ee8efe390f57effca358632566f8c26253",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "192c74196ef9d05cbac52182f98ee2b375efc332",
    "submitter": {
        "id": 177,
        "url": "https://patchwork.libcamera.org/api/people/177/?format=api",
        "name": "Milan Zamazal",
        "email": "mzamazal@redhat.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/23458/mbox/",
    "series": [
        {
            "id": 5201,
            "url": "https://patchwork.libcamera.org/api/series/5201/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5201",
            "date": "2025-05-30T09:08:15",
            "name": "[v4] apps: cam: Skip non-display GPUs",
            "version": 4,
            "mbox": "https://patchwork.libcamera.org/series/5201/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/23458/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/23458/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>",
        "X-Original-To": "parsemail@patchwork.libcamera.org",
        "Delivered-To": "parsemail@patchwork.libcamera.org",
        "Received": [
            "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 60D2BC31E9\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 30 May 2025 09:08:26 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7C91E68DA8;\n\tFri, 30 May 2025 11:08:25 +0200 (CEST)",
            "from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8A6DD614D5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 30 May 2025 11:08:23 +0200 (CEST)",
            "from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-257-RT-HNK6fN5edtqNDhjz24g-1;\n\tFri, 30 May 2025 05:08:21 -0400",
            "from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.12])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id 373281956086; Fri, 30 May 2025 09:08:20 +0000 (UTC)",
            "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.53])\n\tby mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 1675819560A7; Fri, 30 May 2025 09:08:17 +0000 (UTC)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"PnRDgPi7\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1748596102;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding;\n\tbh=3s6WTprmrADzWvHdn8PwsMMPwAV7HEPWV8n7QSLCfXs=;\n\tb=PnRDgPi7SV3oS6Yoz6Q53gVBl3g5Kl7xyX8nIWT7wP6ICegJ0ruXtOd2ORwn6wokfdVfIp\n\tf3vfHXO4c2nFINhT12cC+qtGq03lmqkRkwDFReyq9Ogsil9rdWrcm3MNANvwY6OizCGflQ\n\tVzFPhVkdL4u0zPLaf2Qvd+j0RHcCUak=",
        "X-MC-Unique": "RT-HNK6fN5edtqNDhjz24g-1",
        "X-Mimecast-MFC-AGG-ID": "RT-HNK6fN5edtqNDhjz24g_1748596100",
        "From": "Milan Zamazal <mzamazal@redhat.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Milan Zamazal <mzamazal@redhat.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tMattijs Korpershoek <mkorpershoek@kernel.org>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "Subject": "[PATCH v4] apps: cam: Skip non-display GPUs",
        "Date": "Fri, 30 May 2025 11:08:15 +0200",
        "Message-ID": "<20250530090815.18587-1-mzamazal@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.12",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "TbVtfuvLNo7qZZrXInak-6tyRdM3pULKPqUJGn1wjYQ_1748596100",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Device::openCard() in the cam DRM helpers looks for a /dev/dri/card*\ndevice that can be opened and that doesn't fail when asked about\nDRM_CAP_DUMB_BUFFER capability (regardless whether the capability is\nsupported by the device).\n\nThere can be matching devices that are not display devices.  This can\nlead to selection of such a device and inability to use KMS output with\n`cam' application.  The ultimate goal is to display something on the\ndevice and later the KMS sink will fail if there is no connector\nattached to the device (although it can actually fail earlier, when\ntrying to set DRM_CLIENT_CAP_ATOMIC capability if this is not\nsupported).\n\nLet's avoid selecting devices without connectors, CRTCs or encoders.\nThe added check makes the original check for DRM_CAP_DUMB_BUFFER API\nmost likely unnecessary, let's remove it.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\nReviewed-by: Mattijs Korpershoek <mkorpershoek@kernel.org>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/apps/cam/drm.cpp | 25 +++++++++++++++----------\n 1 file changed, 15 insertions(+), 10 deletions(-)",
    "diff": "diff --git a/src/apps/cam/drm.cpp b/src/apps/cam/drm.cpp\nindex 47bbb6b05..f4b470976 100644\n--- a/src/apps/cam/drm.cpp\n+++ b/src/apps/cam/drm.cpp\n@@ -450,8 +450,6 @@ int Device::openCard()\n \t}\n \n \tfor (struct dirent *res; (res = readdir(folder));) {\n-\t\tuint64_t cap;\n-\n \t\tif (strncmp(res->d_name, \"card\", 4))\n \t\t\tcontinue;\n \n@@ -465,15 +463,22 @@ int Device::openCard()\n \t\t}\n \n \t\t/*\n-\t\t * Skip devices that don't support the modeset API, to avoid\n-\t\t * selecting a DRM device corresponding to a GPU. There is no\n-\t\t * modeset capability, but the kernel returns an error for most\n-\t\t * caps if mode setting isn't support by the driver. The\n-\t\t * DRM_CAP_DUMB_BUFFER capability is one of those, other would\n-\t\t * do as well. The capability value itself isn't relevant.\n+\t\t * Skip non-display devices. While this could in theory be done\n+\t\t * by checking for support of the mode setting API, some\n+\t\t * out-of-tree render-only GPU drivers (namely powervr)\n+\t\t * incorrectly set the DRIVER_MODESET driver feature. Check for\n+\t\t * the presence of at least one CRTC, encoder and connector\n+\t\t * instead.\n \t\t */\n-\t\tret = drmGetCap(fd_, DRM_CAP_DUMB_BUFFER, &cap);\n-\t\tif (ret < 0) {\n+\t\tstd::unique_ptr<drmModeRes, decltype(&drmModeFreeResources)> resources{\n+\t\t\tdrmModeGetResources(fd_),\n+\t\t\t&drmModeFreeResources\n+\t\t};\n+\t\tif (!resources ||\n+\t\t    resources->count_connectors <= 0 ||\n+\t\t    resources->count_crtcs <= 0 ||\n+\t\t    resources->count_encoders <= 0) {\n+\t\t\tresources.reset();\n \t\t\tdrmClose(fd_);\n \t\t\tfd_ = -1;\n \t\t\tcontinue;\n",
    "prefixes": [
        "v4"
    ]
}