Skip to content

Commit

Permalink
Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu
Browse files Browse the repository at this point in the history
… into staging

UI patch queue

- vhost-user-gpu: support dmabuf modifiers
- fix VNC crash when there are no active_console
- cleanups and refactoring in ui/vc code

# -----BEGIN PGP SIGNATURE-----
#
# iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmUAQX4cHG1hcmNhbmRy
# ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5Y4jD/4/whR7a1KZqHytl6sc
# cCQ0Xn0gpcPM8rn3tWItp2vAOlGmx8ACfAyXYa5QzO7pBOU/xoMJt8a99geNRXFu
# nN33UJ0NRAWW6V0/cF5AVe9clckzs1Vq4VX2ITP+VAG+c+kt4E3fgFn9o8nwnBrd
# zuiqYz4pO9yBVO/av/FZQcBY8s9/M8jrdraDNNhsY2O2k2zLTxt1xxNG5qeVvPUw
# 2RZyc/EOG7RzW8eUA55BW/NU8Olg5u7dxsB0jfYnWBQxknOy5c+wF9MTGJSKmdGk
# HmgfMns6intUdfHmmJuDpP1Tiy1sVK1lkrsMeeQ67M84lYZsrSI+kIG5+YbWN8vx
# mMB/qwDmNMVMnGiBN5/ktvAJwcilYBUqen0KFrEHBghTpGhqAVoBNCC1MT/9w/bO
# c3/E1viuCi8OamPixVu9LeqQsxuP2jK5qxjfyDYH87HdnljSY6wFbVzD/2zz5YNv
# 43JtEbP9bv1yyRRd+JTpD54vCK0IZK7MBR8MbJqfknpbEw1FSPofRQxCSe9BlSJ/
# nYamatH9I9i92kGg5eD573X+UcLX9eOPBw8gVNKxuttwSIW1cwjGKi12B9MiFMg7
# Z6jP3gvpe9DrYef+4Wojo1PAioyweZVG5IFtWIqXRZjPwAoIzzVgBcEtcq4qeZwX
# BAliXWeUcRGsbLorT3COx2DjBw==
# =Xsr0
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 12 Sep 2023 06:46:22 EDT
# gpg:                using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5
# gpg:                issuer "marcandre.lureau@redhat.com"
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full]
# gpg:                 aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full]
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276  F62D DAE8 E109 7596 9CE5

* tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu:
  ui: add precondition for dpy_get_ui_info()
  ui: fix crash when there are no active_console
  virtio-gpu/win32: set the destroy function on load
  ui/console: move DisplaySurface to its own header
  ui/vc: split off the VC part from console.c
  ui/vc: preliminary QemuTextConsole changes before split
  ui/console: remove redundant format field
  ui/vc: rename kbd_put to qemu_text_console functions
  ui/vc: remove kbd_put_keysym() and update function calls
  vmmouse: use explicit code
  vmmouse: replace DPRINTF with tracing
  vhost-user-gpu: support dmabuf modifiers
  contrib/vhost-user-gpu: add support for sending dmabuf modifiers
  docs: vhost-user-gpu: add protocol changes for dmabuf modifiers

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Sep 12, 2023
2 parents 9ef4977 + a92e7bb commit ad7a958
Show file tree
Hide file tree
Showing 22 changed files with 1,426 additions and 1,245 deletions.
5 changes: 4 additions & 1 deletion contrib/vhost-user-gpu/vhost-user-gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,7 @@ static gboolean
protocol_features_cb(gint fd, GIOCondition condition, gpointer user_data)
{
const uint64_t protocol_edid = (1 << VHOST_USER_GPU_PROTOCOL_F_EDID);
const uint64_t protocol_dmabuf2 = (1 << VHOST_USER_GPU_PROTOCOL_F_DMABUF2);
VuGpu *g = user_data;
uint64_t protocol_features;
VhostUserGpuMsg msg = {
Expand All @@ -1082,7 +1083,7 @@ protocol_features_cb(gint fd, GIOCondition condition, gpointer user_data)
return G_SOURCE_CONTINUE;
}

protocol_features &= protocol_edid;
protocol_features &= (protocol_edid | protocol_dmabuf2);

msg = (VhostUserGpuMsg) {
.request = VHOST_USER_GPU_SET_PROTOCOL_FEATURES,
Expand All @@ -1100,6 +1101,8 @@ protocol_features_cb(gint fd, GIOCondition condition, gpointer user_data)
exit(EXIT_FAILURE);
}

g->use_modifiers = !!(protocol_features & protocol_dmabuf2);

return G_SOURCE_REMOVE;
}

Expand Down
51 changes: 48 additions & 3 deletions contrib/vhost-user-gpu/virgl.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,37 @@ virgl_resource_detach_backing(VuGpu *g,
vg_cleanup_mapping_iov(g, res_iovs, num_iovs);
}

static int
virgl_get_resource_info_modifiers(uint32_t resource_id,
struct virgl_renderer_resource_info *info,
uint64_t *modifiers)
{
int ret;
#ifdef VIRGL_RENDERER_RESOURCE_INFO_EXT_VERSION
struct virgl_renderer_resource_info_ext info_ext;
ret = virgl_renderer_resource_get_info_ext(resource_id, &info_ext);
if (ret < 0) {
return ret;
}

*info = info_ext.base;
*modifiers = info_ext.modifiers;
#else
ret = virgl_renderer_resource_get_info(resource_id, info);
if (ret < 0) {
return ret;
}

/*
* Before virgl_renderer_resource_get_info_ext,
* getting the modifiers was not possible.
*/
*modifiers = 0;
#endif

return 0;
}

static void
virgl_cmd_set_scanout(VuGpu *g,
struct virtio_gpu_ctrl_command *cmd)
Expand All @@ -338,7 +369,9 @@ virgl_cmd_set_scanout(VuGpu *g,
memset(&info, 0, sizeof(info));

if (ss.resource_id && ss.r.width && ss.r.height) {
ret = virgl_renderer_resource_get_info(ss.resource_id, &info);
uint64_t modifiers = 0;
ret = virgl_get_resource_info_modifiers(ss.resource_id, &info,
&modifiers);
if (ret == -1) {
g_critical("%s: illegal resource specified %d\n",
__func__, ss.resource_id);
Expand All @@ -354,8 +387,6 @@ virgl_cmd_set_scanout(VuGpu *g,
}
assert(fd >= 0);
VhostUserGpuMsg msg = {
.request = VHOST_USER_GPU_DMABUF_SCANOUT,
.size = sizeof(VhostUserGpuDMABUFScanout),
.payload.dmabuf_scanout.scanout_id = ss.scanout_id,
.payload.dmabuf_scanout.x = ss.r.x,
.payload.dmabuf_scanout.y = ss.r.y,
Expand All @@ -367,6 +398,20 @@ virgl_cmd_set_scanout(VuGpu *g,
.payload.dmabuf_scanout.fd_flags = info.flags,
.payload.dmabuf_scanout.fd_drm_fourcc = info.drm_fourcc
};

if (g->use_modifiers) {
/*
* The mesage uses all the fields set in dmabuf_scanout plus
* modifiers which is appended after VhostUserGpuDMABUFScanout.
*/
msg.request = VHOST_USER_GPU_DMABUF_SCANOUT2;
msg.size = sizeof(VhostUserGpuDMABUFScanout2);
msg.payload.dmabuf_scanout2.modifier = modifiers;
} else {
msg.request = VHOST_USER_GPU_DMABUF_SCANOUT;
msg.size = sizeof(VhostUserGpuDMABUFScanout);
}

vg_send_msg(g, &msg, fd);
close(fd);
} else {
Expand Down
9 changes: 9 additions & 0 deletions contrib/vhost-user-gpu/vugpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ typedef enum VhostUserGpuRequest {
VHOST_USER_GPU_DMABUF_SCANOUT,
VHOST_USER_GPU_DMABUF_UPDATE,
VHOST_USER_GPU_GET_EDID,
VHOST_USER_GPU_DMABUF_SCANOUT2,
} VhostUserGpuRequest;

typedef struct VhostUserGpuDisplayInfoReply {
Expand Down Expand Up @@ -84,6 +85,11 @@ typedef struct VhostUserGpuDMABUFScanout {
int fd_drm_fourcc;
} QEMU_PACKED VhostUserGpuDMABUFScanout;

typedef struct VhostUserGpuDMABUFScanout2 {
struct VhostUserGpuDMABUFScanout dmabuf_scanout;
uint64_t modifier;
} QEMU_PACKED VhostUserGpuDMABUFScanout2;

typedef struct VhostUserGpuEdidRequest {
uint32_t scanout_id;
} QEMU_PACKED VhostUserGpuEdidRequest;
Expand All @@ -98,6 +104,7 @@ typedef struct VhostUserGpuMsg {
VhostUserGpuScanout scanout;
VhostUserGpuUpdate update;
VhostUserGpuDMABUFScanout dmabuf_scanout;
VhostUserGpuDMABUFScanout2 dmabuf_scanout2;
VhostUserGpuEdidRequest edid_req;
struct virtio_gpu_resp_edid resp_edid;
struct virtio_gpu_resp_display_info display_info;
Expand All @@ -112,6 +119,7 @@ static VhostUserGpuMsg m __attribute__ ((unused));
#define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4

#define VHOST_USER_GPU_PROTOCOL_F_EDID 0
#define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1

struct virtio_gpu_scanout {
uint32_t width, height;
Expand All @@ -132,6 +140,7 @@ typedef struct VuGpu {
bool virgl;
bool virgl_inited;
bool edid_inited;
bool use_modifiers;
uint32_t inflight;

struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
Expand Down
26 changes: 25 additions & 1 deletion docs/interop/vhost-user-gpu.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ VhostUserGpuEdidRequest
:scanout-id: ``u32``, the scanout to get edid from


VhostUserGpuDMABUFScanout2
^^^^^^^^^^^^^^^^^^^^^^^^^^

+----------------+----------+
| dmabuf_scanout | modifier |
+----------------+----------+

:dmabuf_scanout: ``VhostUserGpuDMABUFScanout``, filled as described in the
VhostUserGpuDMABUFScanout structure.

:modifier: ``u64``, the DMABUF modifiers


C structure
-----------

Expand Down Expand Up @@ -163,7 +176,8 @@ Protocol features

.. code:: c
#define VHOST_USER_GPU_PROTOCOL_F_EDID 0
#define VHOST_USER_GPU_PROTOCOL_F_EDID 0
#define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1
New messages and communication changes are negotiated thanks to the
``VHOST_USER_GPU_GET_PROTOCOL_FEATURES`` and
Expand Down Expand Up @@ -263,3 +277,13 @@ Message types
Retrieve the EDID data for a given scanout.
This message requires the ``VHOST_USER_GPU_PROTOCOL_F_EDID`` protocol
feature to be supported.

``VHOST_USER_GPU_DMABUF_SCANOUT2``
:id: 12
:request payload: ``VhostUserGpuDMABUFScanout2``
:reply payload: N/A

Same as VHOST_USER_GPU_DMABUF_SCANOUT, but also sends the dmabuf modifiers
appended to the message, which were not provided in the other message.
This message requires the ``VHOST_USER_GPU_PROTOCOL_F_DMABUF2`` protocol
feature to be supported.
17 changes: 16 additions & 1 deletion hw/display/vhost-user-gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ typedef enum VhostUserGpuRequest {
VHOST_USER_GPU_DMABUF_SCANOUT,
VHOST_USER_GPU_DMABUF_UPDATE,
VHOST_USER_GPU_GET_EDID,
VHOST_USER_GPU_DMABUF_SCANOUT2,
} VhostUserGpuRequest;

typedef struct VhostUserGpuDisplayInfoReply {
Expand Down Expand Up @@ -79,6 +80,11 @@ typedef struct VhostUserGpuDMABUFScanout {
int fd_drm_fourcc;
} QEMU_PACKED VhostUserGpuDMABUFScanout;

typedef struct VhostUserGpuDMABUFScanout2 {
struct VhostUserGpuDMABUFScanout dmabuf_scanout;
uint64_t modifier;
} QEMU_PACKED VhostUserGpuDMABUFScanout2;

typedef struct VhostUserGpuEdidRequest {
uint32_t scanout_id;
} QEMU_PACKED VhostUserGpuEdidRequest;
Expand All @@ -93,6 +99,7 @@ typedef struct VhostUserGpuMsg {
VhostUserGpuScanout scanout;
VhostUserGpuUpdate update;
VhostUserGpuDMABUFScanout dmabuf_scanout;
VhostUserGpuDMABUFScanout2 dmabuf_scanout2;
VhostUserGpuEdidRequest edid_req;
struct virtio_gpu_resp_edid resp_edid;
struct virtio_gpu_resp_display_info display_info;
Expand All @@ -107,6 +114,7 @@ static VhostUserGpuMsg m __attribute__ ((unused));
#define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4

#define VHOST_USER_GPU_PROTOCOL_F_EDID 0
#define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1

static void vhost_user_gpu_update_blocked(VhostUserGPU *g, bool blocked);

Expand Down Expand Up @@ -171,7 +179,8 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)
.flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
.size = sizeof(uint64_t),
.payload = {
.u64 = (1 << VHOST_USER_GPU_PROTOCOL_F_EDID)
.u64 = (1 << VHOST_USER_GPU_PROTOCOL_F_EDID) |
(1 << VHOST_USER_GPU_PROTOCOL_F_DMABUF2)
}
};

Expand Down Expand Up @@ -236,6 +245,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)

break;
}
case VHOST_USER_GPU_DMABUF_SCANOUT2:
case VHOST_USER_GPU_DMABUF_SCANOUT: {
VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout;
int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr);
Expand Down Expand Up @@ -269,6 +279,11 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)
.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;
}

dpy_gl_scanout_dmabuf(con, dmabuf);
break;
}
Expand Down
4 changes: 3 additions & 1 deletion hw/display/virtio-gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
g_free(res);
return -EINVAL;
}

#ifdef WIN32
pixman_image_set_destroy_function(res->image, win32_pixman_image_destroy, res->handle);
#endif

res->addrs = g_new(uint64_t, res->iov_cnt);
res->iov = g_new(struct iovec, res->iov_cnt);
Expand Down
10 changes: 10 additions & 0 deletions hw/i386/trace-events
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,13 @@ x86_pic_interrupt(int irqn, int level) "PIC interrupt #%d level:%d"
# port92.c
port92_read(uint8_t val) "port92: read 0x%02x"
port92_write(uint8_t val) "port92: write 0x%02x"

# vmmouse.c
vmmouse_get_status(void) ""
vmmouse_mouse_event(int x, int y, int dz, int buttons_state) "event: x=%d y=%d dz=%d state=%d"
vmmouse_init(void) ""
vmmouse_read_id(void) ""
vmmouse_request_relative(void) ""
vmmouse_request_absolute(void) ""
vmmouse_disable(void) ""
vmmouse_data(uint32_t size) "data: size=%" PRIu32
40 changes: 24 additions & 16 deletions hw/i386/vmmouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "cpu.h"
#include "qom/object.h"

#include "trace.h"

/* debug only vmmouse */
//#define DEBUG_VMMOUSE

Expand All @@ -50,11 +52,10 @@
#define VMMOUSE_RIGHT_BUTTON 0x10
#define VMMOUSE_MIDDLE_BUTTON 0x08

#ifdef DEBUG_VMMOUSE
#define DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
#else
#define DPRINTF(fmt, ...) do { } while (0)
#endif
#define VMMOUSE_MIN_X 0
#define VMMOUSE_MIN_Y 0
#define VMMOUSE_MAX_X 0xFFFF
#define VMMOUSE_MAX_Y 0xFFFF

#define TYPE_VMMOUSE "vmmouse"
OBJECT_DECLARE_SIMPLE_TYPE(VMMouseState, VMMOUSE)
Expand Down Expand Up @@ -93,7 +94,8 @@ static void vmmouse_set_data(const uint32_t *data)

static uint32_t vmmouse_get_status(VMMouseState *s)
{
DPRINTF("vmmouse_get_status()\n");
trace_vmmouse_get_status();

return (s->status << 16) | s->nb_queue;
}

Expand All @@ -105,8 +107,7 @@ static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_
if (s->nb_queue > (VMMOUSE_QUEUE_SIZE - 4))
return;

DPRINTF("vmmouse_mouse_event(%d, %d, %d, %d)\n",
x, y, dz, buttons_state);
trace_vmmouse_mouse_event(x, y, dz, buttons_state);

if ((buttons_state & MOUSE_EVENT_LBUTTON))
buttons |= VMMOUSE_LEFT_BUTTON;
Expand All @@ -116,8 +117,12 @@ static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_
buttons |= VMMOUSE_MIDDLE_BUTTON;

if (s->absolute) {
x <<= 1;
y <<= 1;
x = qemu_input_scale_axis(x,
INPUT_EVENT_ABS_MIN, INPUT_EVENT_ABS_MAX,
VMMOUSE_MIN_X, VMMOUSE_MAX_X);
y = qemu_input_scale_axis(y,
INPUT_EVENT_ABS_MIN, INPUT_EVENT_ABS_MAX,
VMMOUSE_MIN_Y, VMMOUSE_MAX_Y);
} else{
/* add for guest vmmouse driver to judge this is a relative packet. */
buttons |= VMMOUSE_RELATIVE_PACKET;
Expand Down Expand Up @@ -160,7 +165,7 @@ static void vmmouse_update_handler(VMMouseState *s, int absolute)

static void vmmouse_read_id(VMMouseState *s)
{
DPRINTF("vmmouse_read_id()\n");
trace_vmmouse_read_id();

if (s->nb_queue == VMMOUSE_QUEUE_SIZE)
return;
Expand All @@ -172,19 +177,22 @@ static void vmmouse_read_id(VMMouseState *s)

static void vmmouse_request_relative(VMMouseState *s)
{
DPRINTF("vmmouse_request_relative()\n");
trace_vmmouse_request_relative();

vmmouse_update_handler(s, 0);
}

static void vmmouse_request_absolute(VMMouseState *s)
{
DPRINTF("vmmouse_request_absolute()\n");
trace_vmmouse_request_absolute();

vmmouse_update_handler(s, 1);
}

static void vmmouse_disable(VMMouseState *s)
{
DPRINTF("vmmouse_disable()\n");
trace_vmmouse_disable();

s->status = 0xffff;
vmmouse_remove_handler(s);
}
Expand All @@ -193,7 +201,7 @@ static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size)
{
int i;

DPRINTF("vmmouse_data(%d)\n", size);
trace_vmmouse_data(size);

if (size == 0 || size > 6 || size > s->nb_queue) {
printf("vmmouse: driver requested too much data %d\n", size);
Expand Down Expand Up @@ -293,7 +301,7 @@ static void vmmouse_realizefn(DeviceState *dev, Error **errp)
{
VMMouseState *s = VMMOUSE(dev);

DPRINTF("vmmouse_init\n");
trace_vmmouse_init();

if (!s->i8042) {
error_setg(errp, "'i8042' link is not set");
Expand Down

0 comments on commit ad7a958

Please sign in to comment.