4 * Copyright Red Hat, Inc. 2013-2014
7 * Dave Airlie <airlied@redhat.com>
8 * Gerd Hoffmann <kraxel@redhat.com>
10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
11 * See the COPYING file in the top-level directory.
14 #include "qemu/osdep.h"
16 #include "hw/virtio/virtio-gpu.h"
17 #include "migration/blocker.h"
18 #include "qapi/error.h"
19 #include "qemu/error-report.h"
23 virtio_gpu_base_reset(VirtIOGPUBase
*g
)
29 for (i
= 0; i
< g
->conf
.max_outputs
; i
++) {
30 g
->scanout
[i
].resource_id
= 0;
31 g
->scanout
[i
].width
= 0;
32 g
->scanout
[i
].height
= 0;
35 g
->scanout
[i
].ds
= NULL
;
40 virtio_gpu_base_fill_display_info(VirtIOGPUBase
*g
,
41 struct virtio_gpu_resp_display_info
*dpy_info
)
45 for (i
= 0; i
< g
->conf
.max_outputs
; i
++) {
46 if (g
->enabled_output_bitmask
& (1 << i
)) {
47 dpy_info
->pmodes
[i
].enabled
= 1;
48 dpy_info
->pmodes
[i
].r
.width
= cpu_to_le32(g
->req_state
[i
].width
);
49 dpy_info
->pmodes
[i
].r
.height
= cpu_to_le32(g
->req_state
[i
].height
);
54 static void virtio_gpu_invalidate_display(void *opaque
)
58 static void virtio_gpu_update_display(void *opaque
)
62 static void virtio_gpu_text_update(void *opaque
, console_ch_t
*chardata
)
66 static void virtio_gpu_notify_event(VirtIOGPUBase
*g
, uint32_t event_type
)
68 g
->virtio_config
.events_read
|= event_type
;
69 virtio_notify_config(&g
->parent_obj
);
72 static void virtio_gpu_ui_info(void *opaque
, uint32_t idx
, QemuUIInfo
*info
)
74 VirtIOGPUBase
*g
= opaque
;
76 if (idx
>= g
->conf
.max_outputs
) {
80 g
->req_state
[idx
].x
= info
->xoff
;
81 g
->req_state
[idx
].y
= info
->yoff
;
82 g
->req_state
[idx
].refresh_rate
= info
->refresh_rate
;
83 g
->req_state
[idx
].width
= info
->width
;
84 g
->req_state
[idx
].height
= info
->height
;
85 g
->req_state
[idx
].width_mm
= info
->width_mm
;
86 g
->req_state
[idx
].height_mm
= info
->height_mm
;
88 if (info
->width
&& info
->height
) {
89 g
->enabled_output_bitmask
|= (1 << idx
);
91 g
->enabled_output_bitmask
&= ~(1 << idx
);
94 /* send event to guest */
95 virtio_gpu_notify_event(g
, VIRTIO_GPU_EVENT_DISPLAY
);
100 virtio_gpu_gl_flushed(void *opaque
)
102 VirtIOGPUBase
*g
= opaque
;
103 VirtIOGPUBaseClass
*vgc
= VIRTIO_GPU_BASE_GET_CLASS(g
);
105 if (vgc
->gl_flushed
) {
111 virtio_gpu_gl_block(void *opaque
, bool block
)
113 VirtIOGPUBase
*g
= opaque
;
116 g
->renderer_blocked
++;
118 g
->renderer_blocked
--;
120 assert(g
->renderer_blocked
>= 0);
122 if (!block
&& g
->renderer_blocked
== 0) {
123 virtio_gpu_gl_flushed(g
);
128 virtio_gpu_get_flags(void *opaque
)
130 VirtIOGPUBase
*g
= opaque
;
131 int flags
= GRAPHIC_FLAGS_NONE
;
133 if (virtio_gpu_virgl_enabled(g
->conf
)) {
134 flags
|= GRAPHIC_FLAGS_GL
;
137 if (virtio_gpu_dmabuf_enabled(g
->conf
)) {
138 flags
|= GRAPHIC_FLAGS_DMABUF
;
144 static const GraphicHwOps virtio_gpu_ops
= {
145 .get_flags
= virtio_gpu_get_flags
,
146 .invalidate
= virtio_gpu_invalidate_display
,
147 .gfx_update
= virtio_gpu_update_display
,
148 .text_update
= virtio_gpu_text_update
,
149 .ui_info
= virtio_gpu_ui_info
,
150 .gl_block
= virtio_gpu_gl_block
,
154 virtio_gpu_base_device_realize(DeviceState
*qdev
,
155 VirtIOHandleOutput ctrl_cb
,
156 VirtIOHandleOutput cursor_cb
,
159 VirtIODevice
*vdev
= VIRTIO_DEVICE(qdev
);
160 VirtIOGPUBase
*g
= VIRTIO_GPU_BASE(qdev
);
163 if (g
->conf
.max_outputs
> VIRTIO_GPU_MAX_SCANOUTS
) {
164 error_setg(errp
, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS
);
168 if (virtio_gpu_virgl_enabled(g
->conf
)) {
169 error_setg(&g
->migration_blocker
, "virgl is not yet migratable");
170 if (migrate_add_blocker(g
->migration_blocker
, errp
) < 0) {
171 error_free(g
->migration_blocker
);
176 g
->virtio_config
.num_scanouts
= cpu_to_le32(g
->conf
.max_outputs
);
177 virtio_init(VIRTIO_DEVICE(g
), VIRTIO_ID_GPU
,
178 sizeof(struct virtio_gpu_config
));
180 if (virtio_gpu_virgl_enabled(g
->conf
)) {
181 /* use larger control queue in 3d mode */
182 virtio_add_queue(vdev
, 256, ctrl_cb
);
183 virtio_add_queue(vdev
, 16, cursor_cb
);
185 virtio_add_queue(vdev
, 64, ctrl_cb
);
186 virtio_add_queue(vdev
, 16, cursor_cb
);
189 g
->enabled_output_bitmask
= 1;
191 g
->req_state
[0].width
= g
->conf
.xres
;
192 g
->req_state
[0].height
= g
->conf
.yres
;
194 g
->hw_ops
= &virtio_gpu_ops
;
195 for (i
= 0; i
< g
->conf
.max_outputs
; i
++) {
197 graphic_console_init(DEVICE(g
), i
, &virtio_gpu_ops
, g
);
204 virtio_gpu_base_get_features(VirtIODevice
*vdev
, uint64_t features
,
207 VirtIOGPUBase
*g
= VIRTIO_GPU_BASE(vdev
);
209 if (virtio_gpu_virgl_enabled(g
->conf
)) {
210 features
|= (1 << VIRTIO_GPU_F_VIRGL
);
212 if (virtio_gpu_edid_enabled(g
->conf
)) {
213 features
|= (1 << VIRTIO_GPU_F_EDID
);
215 if (virtio_gpu_blob_enabled(g
->conf
)) {
216 features
|= (1 << VIRTIO_GPU_F_RESOURCE_BLOB
);
223 virtio_gpu_base_set_features(VirtIODevice
*vdev
, uint64_t features
)
225 static const uint32_t virgl
= (1 << VIRTIO_GPU_F_VIRGL
);
227 trace_virtio_gpu_features(((features
& virgl
) == virgl
));
231 virtio_gpu_base_device_unrealize(DeviceState
*qdev
)
233 VirtIOGPUBase
*g
= VIRTIO_GPU_BASE(qdev
);
235 if (g
->migration_blocker
) {
236 migrate_del_blocker(g
->migration_blocker
);
237 error_free(g
->migration_blocker
);
242 virtio_gpu_base_class_init(ObjectClass
*klass
, void *data
)
244 DeviceClass
*dc
= DEVICE_CLASS(klass
);
245 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
247 vdc
->unrealize
= virtio_gpu_base_device_unrealize
;
248 vdc
->get_features
= virtio_gpu_base_get_features
;
249 vdc
->set_features
= virtio_gpu_base_set_features
;
251 set_bit(DEVICE_CATEGORY_DISPLAY
, dc
->categories
);
252 dc
->hotpluggable
= false;
255 static const TypeInfo virtio_gpu_base_info
= {
256 .name
= TYPE_VIRTIO_GPU_BASE
,
257 .parent
= TYPE_VIRTIO_DEVICE
,
258 .instance_size
= sizeof(VirtIOGPUBase
),
259 .class_size
= sizeof(VirtIOGPUBaseClass
),
260 .class_init
= virtio_gpu_base_class_init
,
263 module_obj(TYPE_VIRTIO_GPU_BASE
);
264 module_kconfig(VIRTIO_GPU
);
267 virtio_register_types(void)
269 type_register_static(&virtio_gpu_base_info
);
272 type_init(virtio_register_types
)
274 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctrl_hdr
) != 24);
275 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_update_cursor
) != 56);
276 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_unref
) != 32);
277 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_2d
) != 40);
278 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_set_scanout
) != 48);
279 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_flush
) != 48);
280 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_to_host_2d
) != 56);
281 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_mem_entry
) != 16);
282 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_attach_backing
) != 32);
283 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_detach_backing
) != 32);
284 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_display_info
) != 408);
286 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_host_3d
) != 72);
287 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_3d
) != 72);
288 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_create
) != 96);
289 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_destroy
) != 24);
290 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_resource
) != 32);
291 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_cmd_submit
) != 32);
292 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset_info
) != 32);
293 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset_info
) != 40);
294 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset
) != 32);
295 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset
) != 24);