2
0

vugpu.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Virtio vhost-user GPU Device
  3. *
  4. * Copyright Red Hat, Inc. 2013-2018
  5. *
  6. * Authors:
  7. * Dave Airlie <airlied@redhat.com>
  8. * Gerd Hoffmann <kraxel@redhat.com>
  9. * Marc-André Lureau <marcandre.lureau@redhat.com>
  10. *
  11. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  12. * See the COPYING file in the top-level directory.
  13. */
  14. #ifndef VUGPU_H
  15. #define VUGPU_H
  16. #include "libvhost-user-glib.h"
  17. #include "standard-headers/linux/virtio_gpu.h"
  18. #include "qemu/queue.h"
  19. #include "qemu/iov.h"
  20. #include "qemu/bswap.h"
  21. #include "vugbm.h"
  22. typedef enum VhostUserGpuRequest {
  23. VHOST_USER_GPU_NONE = 0,
  24. VHOST_USER_GPU_GET_PROTOCOL_FEATURES,
  25. VHOST_USER_GPU_SET_PROTOCOL_FEATURES,
  26. VHOST_USER_GPU_GET_DISPLAY_INFO,
  27. VHOST_USER_GPU_CURSOR_POS,
  28. VHOST_USER_GPU_CURSOR_POS_HIDE,
  29. VHOST_USER_GPU_CURSOR_UPDATE,
  30. VHOST_USER_GPU_SCANOUT,
  31. VHOST_USER_GPU_UPDATE,
  32. VHOST_USER_GPU_DMABUF_SCANOUT,
  33. VHOST_USER_GPU_DMABUF_UPDATE,
  34. VHOST_USER_GPU_GET_EDID,
  35. VHOST_USER_GPU_DMABUF_SCANOUT2,
  36. } VhostUserGpuRequest;
  37. typedef struct VhostUserGpuDisplayInfoReply {
  38. struct virtio_gpu_resp_display_info info;
  39. } VhostUserGpuDisplayInfoReply;
  40. typedef struct VhostUserGpuCursorPos {
  41. uint32_t scanout_id;
  42. uint32_t x;
  43. uint32_t y;
  44. } QEMU_PACKED VhostUserGpuCursorPos;
  45. typedef struct VhostUserGpuCursorUpdate {
  46. VhostUserGpuCursorPos pos;
  47. uint32_t hot_x;
  48. uint32_t hot_y;
  49. uint32_t data[64 * 64];
  50. } QEMU_PACKED VhostUserGpuCursorUpdate;
  51. typedef struct VhostUserGpuScanout {
  52. uint32_t scanout_id;
  53. uint32_t width;
  54. uint32_t height;
  55. } QEMU_PACKED VhostUserGpuScanout;
  56. typedef struct VhostUserGpuUpdate {
  57. uint32_t scanout_id;
  58. uint32_t x;
  59. uint32_t y;
  60. uint32_t width;
  61. uint32_t height;
  62. uint8_t data[];
  63. } QEMU_PACKED VhostUserGpuUpdate;
  64. typedef struct VhostUserGpuDMABUFScanout {
  65. uint32_t scanout_id;
  66. uint32_t x;
  67. uint32_t y;
  68. uint32_t width;
  69. uint32_t height;
  70. uint32_t fd_width;
  71. uint32_t fd_height;
  72. uint32_t fd_stride;
  73. uint32_t fd_flags;
  74. int fd_drm_fourcc;
  75. } QEMU_PACKED VhostUserGpuDMABUFScanout;
  76. typedef struct VhostUserGpuDMABUFScanout2 {
  77. struct VhostUserGpuDMABUFScanout dmabuf_scanout;
  78. uint64_t modifier;
  79. } QEMU_PACKED VhostUserGpuDMABUFScanout2;
  80. typedef struct VhostUserGpuEdidRequest {
  81. uint32_t scanout_id;
  82. } QEMU_PACKED VhostUserGpuEdidRequest;
  83. typedef struct VhostUserGpuMsg {
  84. uint32_t request; /* VhostUserGpuRequest */
  85. uint32_t flags;
  86. uint32_t size; /* the following payload size */
  87. union {
  88. VhostUserGpuCursorPos cursor_pos;
  89. VhostUserGpuCursorUpdate cursor_update;
  90. VhostUserGpuScanout scanout;
  91. VhostUserGpuUpdate update;
  92. VhostUserGpuDMABUFScanout dmabuf_scanout;
  93. VhostUserGpuDMABUFScanout2 dmabuf_scanout2;
  94. VhostUserGpuEdidRequest edid_req;
  95. struct virtio_gpu_resp_edid resp_edid;
  96. struct virtio_gpu_resp_display_info display_info;
  97. uint64_t u64;
  98. } payload;
  99. } QEMU_PACKED VhostUserGpuMsg;
  100. static VhostUserGpuMsg m __attribute__ ((unused));
  101. #define VHOST_USER_GPU_HDR_SIZE \
  102. (sizeof(m.request) + sizeof(m.flags) + sizeof(m.size))
  103. #define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4
  104. #define VHOST_USER_GPU_PROTOCOL_F_EDID 0
  105. #define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1
  106. struct virtio_gpu_scanout {
  107. uint32_t width, height;
  108. int x, y;
  109. int invalidate;
  110. uint32_t resource_id;
  111. };
  112. typedef struct VuGpu {
  113. VugDev dev;
  114. struct virtio_gpu_config virtio_config;
  115. struct vugbm_device gdev;
  116. int sock_fd;
  117. int drm_rnode_fd;
  118. GSource *renderer_source;
  119. guint wait_in;
  120. bool virgl;
  121. bool virgl_inited;
  122. bool edid_inited;
  123. bool use_modifiers;
  124. uint32_t inflight;
  125. struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
  126. QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
  127. QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
  128. } VuGpu;
  129. enum {
  130. VG_CMD_STATE_NEW,
  131. VG_CMD_STATE_PENDING,
  132. VG_CMD_STATE_FINISHED,
  133. };
  134. struct virtio_gpu_ctrl_command {
  135. VuVirtqElement elem;
  136. VuVirtq *vq;
  137. struct virtio_gpu_ctrl_hdr cmd_hdr;
  138. uint32_t error;
  139. int state;
  140. QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
  141. };
  142. #define VUGPU_FILL_CMD(out) do { \
  143. size_t vugpufillcmd_s_ = \
  144. iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
  145. &out, sizeof(out)); \
  146. if (vugpufillcmd_s_ != sizeof(out)) { \
  147. g_critical("%s: command size incorrect %zu vs %zu", \
  148. __func__, vugpufillcmd_s_, sizeof(out)); \
  149. return; \
  150. } \
  151. } while (0)
  152. void vg_ctrl_response(VuGpu *g,
  153. struct virtio_gpu_ctrl_command *cmd,
  154. struct virtio_gpu_ctrl_hdr *resp,
  155. size_t resp_len);
  156. void vg_ctrl_response_nodata(VuGpu *g,
  157. struct virtio_gpu_ctrl_command *cmd,
  158. enum virtio_gpu_ctrl_type type);
  159. int vg_create_mapping_iov(VuGpu *g,
  160. struct virtio_gpu_resource_attach_backing *ab,
  161. struct virtio_gpu_ctrl_command *cmd,
  162. struct iovec **iov);
  163. void vg_cleanup_mapping_iov(VuGpu *g, struct iovec *iov, uint32_t count);
  164. void vg_get_display_info(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
  165. void vg_get_edid(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
  166. void vg_wait_ok(VuGpu *g);
  167. void vg_send_msg(VuGpu *g, const VhostUserGpuMsg *msg, int fd);
  168. bool vg_recv_msg(VuGpu *g, uint32_t expect_req, uint32_t expect_size,
  169. gpointer payload);
  170. #endif