mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-31 04:06:46 +00:00 
			
		
		
		
	 3ea32d1355
			
		
	
	
		3ea32d1355
		
	
	
	
	
		
			
			Currently in vhost-user-gpu, we free resource directly in the cleanup case of resource. If we change the cleanup logic we need to change several places, also abstruct a 'vg_create_mapping_iov' can be symmetry with the 'vg_create_mapping_iov'. This is like what virtio-gpu does, no function changed. Signed-off-by: Li Qiang <liq3ea@163.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20210516030403.107723-9-liq3ea@163.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
		
			
				
	
	
		
			184 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Virtio vhost-user GPU Device
 | |
|  *
 | |
|  * Copyright Red Hat, Inc. 2013-2018
 | |
|  *
 | |
|  * Authors:
 | |
|  *     Dave Airlie <airlied@redhat.com>
 | |
|  *     Gerd Hoffmann <kraxel@redhat.com>
 | |
|  *     Marc-André Lureau <marcandre.lureau@redhat.com>
 | |
|  *
 | |
|  * This work is licensed under the terms of the GNU GPL, version 2 or later.
 | |
|  * See the COPYING file in the top-level directory.
 | |
|  */
 | |
| 
 | |
| #ifndef VUGPU_H
 | |
| #define VUGPU_H
 | |
| 
 | |
| 
 | |
| #include "libvhost-user-glib.h"
 | |
| #include "standard-headers/linux/virtio_gpu.h"
 | |
| 
 | |
| #include "qemu/queue.h"
 | |
| #include "qemu/iov.h"
 | |
| #include "qemu/bswap.h"
 | |
| #include "vugbm.h"
 | |
| 
 | |
| typedef enum VhostUserGpuRequest {
 | |
|     VHOST_USER_GPU_NONE = 0,
 | |
|     VHOST_USER_GPU_GET_PROTOCOL_FEATURES,
 | |
|     VHOST_USER_GPU_SET_PROTOCOL_FEATURES,
 | |
|     VHOST_USER_GPU_GET_DISPLAY_INFO,
 | |
|     VHOST_USER_GPU_CURSOR_POS,
 | |
|     VHOST_USER_GPU_CURSOR_POS_HIDE,
 | |
|     VHOST_USER_GPU_CURSOR_UPDATE,
 | |
|     VHOST_USER_GPU_SCANOUT,
 | |
|     VHOST_USER_GPU_UPDATE,
 | |
|     VHOST_USER_GPU_DMABUF_SCANOUT,
 | |
|     VHOST_USER_GPU_DMABUF_UPDATE,
 | |
| } VhostUserGpuRequest;
 | |
| 
 | |
| typedef struct VhostUserGpuDisplayInfoReply {
 | |
|     struct virtio_gpu_resp_display_info info;
 | |
| } VhostUserGpuDisplayInfoReply;
 | |
| 
 | |
| typedef struct VhostUserGpuCursorPos {
 | |
|     uint32_t scanout_id;
 | |
|     uint32_t x;
 | |
|     uint32_t y;
 | |
| } QEMU_PACKED VhostUserGpuCursorPos;
 | |
| 
 | |
| typedef struct VhostUserGpuCursorUpdate {
 | |
|     VhostUserGpuCursorPos pos;
 | |
|     uint32_t hot_x;
 | |
|     uint32_t hot_y;
 | |
|     uint32_t data[64 * 64];
 | |
| } QEMU_PACKED VhostUserGpuCursorUpdate;
 | |
| 
 | |
| typedef struct VhostUserGpuScanout {
 | |
|     uint32_t scanout_id;
 | |
|     uint32_t width;
 | |
|     uint32_t height;
 | |
| } QEMU_PACKED VhostUserGpuScanout;
 | |
| 
 | |
| typedef struct VhostUserGpuUpdate {
 | |
|     uint32_t scanout_id;
 | |
|     uint32_t x;
 | |
|     uint32_t y;
 | |
|     uint32_t width;
 | |
|     uint32_t height;
 | |
|     uint8_t data[];
 | |
| } QEMU_PACKED VhostUserGpuUpdate;
 | |
| 
 | |
| typedef struct VhostUserGpuDMABUFScanout {
 | |
|     uint32_t scanout_id;
 | |
|     uint32_t x;
 | |
|     uint32_t y;
 | |
|     uint32_t width;
 | |
|     uint32_t height;
 | |
|     uint32_t fd_width;
 | |
|     uint32_t fd_height;
 | |
|     uint32_t fd_stride;
 | |
|     uint32_t fd_flags;
 | |
|     int fd_drm_fourcc;
 | |
| } QEMU_PACKED VhostUserGpuDMABUFScanout;
 | |
| 
 | |
| typedef struct VhostUserGpuMsg {
 | |
|     uint32_t request; /* VhostUserGpuRequest */
 | |
|     uint32_t flags;
 | |
|     uint32_t size; /* the following payload size */
 | |
|     union {
 | |
|         VhostUserGpuCursorPos cursor_pos;
 | |
|         VhostUserGpuCursorUpdate cursor_update;
 | |
|         VhostUserGpuScanout scanout;
 | |
|         VhostUserGpuUpdate update;
 | |
|         VhostUserGpuDMABUFScanout dmabuf_scanout;
 | |
|         struct virtio_gpu_resp_display_info display_info;
 | |
|         uint64_t u64;
 | |
|     } payload;
 | |
| } QEMU_PACKED VhostUserGpuMsg;
 | |
| 
 | |
| static VhostUserGpuMsg m __attribute__ ((unused));
 | |
| #define VHOST_USER_GPU_HDR_SIZE \
 | |
|     (sizeof(m.request) + sizeof(m.flags) + sizeof(m.size))
 | |
| 
 | |
| #define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4
 | |
| 
 | |
| struct virtio_gpu_scanout {
 | |
|     uint32_t width, height;
 | |
|     int x, y;
 | |
|     int invalidate;
 | |
|     uint32_t resource_id;
 | |
| };
 | |
| 
 | |
| typedef struct VuGpu {
 | |
|     VugDev dev;
 | |
|     struct virtio_gpu_config virtio_config;
 | |
|     struct vugbm_device gdev;
 | |
|     int sock_fd;
 | |
|     int drm_rnode_fd;
 | |
|     GSource *renderer_source;
 | |
|     guint wait_in;
 | |
| 
 | |
|     bool virgl;
 | |
|     bool virgl_inited;
 | |
|     uint32_t inflight;
 | |
| 
 | |
|     struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
 | |
|     QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
 | |
|     QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
 | |
| } VuGpu;
 | |
| 
 | |
| enum {
 | |
|     VG_CMD_STATE_NEW,
 | |
|     VG_CMD_STATE_PENDING,
 | |
|     VG_CMD_STATE_FINISHED,
 | |
| };
 | |
| 
 | |
| struct virtio_gpu_ctrl_command {
 | |
|     VuVirtqElement elem;
 | |
|     VuVirtq *vq;
 | |
|     struct virtio_gpu_ctrl_hdr cmd_hdr;
 | |
|     uint32_t error;
 | |
|     int state;
 | |
|     QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
 | |
| };
 | |
| 
 | |
| #define VUGPU_FILL_CMD(out) do {                                \
 | |
|         size_t s;                                               \
 | |
|         s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
 | |
|                        &out, sizeof(out));                      \
 | |
|         if (s != sizeof(out)) {                                 \
 | |
|             g_critical("%s: command size incorrect %zu vs %zu", \
 | |
|                        __func__, s, sizeof(out));               \
 | |
|             return;                                             \
 | |
|         }                                                       \
 | |
|     } while (0)
 | |
| 
 | |
| 
 | |
| void    vg_ctrl_response(VuGpu *g,
 | |
|                          struct virtio_gpu_ctrl_command *cmd,
 | |
|                          struct virtio_gpu_ctrl_hdr *resp,
 | |
|                          size_t resp_len);
 | |
| 
 | |
| void    vg_ctrl_response_nodata(VuGpu *g,
 | |
|                                 struct virtio_gpu_ctrl_command *cmd,
 | |
|                                 enum virtio_gpu_ctrl_type type);
 | |
| 
 | |
| int     vg_create_mapping_iov(VuGpu *g,
 | |
|                               struct virtio_gpu_resource_attach_backing *ab,
 | |
|                               struct virtio_gpu_ctrl_command *cmd,
 | |
|                               struct iovec **iov);
 | |
| void    vg_cleanup_mapping_iov(VuGpu *g, struct iovec *iov, uint32_t count);
 | |
| void    vg_get_display_info(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
 | |
| 
 | |
| void    vg_wait_ok(VuGpu *g);
 | |
| 
 | |
| void    vg_send_msg(VuGpu *g, const VhostUserGpuMsg *msg, int fd);
 | |
| 
 | |
| bool    vg_recv_msg(VuGpu *g, uint32_t expect_req, uint32_t expect_size,
 | |
|                     gpointer payload);
 | |
| 
 | |
| 
 | |
| #endif
 |