From patchwork Thu Apr 18 22:05:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Kim, Dongwon" X-Patchwork-Id: 13635494 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CC832C4345F for ; Thu, 18 Apr 2024 22:11:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rxZxM-0001Qs-RE; Thu, 18 Apr 2024 18:10:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rxZxI-0001Pp-C3 for qemu-devel@nongnu.org; Thu, 18 Apr 2024 18:10:08 -0400 Received: from mgamail.intel.com ([192.198.163.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rxZxF-00021j-Fs for qemu-devel@nongnu.org; Thu, 18 Apr 2024 18:10:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1713478205; x=1745014205; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/tJiyEAwp+9URmgUByfUb263mN4pJ4aBbqmvN/gziMo=; b=bFXBDc5RPTF0/24T8i1CEnieAdKU4UhlLiuVHa7Q/AXvRmWAw8j02sGr yzYBQqjOIe7pQDWZFluVS6IcPWRPpqBsm6w6H3JM1/PUQ+PiT7p0yyK7Q 2ZA9gvkZ+aGZSNS6gXVATQSxDy708zYzCA0gbyGMSa/qncXQrV2hs4iBV Obsyi/cpHlN749sL5OjGjRpaPHbskRh/7bCEbmW/luvD2AfMUolU+qYz0 HaEoJRqbQ3h+DXDfJLbJMVgEjA1LPzFyMA7Dw3U18h4V1ELbtTkdqk3BP i6/5jFoLen7/Uwe19D0MuQekNMquCBmkrJ8TGEfDv6wwtbtap+LFFl56H g==; X-CSE-ConnectionGUID: x4SVUvr/R0+4ZLnaFBh29w== X-CSE-MsgGUID: wYNd3fZATS+LqRyYlgHFHA== X-IronPort-AV: E=McAfee;i="6600,9927,11047"; a="12002032" X-IronPort-AV: E=Sophos;i="6.07,213,1708416000"; d="scan'208";a="12002032" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2024 15:09:55 -0700 X-CSE-ConnectionGUID: ylU4a/9UTeOIuRpw6rNCbQ== X-CSE-MsgGUID: HcBNYaItSnCQXuk0kyxdkQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,213,1708416000"; d="scan'208";a="60559331" Received: from dongwonk-z390-aorus-ultra.fm.intel.com ([10.105.129.124]) by orviesa001.jf.intel.com with ESMTP; 18 Apr 2024 15:09:56 -0700 From: dongwon.kim@intel.com To: qemu-devel@nongnu.org Cc: marcandre.lureau@redhat.com, berrange@redhat.com Subject: [PATCH v7 4/5] ui/console: Introduce qemu_dmabuf_new() and free() helpers Date: Thu, 18 Apr 2024 15:05:40 -0700 Message-Id: <20240418220541.931134-5-dongwon.kim@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240418220541.931134-1-dongwon.kim@intel.com> References: <20240418220541.931134-1-dongwon.kim@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.13; envelope-from=dongwon.kim@intel.com; helo=mgamail.intel.com X-Spam_score_int: -64 X-Spam_score: -6.5 X-Spam_bar: ------ X-Spam_report: (-6.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-2.067, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Dongwon Kim This commit introduces utility functions for the creation and deallocation of QemuDmaBuf instances. Additionally, it updates all relevant sections of the codebase to utilize these new utility functions. v7: remove prefix, "dpy_gl_" from all helpers qemu_dmabuf_free() returns without doing anything if input is null (Daniel P. Berrangé ) call G_DEFINE_AUTOPTR_CLEANUP_FUNC for qemu_dmabuf_free() (Daniel P. Berrangé ) Suggested-by: Marc-André Lureau Cc: Philippe Mathieu-Daudé Cc: Daniel P. Berrangé Cc: Vivek Kasireddy Signed-off-by: Dongwon Kim --- include/hw/vfio/vfio-common.h | 2 +- include/hw/virtio/virtio-gpu.h | 4 ++-- include/ui/console.h | 9 +++++++++ hw/display/vhost-user-gpu.c | 32 ++++++++++++++++------------- hw/display/virtio-gpu-udmabuf.c | 24 +++++++++------------- hw/vfio/display.c | 26 +++++++++++------------- ui/console.c | 36 +++++++++++++++++++++++++++++++++ ui/dbus-listener.c | 28 +++++++++++-------------- 8 files changed, 99 insertions(+), 62 deletions(-) diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index b9da6c08ef..d66e27db02 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -148,7 +148,7 @@ typedef struct VFIOGroup { } VFIOGroup; typedef struct VFIODMABuf { - QemuDmaBuf buf; + QemuDmaBuf *buf; uint32_t pos_x, pos_y, pos_updates; uint32_t hot_x, hot_y, hot_updates; int dmabuf_id; diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index ed44cdad6b..56d6e821bf 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -169,7 +169,7 @@ struct VirtIOGPUBaseClass { DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800) typedef struct VGPUDMABuf { - QemuDmaBuf buf; + QemuDmaBuf *buf; uint32_t scanout_id; QTAILQ_ENTRY(VGPUDMABuf) next; } VGPUDMABuf; @@ -238,7 +238,7 @@ struct VhostUserGPU { VhostUserBackend *vhost; int vhost_gpu_fd; /* closed by the chardev */ CharBackend vhost_chr; - QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS]; + QemuDmaBuf *dmabuf[VIRTIO_GPU_MAX_SCANOUTS]; bool backend_blocked; }; diff --git a/include/ui/console.h b/include/ui/console.h index 92a7d0d468..b47135bc2f 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -358,6 +358,15 @@ void dpy_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, bool have_hot, uint32_t hot_x, uint32_t hot_y); void dpy_gl_cursor_position(QemuConsole *con, uint32_t pos_x, uint32_t pos_y); +QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, + uint32_t stride, uint32_t x, + uint32_t y, uint32_t backing_width, + uint32_t backing_height, uint32_t fourcc, + uint64_t modifier, int32_t dmabuf_fd, + bool allow_fences, bool y0_top); +void qemu_dmabuf_free(QemuDmaBuf *dmabuf); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuDmaBuf, qemu_dmabuf_free); int32_t qemu_dmabuf_get_fd(QemuDmaBuf *dmabuf); uint32_t qemu_dmabuf_get_width(QemuDmaBuf *dmabuf); diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index ea9a6c5d10..7f8cf38647 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -250,6 +250,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout; int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr); int old_fd; + uint64_t modifier = 0; QemuDmaBuf *dmabuf; if (m->scanout_id >= g->parent_obj.conf.max_outputs) { @@ -262,31 +263,34 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) g->parent_obj.enable = 1; con = g->parent_obj.scanout[m->scanout_id].con; - dmabuf = &g->dmabuf[m->scanout_id]; - old_fd = qemu_dmabuf_get_fd(dmabuf); - if (old_fd >= 0) { - close(old_fd); - dmabuf->fd = -1; + dmabuf = g->dmabuf[m->scanout_id]; + if (dmabuf) { + old_fd = qemu_dmabuf_get_fd(dmabuf); + if (old_fd >= 0) { + close(old_fd); + qemu_dmabuf_set_fd(dmabuf, -1); + } } dpy_gl_release_dmabuf(con, dmabuf); + g_clear_pointer(&dmabuf, qemu_dmabuf_free); if (fd == -1) { dpy_gl_scanout_disable(con); break; } - *dmabuf = (QemuDmaBuf) { - .fd = fd, - .width = m->fd_width, - .height = m->fd_height, - .stride = m->fd_stride, - .fourcc = m->fd_drm_fourcc, - .y0_top = m->fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP, - }; + if (msg->request == VHOST_USER_GPU_DMABUF_SCANOUT2) { VhostUserGpuDMABUFScanout2 *m2 = &msg->payload.dmabuf_scanout2; - dmabuf->modifier = m2->modifier; + modifier = m2->modifier; } + dmabuf = qemu_dmabuf_new(m->fd_width, m->fd_height, + m->fd_stride, 0, 0, 0, 0, + m->fd_drm_fourcc, modifier, + fd, false, m->fd_flags & + VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP); + dpy_gl_scanout_dmabuf(con, dmabuf); + g->dmabuf[m->scanout_id] = dmabuf; break; } case VHOST_USER_GPU_DMABUF_UPDATE: { diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c index c90eba281e..edd7886cf2 100644 --- a/hw/display/virtio-gpu-udmabuf.c +++ b/hw/display/virtio-gpu-udmabuf.c @@ -162,7 +162,8 @@ static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf) struct virtio_gpu_scanout *scanout; scanout = &g->parent_obj.scanout[dmabuf->scanout_id]; - dpy_gl_release_dmabuf(scanout->con, &dmabuf->buf); + dpy_gl_release_dmabuf(scanout->con, dmabuf->buf); + g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free); QTAILQ_REMOVE(&g->dmabuf.bufs, dmabuf, next); g_free(dmabuf); } @@ -181,17 +182,10 @@ static VGPUDMABuf } dmabuf = g_new0(VGPUDMABuf, 1); - dmabuf->buf.width = r->width; - dmabuf->buf.height = r->height; - dmabuf->buf.stride = fb->stride; - dmabuf->buf.x = r->x; - dmabuf->buf.y = r->y; - dmabuf->buf.backing_width = fb->width; - dmabuf->buf.backing_height = fb->height; - dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format); - dmabuf->buf.fd = res->dmabuf_fd; - dmabuf->buf.allow_fences = true; - dmabuf->buf.draw_submitted = false; + dmabuf->buf = qemu_dmabuf_new(r->width, r->height, fb->stride, + r->x, r->y, fb->width, fb->height, + qemu_pixman_to_drm_format(fb->format), + 0, res->dmabuf_fd, false, 0); dmabuf->scanout_id = scanout_id; QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next); @@ -217,11 +211,11 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g, old_primary = g->dmabuf.primary[scanout_id]; } - width = qemu_dmabuf_get_width(&new_primary->buf); - height = qemu_dmabuf_get_height(&new_primary->buf); + width = qemu_dmabuf_get_width(new_primary->buf); + height = qemu_dmabuf_get_height(new_primary->buf); g->dmabuf.primary[scanout_id] = new_primary; qemu_console_resize(scanout->con, width, height); - dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf); + dpy_gl_scanout_dmabuf(scanout->con, new_primary->buf); if (old_primary) { virtio_gpu_free_dmabuf(g, old_primary); diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 4861c8161d..ad15b383f5 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -241,14 +241,11 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev, dmabuf = g_new0(VFIODMABuf, 1); dmabuf->dmabuf_id = plane.dmabuf_id; - dmabuf->buf.width = plane.width; - dmabuf->buf.height = plane.height; - dmabuf->buf.backing_width = plane.width; - dmabuf->buf.backing_height = plane.height; - dmabuf->buf.stride = plane.stride; - dmabuf->buf.fourcc = plane.drm_format; - dmabuf->buf.modifier = plane.drm_format_mod; - dmabuf->buf.fd = fd; + dmabuf->buf = qemu_dmabuf_new(plane.width, plane.height, + plane.stride, 0, 0, plane.width, + plane.height, plane.drm_format, + plane.drm_format_mod, fd, false, 0); + if (plane_type == DRM_PLANE_TYPE_CURSOR) { vfio_display_update_cursor(dmabuf, &plane); } @@ -263,8 +260,9 @@ static void vfio_display_free_one_dmabuf(VFIODisplay *dpy, VFIODMABuf *dmabuf) QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next); - fd = qemu_dmabuf_get_fd(&dmabuf->buf); - dpy_gl_release_dmabuf(dpy->con, &dmabuf->buf); + fd = qemu_dmabuf_get_fd(dmabuf->buf); + dpy_gl_release_dmabuf(dpy->con, dmabuf->buf); + g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free); close(fd); g_free(dmabuf); } @@ -301,13 +299,13 @@ static void vfio_display_dmabuf_update(void *opaque) return; } - width = qemu_dmabuf_get_width(&primary->buf); - height = qemu_dmabuf_get_height(&primary->buf); + width = qemu_dmabuf_get_width(primary->buf); + height = qemu_dmabuf_get_height(primary->buf); if (dpy->dmabuf.primary != primary) { dpy->dmabuf.primary = primary; qemu_console_resize(dpy->con, width, height); - dpy_gl_scanout_dmabuf(dpy->con, &primary->buf); + dpy_gl_scanout_dmabuf(dpy->con, primary->buf); free_bufs = true; } @@ -321,7 +319,7 @@ static void vfio_display_dmabuf_update(void *opaque) if (cursor && (new_cursor || cursor->hot_updates)) { bool have_hot = (cursor->hot_x != 0xffffffff && cursor->hot_y != 0xffffffff); - dpy_gl_cursor_dmabuf(dpy->con, &cursor->buf, have_hot, + dpy_gl_cursor_dmabuf(dpy->con, cursor->buf, have_hot, cursor->hot_x, cursor->hot_y); cursor->hot_updates = 0; } else if (!cursor && new_cursor) { diff --git a/ui/console.c b/ui/console.c index bd16ea7a4a..101af3df4a 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1132,6 +1132,42 @@ void dpy_gl_cursor_position(QemuConsole *con, } } +QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, + uint32_t stride, uint32_t x, + uint32_t y, uint32_t backing_width, + uint32_t backing_height, uint32_t fourcc, + uint64_t modifier, int32_t dmabuf_fd, + bool allow_fences, bool y0_top) { + QemuDmaBuf *dmabuf; + + dmabuf = g_new0(QemuDmaBuf, 1); + + dmabuf->width = width; + dmabuf->height = height; + dmabuf->stride = stride; + dmabuf->x = x; + dmabuf->y = y; + dmabuf->backing_width = backing_width; + dmabuf->backing_height = backing_height; + dmabuf->fourcc = fourcc; + dmabuf->modifier = modifier; + dmabuf->fd = dmabuf_fd; + dmabuf->allow_fences = allow_fences; + dmabuf->y0_top = y0_top; + dmabuf->fence_fd = -1; + + return dmabuf; +} + +void qemu_dmabuf_free(QemuDmaBuf *dmabuf) +{ + if (dmabuf == NULL) { + return; + } + + g_free(dmabuf); +} + int32_t qemu_dmabuf_get_fd(QemuDmaBuf *dmabuf) { assert(dmabuf != NULL); diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 62d1e2d3f9..f1775a0a39 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -442,28 +442,24 @@ static void dbus_scanout_texture(DisplayChangeListener *dcl, trace_dbus_scanout_texture(tex_id, backing_y_0_top, backing_width, backing_height, x, y, w, h); #ifdef CONFIG_GBM - QemuDmaBuf dmabuf = { - .width = w, - .height = h, - .y0_top = backing_y_0_top, - .x = x, - .y = y, - .backing_width = backing_width, - .backing_height = backing_height, - }; + int32_t fd; + uint32_t stride, fourcc; + uint64_t modifier; + QemuDmaBuf *dmabuf; assert(tex_id); - dmabuf.fd = egl_get_fd_for_texture( - tex_id, (EGLint *)&dmabuf.stride, - (EGLint *)&dmabuf.fourcc, - &dmabuf.modifier); - if (dmabuf.fd < 0) { + fd = egl_get_fd_for_texture(tex_id, (EGLint *)&stride, (EGLint *)&fourcc, + &modifier); + if (fd < 0) { error_report("%s: failed to get fd for texture", __func__); return; } + dmabuf = qemu_dmabuf_new(w, h, stride, x, y, backing_width, + backing_height, fourcc, modifier, fd, + false, backing_y_0_top); - dbus_scanout_dmabuf(dcl, &dmabuf); - close(dmabuf.fd); + dbus_scanout_dmabuf(dcl, dmabuf); + close(fd); #endif #ifdef WIN32