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
)
28 g
->use_virgl_renderer
= false;
30 for (i
= 0; i
< g
->conf
.max_outputs
; i
++) {
31 g
->scanout
[i
].resource_id
= 0;
32 g
->scanout
[i
].width
= 0;
33 g
->scanout
[i
].height
= 0;
36 g
->scanout
[i
].ds
= NULL
;
41 virtio_gpu_base_fill_display_info(VirtIOGPUBase
*g
,
42 struct virtio_gpu_resp_display_info
*dpy_info
)
46 for (i
= 0; i
< g
->conf
.max_outputs
; i
++) {
47 if (g
->enabled_output_bitmask
& (1 << i
)) {
48 dpy_info
->pmodes
[i
].enabled
= 1;
49 dpy_info
->pmodes
[i
].r
.width
= cpu_to_le32(g
->req_state
[i
].width
);
50 dpy_info
->pmodes
[i
].r
.height
= cpu_to_le32(g
->req_state
[i
].height
);
55 static void virtio_gpu_invalidate_display(void *opaque
)
59 static void virtio_gpu_update_display(void *opaque
)
63 static void virtio_gpu_text_update(void *opaque
, console_ch_t
*chardata
)
67 static void virtio_gpu_notify_event(VirtIOGPUBase
*g
, uint32_t event_type
)
69 g
->virtio_config
.events_read
|= event_type
;
70 virtio_notify_config(&g
->parent_obj
);
73 static int virtio_gpu_ui_info(void *opaque
, uint32_t idx
, QemuUIInfo
*info
)
75 VirtIOGPUBase
*g
= opaque
;
77 if (idx
>= g
->conf
.max_outputs
) {
81 g
->req_state
[idx
].x
= info
->xoff
;
82 g
->req_state
[idx
].y
= info
->yoff
;
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_block(void *opaque
, bool block
)
102 VirtIOGPUBase
*g
= opaque
;
103 VirtIOGPUBaseClass
*vgc
= VIRTIO_GPU_BASE_GET_CLASS(g
);
106 g
->renderer_blocked
++;
108 g
->renderer_blocked
--;
110 assert(g
->renderer_blocked
>= 0);
112 if (g
->renderer_blocked
== 0) {
118 virtio_gpu_get_flags(void *opaque
)
120 VirtIOGPUBase
*g
= opaque
;
121 int flags
= GRAPHIC_FLAGS_NONE
;
123 if (virtio_gpu_virgl_enabled(g
->conf
)) {
124 flags
|= GRAPHIC_FLAGS_GL
;
127 if (virtio_gpu_dmabuf_enabled(g
->conf
)) {
128 flags
|= GRAPHIC_FLAGS_DMABUF
;
134 static const GraphicHwOps virtio_gpu_ops
= {
135 .get_flags
= virtio_gpu_get_flags
,
136 .invalidate
= virtio_gpu_invalidate_display
,
137 .gfx_update
= virtio_gpu_update_display
,
138 .text_update
= virtio_gpu_text_update
,
139 .ui_info
= virtio_gpu_ui_info
,
140 .gl_block
= virtio_gpu_gl_block
,
144 virtio_gpu_base_device_realize(DeviceState
*qdev
,
145 VirtIOHandleOutput ctrl_cb
,
146 VirtIOHandleOutput cursor_cb
,
149 VirtIODevice
*vdev
= VIRTIO_DEVICE(qdev
);
150 VirtIOGPUBase
*g
= VIRTIO_GPU_BASE(qdev
);
153 if (g
->conf
.max_outputs
> VIRTIO_GPU_MAX_SCANOUTS
) {
154 error_setg(errp
, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS
);
158 g
->use_virgl_renderer
= false;
159 if (virtio_gpu_virgl_enabled(g
->conf
)) {
160 error_setg(&g
->migration_blocker
, "virgl is not yet migratable");
161 if (migrate_add_blocker(g
->migration_blocker
, errp
) < 0) {
162 error_free(g
->migration_blocker
);
167 g
->virtio_config
.num_scanouts
= cpu_to_le32(g
->conf
.max_outputs
);
168 virtio_init(VIRTIO_DEVICE(g
), "virtio-gpu", VIRTIO_ID_GPU
,
169 sizeof(struct virtio_gpu_config
));
171 if (virtio_gpu_virgl_enabled(g
->conf
)) {
172 /* use larger control queue in 3d mode */
173 virtio_add_queue(vdev
, 256, ctrl_cb
);
174 virtio_add_queue(vdev
, 16, cursor_cb
);
176 virtio_add_queue(vdev
, 64, ctrl_cb
);
177 virtio_add_queue(vdev
, 16, cursor_cb
);
180 g
->enabled_output_bitmask
= 1;
182 g
->req_state
[0].width
= g
->conf
.xres
;
183 g
->req_state
[0].height
= g
->conf
.yres
;
185 g
->hw_ops
= &virtio_gpu_ops
;
186 for (i
= 0; i
< g
->conf
.max_outputs
; i
++) {
188 graphic_console_init(DEVICE(g
), i
, &virtio_gpu_ops
, g
);
190 dpy_gfx_replace_surface(g
->scanout
[i
].con
, NULL
);
198 virtio_gpu_base_get_features(VirtIODevice
*vdev
, uint64_t features
,
201 VirtIOGPUBase
*g
= VIRTIO_GPU_BASE(vdev
);
203 if (virtio_gpu_virgl_enabled(g
->conf
)) {
204 features
|= (1 << VIRTIO_GPU_F_VIRGL
);
206 if (virtio_gpu_edid_enabled(g
->conf
)) {
207 features
|= (1 << VIRTIO_GPU_F_EDID
);
214 virtio_gpu_base_set_features(VirtIODevice
*vdev
, uint64_t features
)
216 static const uint32_t virgl
= (1 << VIRTIO_GPU_F_VIRGL
);
217 VirtIOGPUBase
*g
= VIRTIO_GPU_BASE(vdev
);
219 g
->use_virgl_renderer
= ((features
& virgl
) == virgl
);
220 trace_virtio_gpu_features(g
->use_virgl_renderer
);
224 virtio_gpu_base_device_unrealize(DeviceState
*qdev
)
226 VirtIOGPUBase
*g
= VIRTIO_GPU_BASE(qdev
);
228 if (g
->migration_blocker
) {
229 migrate_del_blocker(g
->migration_blocker
);
230 error_free(g
->migration_blocker
);
235 virtio_gpu_base_class_init(ObjectClass
*klass
, void *data
)
237 DeviceClass
*dc
= DEVICE_CLASS(klass
);
238 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
240 vdc
->unrealize
= virtio_gpu_base_device_unrealize
;
241 vdc
->get_features
= virtio_gpu_base_get_features
;
242 vdc
->set_features
= virtio_gpu_base_set_features
;
244 set_bit(DEVICE_CATEGORY_DISPLAY
, dc
->categories
);
245 dc
->hotpluggable
= false;
248 static const TypeInfo virtio_gpu_base_info
= {
249 .name
= TYPE_VIRTIO_GPU_BASE
,
250 .parent
= TYPE_VIRTIO_DEVICE
,
251 .instance_size
= sizeof(VirtIOGPUBase
),
252 .class_size
= sizeof(VirtIOGPUBaseClass
),
253 .class_init
= virtio_gpu_base_class_init
,
258 virtio_register_types(void)
260 type_register_static(&virtio_gpu_base_info
);
263 type_init(virtio_register_types
)
265 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctrl_hdr
) != 24);
266 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_update_cursor
) != 56);
267 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_unref
) != 32);
268 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_2d
) != 40);
269 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_set_scanout
) != 48);
270 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_flush
) != 48);
271 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_to_host_2d
) != 56);
272 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_mem_entry
) != 16);
273 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_attach_backing
) != 32);
274 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_detach_backing
) != 32);
275 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_display_info
) != 408);
277 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_host_3d
) != 72);
278 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_3d
) != 72);
279 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_create
) != 96);
280 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_destroy
) != 24);
281 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_resource
) != 32);
282 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_cmd_submit
) != 32);
283 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset_info
) != 32);
284 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset_info
) != 40);
285 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset
) != 32);
286 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset
) != 24);