From patchwork Tue Oct 10 14:03:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 823857 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yBJp857Ftz9t4V for ; Wed, 11 Oct 2017 01:07:11 +1100 (AEDT) Received: from localhost ([::1]:35255 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1vBW-0003uS-Ir for incoming@patchwork.ozlabs.org; Tue, 10 Oct 2017 10:07:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41532) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v8M-0001jY-0c for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1v8H-00047o-A4 for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35983) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1v8H-00047P-1c for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:41 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 191C17EA96; Tue, 10 Oct 2017 14:03:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 191C17EA96 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kraxel@redhat.com Received: from sirius.home.kraxel.org (ovpn-116-239.ams2.redhat.com [10.36.116.239]) by smtp.corp.redhat.com (Postfix) with ESMTP id 04FAB60E3F; Tue, 10 Oct 2017 14:03:35 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 3848F16A887; Tue, 10 Oct 2017 16:03:34 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 10 Oct 2017 16:03:29 +0200 Message-Id: <20171010140334.8231-2-kraxel@redhat.com> In-Reply-To: <20171010140334.8231-1-kraxel@redhat.com> References: <20171010140334.8231-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 10 Oct 2017 14:03:40 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RfC PATCH 1/6] headers: update linux-headers/linux/vfio.h (intel-gvt kernel patches, v15) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann , Tina Zhang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Gerd Hoffmann --- linux-headers/linux/vfio.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h index 4e7ab4c52a..ff30feb1eb 100644 --- a/linux-headers/linux/vfio.h +++ b/linux-headers/linux/vfio.h @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset { #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13) +/** + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14, + * struct vfio_device_query_gfx_plane) + * + * Set the drm_plane_type and flags, then retrieve the gfx plane info. + * + * flags supported: + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no + * support for dma-buf. + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set + * to ask if the mdev supports region. 0 on support, -EINVAL on no + * support for region. + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set + * with each call to query the plane info. + * - Others are invalid and return -EINVAL. + * + * Return: 0 on success, -ENODEV with all out fields zero on mdev + * device initialization, -errno on other failure. + */ +struct vfio_device_gfx_plane_info { + __u32 argsz; + __u32 flags; +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0) +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1) +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2) + /* in */ + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */ + /* out */ + __u32 drm_format; /* drm format of plane */ + __u64 drm_format_mod; /* tiled mode */ + __u32 width; /* width of plane */ + __u32 height; /* height of plane */ + __u32 stride; /* stride of plane */ + __u32 size; /* size of plane in bytes, align on page*/ + __u32 x_pos; /* horizontal position of cursor plane */ + __u32 y_pos; /* vertical position of cursor plane*/ + union { + __u32 region_index; /* region index */ + __s32 dmabuf_id; /* dma-buf fd */ + }; +}; + +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14) + +/** + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, + * struct vfio_device_gfx_dmabuf_fd) + * + * Return: 0 on success, -errno on failure. + */ +struct vfio_device_gfx_dmabuf_fd { + __u32 argsz; + __u32 flags; + /* in */ + __u32 dmabuf_id; + /* out */ + __s32 dmabuf_fd; +}; + +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15) + /* -------- API for Type1 VFIO IOMMU -------- */ /** From patchwork Tue Oct 10 14:03:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 823858 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yBJp856x2z9s7G for ; Wed, 11 Oct 2017 01:07:11 +1100 (AEDT) Received: from localhost ([::1]:35256 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1vBc-000418-29 for incoming@patchwork.ozlabs.org; Tue, 10 Oct 2017 10:07:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41610) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v8U-0001nX-V7 for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1v8L-00049Y-9H for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59548) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1v8K-00048w-WE for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:45 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 03EE27C849; Tue, 10 Oct 2017 14:03:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 03EE27C849 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kraxel@redhat.com Received: from sirius.home.kraxel.org (ovpn-116-239.ams2.redhat.com [10.36.116.239]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0C600779D8; Tue, 10 Oct 2017 14:03:35 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 40E2616A88F; Tue, 10 Oct 2017 16:03:34 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 10 Oct 2017 16:03:30 +0200 Message-Id: <20171010140334.8231-3-kraxel@redhat.com> In-Reply-To: <20171010140334.8231-1-kraxel@redhat.com> References: <20171010140334.8231-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 10 Oct 2017 14:03:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RfC PATCH 2/6] headers: add drm/drm_fourcc.h to standard-headers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann , Tina Zhang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" So we can use the drm fourcc codes without a dependency on libdrm-devel. Signed-off-by: Gerd Hoffmann --- include/standard-headers/drm/drm_fourcc.h | 382 ++++++++++++++++++++++++++++++ scripts/update-linux-headers.sh | 4 + 2 files changed, 386 insertions(+) create mode 100644 include/standard-headers/drm/drm_fourcc.h diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h new file mode 100644 index 0000000000..5d7db07f98 --- /dev/null +++ b/include/standard-headers/drm/drm_fourcc.h @@ -0,0 +1,382 @@ +/* + * Copyright 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef DRM_FOURCC_H +#define DRM_FOURCC_H + + +#if defined(__cplusplus) +extern "C" { +#endif + +#define fourcc_code(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ + ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) + +#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */ + +/* color index */ +#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ') /* [7:0] C */ + +/* 8 bpp Red */ +#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */ + +/* 16 bpp Red */ +#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */ + +/* 16 bpp RG */ +#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */ +#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */ + +/* 32 bpp RG */ +#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2') /* [31:0] R:G 16:16 little endian */ +#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] G:R 16:16 little endian */ + +/* 8 bpp RGB */ +#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */ +#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */ + +/* 16 bpp RGB */ +#define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2') /* [15:0] x:R:G:B 4:4:4:4 little endian */ +#define DRM_FORMAT_XBGR4444 fourcc_code('X', 'B', '1', '2') /* [15:0] x:B:G:R 4:4:4:4 little endian */ +#define DRM_FORMAT_RGBX4444 fourcc_code('R', 'X', '1', '2') /* [15:0] R:G:B:x 4:4:4:4 little endian */ +#define DRM_FORMAT_BGRX4444 fourcc_code('B', 'X', '1', '2') /* [15:0] B:G:R:x 4:4:4:4 little endian */ + +#define DRM_FORMAT_ARGB4444 fourcc_code('A', 'R', '1', '2') /* [15:0] A:R:G:B 4:4:4:4 little endian */ +#define DRM_FORMAT_ABGR4444 fourcc_code('A', 'B', '1', '2') /* [15:0] A:B:G:R 4:4:4:4 little endian */ +#define DRM_FORMAT_RGBA4444 fourcc_code('R', 'A', '1', '2') /* [15:0] R:G:B:A 4:4:4:4 little endian */ +#define DRM_FORMAT_BGRA4444 fourcc_code('B', 'A', '1', '2') /* [15:0] B:G:R:A 4:4:4:4 little endian */ + +#define DRM_FORMAT_XRGB1555 fourcc_code('X', 'R', '1', '5') /* [15:0] x:R:G:B 1:5:5:5 little endian */ +#define DRM_FORMAT_XBGR1555 fourcc_code('X', 'B', '1', '5') /* [15:0] x:B:G:R 1:5:5:5 little endian */ +#define DRM_FORMAT_RGBX5551 fourcc_code('R', 'X', '1', '5') /* [15:0] R:G:B:x 5:5:5:1 little endian */ +#define DRM_FORMAT_BGRX5551 fourcc_code('B', 'X', '1', '5') /* [15:0] B:G:R:x 5:5:5:1 little endian */ + +#define DRM_FORMAT_ARGB1555 fourcc_code('A', 'R', '1', '5') /* [15:0] A:R:G:B 1:5:5:5 little endian */ +#define DRM_FORMAT_ABGR1555 fourcc_code('A', 'B', '1', '5') /* [15:0] A:B:G:R 1:5:5:5 little endian */ +#define DRM_FORMAT_RGBA5551 fourcc_code('R', 'A', '1', '5') /* [15:0] R:G:B:A 5:5:5:1 little endian */ +#define DRM_FORMAT_BGRA5551 fourcc_code('B', 'A', '1', '5') /* [15:0] B:G:R:A 5:5:5:1 little endian */ + +#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */ +#define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */ + +/* 24 bpp RGB */ +#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */ +#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */ + +/* 32 bpp RGB */ +#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ +#define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */ +#define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */ +#define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */ + +#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */ +#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */ +#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */ +#define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */ + +#define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0') /* [31:0] x:R:G:B 2:10:10:10 little endian */ +#define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0') /* [31:0] x:B:G:R 2:10:10:10 little endian */ +#define DRM_FORMAT_RGBX1010102 fourcc_code('R', 'X', '3', '0') /* [31:0] R:G:B:x 10:10:10:2 little endian */ +#define DRM_FORMAT_BGRX1010102 fourcc_code('B', 'X', '3', '0') /* [31:0] B:G:R:x 10:10:10:2 little endian */ + +#define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */ +#define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0') /* [31:0] A:B:G:R 2:10:10:10 little endian */ +#define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */ +#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */ + +/* packed YCbCr */ +#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ +#define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ +#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ +#define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ + +#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ + +/* 64 bpp RGB 16:16:16:16 Floating Point */ +#define DRM_FORMAT_XRGB161616F fourcc_code('X', 'R', '3', 'F') /* [63:0] x:R:G:B 16:16:16:16 little endian */ +#define DRM_FORMAT_XBGR161616F fourcc_code('X', 'B', '3', 'F') /* [63:0] x:B:G:R 16:16:16:16 little endian */ + +/* + * 2 plane RGB + A + * index 0 = RGB plane, same format as the corresponding non _A8 format has + * index 1 = A plane, [7:0] A + */ +#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8') +#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8') +#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8') +#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8') +#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8') +#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8') +#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8') +#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8') + +/* + * 2 plane YCbCr + * index 0 = Y plane, [7:0] Y + * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian + * or + * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian + */ +#define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */ +#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ +#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */ + +/* + * 3 plane YCbCr + * index 0: Y plane, [7:0] Y + * index 1: Cb plane, [7:0] Cb + * index 2: Cr plane, [7:0] Cr + * or + * index 1: Cr plane, [7:0] Cr + * index 2: Cb plane, [7:0] Cb + */ +#define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU411 fourcc_code('Y', 'V', '1', '1') /* 4x1 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU422 fourcc_code('Y', 'V', '1', '6') /* 2x1 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ + + +/* + * Format Modifiers: + * + * Format modifiers describe, typically, a re-ordering or modification + * of the data in a plane of an FB. This can be used to express tiled/ + * swizzled formats, or compression, or a combination of the two. + * + * The upper 8 bits of the format modifier are a vendor-id as assigned + * below. The lower 56 bits are assigned as vendor sees fit. + */ + +/* Vendor Ids: */ +#define DRM_FORMAT_MOD_NONE 0 +#define DRM_FORMAT_MOD_VENDOR_NONE 0 +#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01 +#define DRM_FORMAT_MOD_VENDOR_AMD 0x02 +#define DRM_FORMAT_MOD_VENDOR_NV 0x03 +#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04 +#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05 +#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06 +#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 +/* add more to the end as needed */ + +#define fourcc_mod_code(vendor, val) \ + ((((uint64_t)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) + +/* + * Format Modifier tokens: + * + * When adding a new token please document the layout with a code comment, + * similar to the fourcc codes above. drm_fourcc.h is considered the + * authoritative source for all of these. + */ + +/* + * Linear Layout + * + * Just plain linear layout. Note that this is different from no specifying any + * modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl), + * which tells the driver to also take driver-internal information into account + * and so might actually result in a tiled framebuffer. + */ +#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0) + +/* Intel framebuffer modifiers */ + +/* + * Intel X-tiling layout + * + * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) + * in row-major layout. Within the tile bytes are laid out row-major, with + * a platform-dependent stride. On top of that the memory can apply + * platform-depending swizzling of some higher address bits into bit6. + * + * This format is highly platforms specific and not useful for cross-driver + * sharing. It exists since on a given platform it does uniquely identify the + * layout in a simple way for i915-specific userspace. + */ +#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1) + +/* + * Intel Y-tiling layout + * + * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) + * in row-major layout. Within the tile bytes are laid out in OWORD (16 bytes) + * chunks column-major, with a platform-dependent height. On top of that the + * memory can apply platform-depending swizzling of some higher address bits + * into bit6. + * + * This format is highly platforms specific and not useful for cross-driver + * sharing. It exists since on a given platform it does uniquely identify the + * layout in a simple way for i915-specific userspace. + */ +#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2) + +/* + * Intel Yf-tiling layout + * + * This is a tiled layout using 4Kb tiles in row-major layout. + * Within the tile pixels are laid out in 16 256 byte units / sub-tiles which + * are arranged in four groups (two wide, two high) with column-major layout. + * Each group therefore consits out of four 256 byte units, which are also laid + * out as 2x2 column-major. + * 256 byte units are made out of four 64 byte blocks of pixels, producing + * either a square block or a 2:1 unit. + * 64 byte blocks of pixels contain four pixel rows of 16 bytes, where the width + * in pixel depends on the pixel depth. + */ +#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3) + +/* + * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks + * + * Macroblocks are laid in a Z-shape, and each pixel data is following the + * standard NV12 style. + * As for NV12, an image is the result of two frame buffers: one for Y, + * one for the interleaved Cb/Cr components (1/2 the height of the Y buffer). + * Alignment requirements are (for each buffer): + * - multiple of 128 pixels for the width + * - multiple of 32 pixels for the height + * + * For more information: see https://linuxtv.org/downloads/v4l-dvb-apis/re32.html + */ +#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1) + +/* Vivante framebuffer modifiers */ + +/* + * Vivante 4x4 tiling layout + * + * This is a simple tiled layout using tiles of 4x4 pixels in a row-major + * layout. + */ +#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1) + +/* + * Vivante 64x64 super-tiling layout + * + * This is a tiled layout using 64x64 pixel super-tiles, where each super-tile + * contains 8x4 groups of 2x4 tiles of 4x4 pixels (like above) each, all in row- + * major layout. + * + * For more information: see + * https://github.com/etnaviv/etna_viv/blob/master/doc/hardware.md#texture-tiling + */ +#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2) + +/* + * Vivante 4x4 tiling layout for dual-pipe + * + * Same as the 4x4 tiling layout, except every second 4x4 pixel tile starts at a + * different base address. Offsets from the base addresses are therefore halved + * compared to the non-split tiled layout. + */ +#define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3) + +/* + * Vivante 64x64 super-tiling layout for dual-pipe + * + * Same as the 64x64 super-tiling layout, except every second 4x4 pixel tile + * starts at a different base address. Offsets from the base addresses are + * therefore halved compared to the non-split super-tiled layout. + */ +#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4) + +/* NVIDIA Tegra frame buffer modifiers */ + +/* + * Some modifiers take parameters, for example the number of vertical GOBs in + * a block. Reserve the lower 32 bits for parameters + */ +#define __fourcc_mod_tegra_mode_shift 32 +#define fourcc_mod_tegra_code(val, params) \ + fourcc_mod_code(NV, ((((uint64_t)val) << __fourcc_mod_tegra_mode_shift) | params)) +#define fourcc_mod_tegra_mod(m) \ + (m & ~((1ULL << __fourcc_mod_tegra_mode_shift) - 1)) +#define fourcc_mod_tegra_param(m) \ + (m & ((1ULL << __fourcc_mod_tegra_mode_shift) - 1)) + +/* + * Tegra Tiled Layout, used by Tegra 2, 3 and 4. + * + * Pixels are arranged in simple tiles of 16 x 16 bytes. + */ +#define NV_FORMAT_MOD_TEGRA_TILED fourcc_mod_tegra_code(1, 0) + +/* + * Tegra 16Bx2 Block Linear layout, used by TK1/TX1 + * + * Pixels are arranged in 64x8 Groups Of Bytes (GOBs). GOBs are then stacked + * vertically by a power of 2 (1 to 32 GOBs) to form a block. + * + * Within a GOB, data is ordered as 16B x 2 lines sectors laid in Z-shape. + * + * Parameter 'v' is the log2 encoding of the number of GOBs stacked vertically. + * Valid values are: + * + * 0 == ONE_GOB + * 1 == TWO_GOBS + * 2 == FOUR_GOBS + * 3 == EIGHT_GOBS + * 4 == SIXTEEN_GOBS + * 5 == THIRTYTWO_GOBS + * + * Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format + * in full detail. + */ +#define NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(v) fourcc_mod_tegra_code(2, v) + +/* + * Broadcom VC4 "T" format + * + * This is the primary layout that the V3D GPU can texture from (it + * can't do linear). The T format has: + * + * - 64b utiles of pixels in a raster-order grid according to cpp. It's 4x4 + * pixels at 32 bit depth. + * + * - 1k subtiles made of a 4x4 raster-order grid of 64b utiles (so usually + * 16x16 pixels). + * + * - 4k tiles made of a 2x2 grid of 1k subtiles (so usually 32x32 pixels). On + * even 4k tile rows, they're arranged as (BL, TL, TR, BR), and on odd rows + * they're (TR, BR, BL, TL), where bottom left is start of memory. + * + * - an image made of 4k tiles in rows either left-to-right (even rows of 4k + * tiles) or right-to-left (odd rows of 4k tiles). + */ +#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1) + +#if defined(__cplusplus) +} +#endif + +#endif /* DRM_FOURCC_H */ diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index ad80fe3fca..8b847e279b 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -38,6 +38,7 @@ cp_portable() { -e 'linux/if_ether' \ -e 'input-event-codes' \ -e 'sys/' \ + -e 'drm.h' \ > /dev/null then echo "Unexpected #include in input file $f". @@ -54,6 +55,7 @@ cp_portable() { -e 's/__bitwise//' \ -e 's/__attribute__((packed))/QEMU_PACKED/' \ -e 's/__inline__/inline/' \ + -e '/\"drm.h\"/d' \ -e '/sys\/ioctl.h/d' \ -e 's/SW_MAX/SW_MAX_/' \ "$f" > "$to/$header"; @@ -147,6 +149,8 @@ for i in "$tmpdir"/include/linux/*virtio*.h "$tmpdir/include/linux/input.h" \ "$tmpdir/include/linux/pci_regs.h"; do cp_portable "$i" "$output/include/standard-headers/linux" done +mkdir -p "$output/include/standard-headers/drm" +cp_portable "$tmpdir/include/drm/drm_fourcc.h" "$output/include/standard-headers/drm" cat <$output/include/standard-headers/linux/types.h /* For QEMU all types are already defined via osdep.h, so this From patchwork Tue Oct 10 14:03:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 823853 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yBJl373dDz9t4V for ; Wed, 11 Oct 2017 01:04:31 +1100 (AEDT) Received: from localhost ([::1]:35242 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v94-0001jx-2L for incoming@patchwork.ozlabs.org; Tue, 10 Oct 2017 10:04:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41499) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v8K-0001jW-NH for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1v8G-00047Y-Pe for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:6055) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1v8G-00047A-Kn for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:40 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AE9DB806AA; Tue, 10 Oct 2017 14:03:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AE9DB806AA Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kraxel@redhat.com Received: from sirius.home.kraxel.org (ovpn-116-239.ams2.redhat.com [10.36.116.239]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0A6016954C; Tue, 10 Oct 2017 14:03:35 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 48DC916A89E; Tue, 10 Oct 2017 16:03:34 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 10 Oct 2017 16:03:31 +0200 Message-Id: <20171010140334.8231-4-kraxel@redhat.com> In-Reply-To: <20171010140334.8231-1-kraxel@redhat.com> References: <20171010140334.8231-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 10 Oct 2017 14:03:39 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RfC PATCH 3/6] ui/pixman: add qemu_drm_format_to_pixman() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann , Tina Zhang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Map drm fourcc codes to pixman formats. Signed-off-by: Gerd Hoffmann --- include/ui/qemu-pixman.h | 1 + ui/qemu-pixman.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index 4a67e01232..75661db080 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -51,6 +51,7 @@ PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format); pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian); +pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format); int qemu_pixman_get_type(int rshift, int gshift, int bshift); pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf); bool qemu_pixman_check_format(DisplayChangeListener *dcl, diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c index 6e591ab821..2c389ad323 100644 --- a/ui/qemu-pixman.c +++ b/ui/qemu-pixman.c @@ -6,6 +6,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "ui/console.h" +#include "standard-headers/drm/drm_fourcc.h" PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format) { @@ -88,6 +89,25 @@ pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian) return 0; } +/* Note: drm is little endian, pixman is native endian */ +pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format) +{ + static const struct { + uint32_t drm_format; + pixman_format_code_t pixman; + } map[] = { + { DRM_FORMAT_XRGB8888, PIXMAN_LE_x8r8g8b8 } + }; + int i; + + for (i = 0; i < ARRAY_SIZE(map); i++) { + if (drm_format == map[i].drm_format) { + return map[i].pixman; + } + } + return 0; +} + int qemu_pixman_get_type(int rshift, int gshift, int bshift) { int type = PIXMAN_TYPE_OTHER; From patchwork Tue Oct 10 14:03:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 823855 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yBJlC63Plz9t4V for ; Wed, 11 Oct 2017 01:04:39 +1100 (AEDT) Received: from localhost ([::1]:35244 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v9B-0001ni-Sc for incoming@patchwork.ozlabs.org; Tue, 10 Oct 2017 10:04:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41570) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v8Q-0001kS-KO for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1v8K-000495-Js for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59462) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1v8K-00048n-CA for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:44 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 68F397C838; Tue, 10 Oct 2017 14:03:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 68F397C838 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kraxel@redhat.com Received: from sirius.home.kraxel.org (ovpn-116-239.ams2.redhat.com [10.36.116.239]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0840F60A9B; Tue, 10 Oct 2017 14:03:35 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 52AB34FD40; Tue, 10 Oct 2017 16:03:34 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 10 Oct 2017 16:03:32 +0200 Message-Id: <20171010140334.8231-5-kraxel@redhat.com> In-Reply-To: <20171010140334.8231-1-kraxel@redhat.com> References: <20171010140334.8231-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 10 Oct 2017 14:03:43 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RfC PATCH 4/6] vfio/display: core & wireup X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann , Tina Zhang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Infrastructure for display support. Must be enabled using x-display property for now. Signed-off-by: Gerd Hoffmann --- hw/vfio/pci.h | 4 ++++ hw/vfio/display.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ hw/vfio/pci.c | 9 +++++++++ hw/vfio/Makefile.objs | 2 +- 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 hw/vfio/display.c diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index 502a5755b9..3c1b0a33ab 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -132,6 +132,8 @@ typedef struct VFIOPCIDevice { #define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2 #define VFIO_FEATURE_ENABLE_IGD_OPREGION \ (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT) +#define VFIO_FEATURE_ENABLE_DISPLAY_BIT 3 +#define VFIO_FEATURE_ENABLE_DISPLAY (1 << VFIO_FEATURE_ENABLE_DISPLAY_BIT) int32_t bootindex; uint32_t igd_gms; uint8_t pm_cap; @@ -171,4 +173,6 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, struct vfio_region_info *info, Error **errp); +int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp); + #endif /* HW_VFIO_VFIO_PCI_H */ diff --git a/hw/vfio/display.c b/hw/vfio/display.c new file mode 100644 index 0000000000..064ec95f3e --- /dev/null +++ b/hw/vfio/display.c @@ -0,0 +1,46 @@ +/* + * display support for mdev based vgpu devices + * + * Copyright Red Hat, Inc. 2017 + * + * Authors: + * Gerd Hoffmann + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include +#include + +#include "sysemu/sysemu.h" +#include "ui/console.h" +#include "pci.h" + +int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp) +{ + struct vfio_device_gfx_plane_info probe; + int ret; + + memset(&probe, 0, sizeof(probe)); + probe.argsz = sizeof(probe); + probe.flags = VFIO_GFX_PLANE_TYPE_PROBE | VFIO_GFX_PLANE_TYPE_DMABUF; + ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &probe); + if (ret == 0) { + error_setg(errp, "vfio-display: dmabuf support not implemented yet"); + return -1; + } + + memset(&probe, 0, sizeof(probe)); + probe.argsz = sizeof(probe); + probe.flags = VFIO_GFX_PLANE_TYPE_PROBE | VFIO_GFX_PLANE_TYPE_REGION; + ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &probe); + if (ret == 0) { + error_setg(errp, "vfio-display: region support not implemented yet"); + return -1; + } + + error_setg(errp, "vfio: device doesn't support any (known) display method"); + return -1; +} diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 9e86db7c3b..91ac7258a3 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -2873,6 +2873,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) } } + if (vdev->features & VFIO_FEATURE_ENABLE_DISPLAY) { + ret = vfio_display_probe(vdev, errp); + if (ret) { + goto out_teardown; + } + } + vfio_register_err_notifier(vdev); vfio_register_req_notifier(vdev); vfio_setup_resetfn_quirk(vdev); @@ -2985,6 +2992,8 @@ static Property vfio_pci_dev_properties[] = { VFIO_FEATURE_ENABLE_REQ_BIT, true), DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features, VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false), + DEFINE_PROP_BIT("x-display", VFIOPCIDevice, features, + VFIO_FEATURE_ENABLE_DISPLAY_BIT, false), DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false), DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false), DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false), diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index c3ab9097f1..a2e7a0a7cf 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -1,6 +1,6 @@ ifeq ($(CONFIG_LINUX), y) obj-$(CONFIG_SOFTMMU) += common.o -obj-$(CONFIG_PCI) += pci.o pci-quirks.o +obj-$(CONFIG_PCI) += pci.o pci-quirks.o display.o obj-$(CONFIG_VFIO_CCW) += ccw.o obj-$(CONFIG_SOFTMMU) += platform.o obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o From patchwork Tue Oct 10 14:03:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 823854 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yBJl74R9Lz9s7G for ; Wed, 11 Oct 2017 01:04:35 +1100 (AEDT) Received: from localhost ([::1]:35243 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v97-0001kt-N3 for incoming@patchwork.ozlabs.org; Tue, 10 Oct 2017 10:04:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41548) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v8O-0001ja-5c for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1v8J-00048P-0P for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46202) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1v8I-000482-OG for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:42 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C1ABBC059B63; Tue, 10 Oct 2017 14:03:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C1ABBC059B63 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kraxel@redhat.com Received: from sirius.home.kraxel.org (ovpn-116-239.ams2.redhat.com [10.36.116.239]) by smtp.corp.redhat.com (Postfix) with ESMTP id E08CF69549; Tue, 10 Oct 2017 14:03:40 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 5ABB74FD41; Tue, 10 Oct 2017 16:03:34 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 10 Oct 2017 16:03:33 +0200 Message-Id: <20171010140334.8231-6-kraxel@redhat.com> In-Reply-To: <20171010140334.8231-1-kraxel@redhat.com> References: <20171010140334.8231-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 10 Oct 2017 14:03:41 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RfC PATCH 5/6] vfio/display: adding region support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann , Tina Zhang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Wire up region-based display. UNTESTED. Signed-off-by: Gerd Hoffmann --- hw/vfio/pci.h | 6 ++++ hw/vfio/display.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index 3c1b0a33ab..c03c4b3eb0 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -146,6 +146,12 @@ typedef struct VFIOPCIDevice { bool no_kvm_intx; bool no_kvm_msi; bool no_kvm_msix; + /* vgpu local display */ + QemuConsole *display_con; + uint32_t region_index; + uint32_t region_size; + void *region_mmap; + DisplaySurface *region_surface; } VFIOPCIDevice; uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 064ec95f3e..8211bcc6d4 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -18,6 +18,99 @@ #include "ui/console.h" #include "pci.h" +/* ---------------------------------------------------------------------- */ + +static void vfio_display_region_update(void *opaque) +{ + VFIOPCIDevice *vdev = opaque; + struct vfio_device_gfx_plane_info plane; + struct vfio_region_info *region = NULL; + pixman_format_code_t format = PIXMAN_x8r8g8b8; + int ret; + + memset(&plane, 0, sizeof(plane)); + plane.argsz = sizeof(plane); + plane.flags = VFIO_GFX_PLANE_TYPE_REGION; + ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &plane); + if (ret < 0) { + fprintf(stderr, "ioctl VFIO_DEVICE_QUERY_GFX_PLANE: %s\n", + strerror(errno)); + return; + } + if (!plane.drm_format || !plane.size) { + return; + } + format = qemu_drm_format_to_pixman(plane.drm_format); + + if (vdev->region_mmap && vdev->region_index != plane.region_index) { + /* region changed */ + munmap(vdev->region_mmap, vdev->region_size); + vdev->region_mmap = NULL; + vdev->region_surface = NULL; + } + + if (vdev->region_surface && + (surface_width(vdev->region_surface) != plane.width || + surface_height(vdev->region_surface) != plane.height || + surface_format(vdev->region_surface) != format)) { + /* size changed */ + vdev->region_surface = NULL; + } + + if (vdev->region_mmap == NULL) { + /* mmap region */ + ret = vfio_get_region_info(&vdev->vbasedev, plane.region_index, + ®ion); + if (ret != 0) { + fprintf(stderr, "%s: vfio_get_region_info(%d): %s\n", + __func__, plane.region_index, strerror(-ret)); + return; + } + vdev->region_size = region->size; + vdev->region_mmap = mmap(NULL, region->size, + PROT_READ, MAP_SHARED, + vdev->vbasedev.fd, + region->offset); + if (vdev->region_mmap == MAP_FAILED) { + fprintf(stderr, "%s: mmap region %d: %s\n", __func__, + plane.region_index, strerror(errno)); + vdev->region_mmap = NULL; + g_free(region); + return; + } + g_free(region); + } + + if (vdev->region_surface == NULL) { + /* create surface */ + vdev->region_surface = qemu_create_displaysurface_from + (plane.width, plane.height, format, + plane.stride, vdev->region_mmap); + dpy_gfx_replace_surface(vdev->display_con, vdev->region_surface); + } + + /* full screen update */ + dpy_gfx_update(vdev->display_con, 0, 0, + surface_width(vdev->region_surface), + surface_height(vdev->region_surface)); + +} + +static const GraphicHwOps vfio_display_region_ops = { + .gfx_update = vfio_display_region_update, +}; + +static int vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp) +{ + vdev->display_con = graphic_console_init(DEVICE(vdev), 0, + &vfio_display_region_ops, + vdev); + /* TODO: disable hotplug (there is no graphic_console_close) */ + return 0; +} + +/* ---------------------------------------------------------------------- */ + int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp) { struct vfio_device_gfx_plane_info probe; @@ -37,8 +130,7 @@ int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp) probe.flags = VFIO_GFX_PLANE_TYPE_PROBE | VFIO_GFX_PLANE_TYPE_REGION; ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &probe); if (ret == 0) { - error_setg(errp, "vfio-display: region support not implemented yet"); - return -1; + return vfio_display_region_init(vdev, errp); } error_setg(errp, "vfio: device doesn't support any (known) display method"); From patchwork Tue Oct 10 14:03:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 823859 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yBJr43zfxz9t4V for ; Wed, 11 Oct 2017 01:08:52 +1100 (AEDT) Received: from localhost ([::1]:35262 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1vDG-0005Kg-ML for incoming@patchwork.ozlabs.org; Tue, 10 Oct 2017 10:08:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41585) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1v8R-0001lE-Ho for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1v8L-00049y-Gk for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40192) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e1v8L-000499-8m for qemu-devel@nongnu.org; Tue, 10 Oct 2017 10:03:45 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 31BDA9091F; Tue, 10 Oct 2017 14:03:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 31BDA9091F Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kraxel@redhat.com Received: from sirius.home.kraxel.org (ovpn-116-239.ams2.redhat.com [10.36.116.239]) by smtp.corp.redhat.com (Postfix) with ESMTP id DE200675FA; Tue, 10 Oct 2017 14:03:40 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 62E894FD42; Tue, 10 Oct 2017 16:03:34 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 10 Oct 2017 16:03:34 +0200 Message-Id: <20171010140334.8231-7-kraxel@redhat.com> In-Reply-To: <20171010140334.8231-1-kraxel@redhat.com> References: <20171010140334.8231-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 10 Oct 2017 14:03:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RfC PATCH 6/6] vfio/display: add dmabuf support (v15) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann , Tina Zhang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Wire up dma-buf based display. TODO: drop debug code and messages. Signed-off-by: Gerd Hoffmann --- hw/vfio/pci.h | 12 ++++ hw/vfio/display.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 193 insertions(+), 2 deletions(-) diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index c03c4b3eb0..1ab6f6abde 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -19,6 +19,7 @@ #include "qemu/event_notifier.h" #include "qemu/queue.h" #include "qemu/timer.h" +#include "ui/console.h" #define PCI_ANY_ID (~0) @@ -98,6 +99,14 @@ typedef struct VFIOMSIXInfo { unsigned long *pending; } VFIOMSIXInfo; +typedef struct VFIODMABuf VFIODMABuf; +struct VFIODMABuf { + QemuDmaBuf buf; + uint32_t pos_x, pos_y; + int dmabuf_id; + QTAILQ_ENTRY(VFIODMABuf) next; +}; + typedef struct VFIOPCIDevice { PCIDevice pdev; VFIODevice vbasedev; @@ -152,6 +161,9 @@ typedef struct VFIOPCIDevice { uint32_t region_size; void *region_mmap; DisplaySurface *region_surface; + QTAILQ_HEAD(, VFIODMABuf) dmabufs; + VFIODMABuf *primary; + VFIODMABuf *cursor; } VFIOPCIDevice; uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 8211bcc6d4..f45fd1fb98 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -18,6 +18,186 @@ #include "ui/console.h" #include "pci.h" +/* FIXME */ +#ifndef DRM_PLANE_TYPE_PRIMARY +# define DRM_PLANE_TYPE_PRIMARY 1 +# define DRM_PLANE_TYPE_CURSOR 2 +#endif + +static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev, + uint32_t plane_type) +{ + struct vfio_device_gfx_plane_info plane; + struct vfio_device_gfx_dmabuf_fd gfd; + VFIODMABuf *dmabuf; + static int errcnt; + int ret; + + memset(&plane, 0, sizeof(plane)); + plane.argsz = sizeof(plane); + plane.flags = VFIO_GFX_PLANE_TYPE_DMABUF; + plane.drm_plane_type = plane_type; + ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &plane); + if (ret < 0) { + fprintf(stderr, "(%d) ioctl VFIO_DEVICE_QUERY_GFX_PLANE(%s): %s\r", + ++errcnt, + (plane_type == DRM_PLANE_TYPE_PRIMARY) ? "primary" : "cursor", + strerror(errno)); + fflush(stderr); + return NULL; + } + if (!plane.drm_format || !plane.size) { + fprintf(stderr, "(%d) %s plane not initialized by guest\r", + ++errcnt, + (plane_type == DRM_PLANE_TYPE_PRIMARY) ? "primary" : "cursor"); + fflush(stderr); + return NULL; + } + + QTAILQ_FOREACH(dmabuf, &vdev->dmabufs, next) { + if (dmabuf->dmabuf_id == plane.dmabuf_id) { + /* found in list, move to head, return it */ + QTAILQ_REMOVE(&vdev->dmabufs, dmabuf, next); + QTAILQ_INSERT_HEAD(&vdev->dmabufs, dmabuf, next); + if (plane_type == DRM_PLANE_TYPE_CURSOR) { + dmabuf->pos_x = plane.x_pos; + dmabuf->pos_y = plane.y_pos; + } +#if 1 + if (plane.width != dmabuf->buf.width || + plane.height != dmabuf->buf.height) { + fprintf(stderr, "%s: cached dmabuf mismatch: id %d, " + "kernel %dx%d, cached %dx%d, plane %s\n", + __func__, plane.dmabuf_id, + plane.width, plane.height, + dmabuf->buf.width, dmabuf->buf.height, + (plane_type == DRM_PLANE_TYPE_PRIMARY) + ? "primary" : "cursor"); + abort(); + } +#endif + return dmabuf; + } + } + + memset(&gfd, 0, sizeof(gfd)); + gfd.argsz = sizeof(gfd); + gfd.dmabuf_id = plane.dmabuf_id; + ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_GFX_DMABUF, &gfd); + if (ret < 0) { + fprintf(stderr, "(%d) ioctl VFIO_DEVICE_GET_GFX_DMABUF: %s\r", + ++errcnt, strerror(errno)); + return NULL; + } + + fprintf(stderr, "%s: new dmabuf: id %d, res %dx%d, " + "format %c%c%c%c, plane %s, fd %d, hot +%d+%d\n", + __func__, plane.dmabuf_id, + plane.width, plane.height, + (plane.drm_format >> 0) & 0xff, + (plane.drm_format >> 8) & 0xff, + (plane.drm_format >> 16) & 0xff, + (plane.drm_format >> 24) & 0xff, + (plane_type == DRM_PLANE_TYPE_PRIMARY) ? "primary" : "cursor", + gfd.dmabuf_fd, + plane.x_pos, plane.y_pos); + + dmabuf = g_new0(VFIODMABuf, 1); + dmabuf->dmabuf_id = plane.dmabuf_id; + dmabuf->buf.width = plane.width; + dmabuf->buf.height = plane.height; + dmabuf->buf.stride = plane.stride; + dmabuf->buf.fourcc = plane.drm_format; + dmabuf->buf.fd = gfd.dmabuf_fd; + if (plane_type == DRM_PLANE_TYPE_CURSOR) { + dmabuf->pos_x = plane.x_pos; + dmabuf->pos_y = plane.y_pos; + } + + QTAILQ_INSERT_HEAD(&vdev->dmabufs, dmabuf, next); + return dmabuf; +} + +static void vfio_display_free_dmabufs(VFIOPCIDevice *vdev) +{ + char log[128]; int pos = 0; + VFIODMABuf *dmabuf, *tmp; + uint32_t keep = 8; + + QTAILQ_FOREACH_SAFE(dmabuf, &vdev->dmabufs, next, tmp) { + if (keep > 0) { + pos += sprintf(log + pos, " %d", dmabuf->buf.fd); + keep--; + continue; + } + assert(dmabuf != vdev->primary); + QTAILQ_REMOVE(&vdev->dmabufs, dmabuf, next); + fprintf(stderr, "%s: free dmabuf: fd %d (keep%s)\n", + __func__, dmabuf->buf.fd, log); + dpy_gl_release_dmabuf(vdev->display_con, &dmabuf->buf); + close(dmabuf->buf.fd); + g_free(dmabuf); + } +} + +static void vfio_display_dmabuf_update(void *opaque) +{ + VFIOPCIDevice *vdev = opaque; + VFIODMABuf *primary, *cursor; + bool free_bufs = false; + + primary = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_PRIMARY); + if (primary == NULL) { + return; + } + + if (vdev->primary != primary) { + vdev->primary = primary; + qemu_console_resize(vdev->display_con, + primary->buf.width, primary->buf.height); + dpy_gl_scanout_dmabuf(vdev->display_con, + &primary->buf); + free_bufs = true; + } + + cursor = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_CURSOR); + if (vdev->cursor != cursor) { + vdev->cursor = cursor; + free_bufs = true; + } + if (cursor != NULL) { + dpy_gl_cursor_dmabuf(vdev->display_con, + &cursor->buf, + cursor->pos_x, + cursor->pos_y); + } + + dpy_gl_update(vdev->display_con, 0, 0, + primary->buf.width, primary->buf.height); + + if (free_bufs) { + vfio_display_free_dmabufs(vdev); + } +} + +static const GraphicHwOps vfio_display_dmabuf_ops = { + .gfx_update = vfio_display_dmabuf_update, +}; + +static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp) +{ + if (!display_opengl) { + error_setg(errp, "vfio-display-dmabuf: opengl not available"); + return -1; + } + + vdev->display_con = graphic_console_init(DEVICE(vdev), 0, + &vfio_display_dmabuf_ops, + vdev); + /* TODO: disable hotplug (there is no graphic_console_close) */ + return 0; +} + /* ---------------------------------------------------------------------- */ static void vfio_display_region_update(void *opaque) @@ -121,8 +301,7 @@ int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp) probe.flags = VFIO_GFX_PLANE_TYPE_PROBE | VFIO_GFX_PLANE_TYPE_DMABUF; ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_QUERY_GFX_PLANE, &probe); if (ret == 0) { - error_setg(errp, "vfio-display: dmabuf support not implemented yet"); - return -1; + return vfio_display_dmabuf_init(vdev, errp); } memset(&probe, 0, sizeof(probe));