* [PATCH v13 01/13] virtio-gpu: Move fence_poll timer to VirtIOGPUGL
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 02/13] virtio-gpu: Move print_stats " Dmitry Osipenko
` (11 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
Move fence_poll timer to VirtIOGPUGL for consistency with cmdq_resume_bh
that are used only by GL device.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-virgl.c | 8 +++++---
include/hw/virtio/virtio-gpu.h | 3 ++-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 9f34d0e6619c..7239a9f8e066 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -594,11 +594,12 @@ static void virtio_gpu_print_stats(void *opaque)
static void virtio_gpu_fence_poll(void *opaque)
{
VirtIOGPU *g = opaque;
+ VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
virgl_renderer_poll();
virtio_gpu_process_cmdq(g);
if (!QTAILQ_EMPTY(&g->cmdq) || !QTAILQ_EMPTY(&g->fenceq)) {
- timer_mod(g->fence_poll, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 10);
+ timer_mod(gl->fence_poll, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 10);
}
}
@@ -626,6 +627,7 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
{
int ret;
uint32_t flags = 0;
+ VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
#if VIRGL_RENDERER_CALLBACKS_VERSION >= 4
if (qemu_egl_display) {
@@ -645,8 +647,8 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
return ret;
}
- g->fence_poll = timer_new_ms(QEMU_CLOCK_VIRTUAL,
- virtio_gpu_fence_poll, g);
+ gl->fence_poll = timer_new_ms(QEMU_CLOCK_VIRTUAL,
+ virtio_gpu_fence_poll, g);
if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
g->print_stats = timer_new_ms(QEMU_CLOCK_VIRTUAL,
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 7a59379f5a7a..bc69fd78a440 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -196,7 +196,6 @@ struct VirtIOGPU {
uint64_t hostmem;
bool processing_cmdq;
- QEMUTimer *fence_poll;
QEMUTimer *print_stats;
uint32_t inflight;
@@ -231,6 +230,8 @@ struct VirtIOGPUGL {
bool renderer_inited;
bool renderer_reset;
+
+ QEMUTimer *fence_poll;
};
struct VhostUserGPU {
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v13 02/13] virtio-gpu: Move print_stats timer to VirtIOGPUGL
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 01/13] virtio-gpu: Move fence_poll timer to VirtIOGPUGL Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure Dmitry Osipenko
` (10 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
Move print_stats timer to VirtIOGPUGL for consistency with
cmdq_resume_bh and fence_poll that are used only by GL device.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-virgl.c | 10 ++++++----
include/hw/virtio/virtio-gpu.h | 2 +-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 7239a9f8e066..fa0da8f5c7f1 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -574,6 +574,7 @@ static struct virgl_renderer_callbacks virtio_gpu_3d_cbs = {
static void virtio_gpu_print_stats(void *opaque)
{
VirtIOGPU *g = opaque;
+ VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
if (g->stats.requests) {
fprintf(stderr, "stats: vq req %4d, %3d -- 3D %4d (%5d)\n",
@@ -588,7 +589,7 @@ static void virtio_gpu_print_stats(void *opaque)
} else {
fprintf(stderr, "stats: idle\r");
}
- timer_mod(g->print_stats, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
+ timer_mod(gl->print_stats, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
}
static void virtio_gpu_fence_poll(void *opaque)
@@ -651,9 +652,10 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
virtio_gpu_fence_poll, g);
if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
- g->print_stats = timer_new_ms(QEMU_CLOCK_VIRTUAL,
- virtio_gpu_print_stats, g);
- timer_mod(g->print_stats, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
+ gl->print_stats = timer_new_ms(QEMU_CLOCK_VIRTUAL,
+ virtio_gpu_print_stats, g);
+ timer_mod(gl->print_stats,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
}
return 0;
}
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index bc69fd78a440..7ff989a45a5c 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -196,7 +196,6 @@ struct VirtIOGPU {
uint64_t hostmem;
bool processing_cmdq;
- QEMUTimer *print_stats;
uint32_t inflight;
struct {
@@ -232,6 +231,7 @@ struct VirtIOGPUGL {
bool renderer_reset;
QEMUTimer *fence_poll;
+ QEMUTimer *print_stats;
};
struct VhostUserGPU {
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 01/13] virtio-gpu: Move fence_poll timer to VirtIOGPUGL Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 02/13] virtio-gpu: Move print_stats " Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-06-02 5:34 ` Akihiko Odaki
2024-06-04 14:21 ` Marc-André Lureau
2024-05-27 3:02 ` [PATCH v13 04/13] virtio-gpu: Unrealize GL device Dmitry Osipenko
` (9 subsequent siblings)
12 siblings, 2 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
virtio_gpu_virgl_init() may fail, leading to a further Qemu crash
because Qemu assumes it never fails. Check virtio_gpu_virgl_init()
return code and don't execute virtio commands on error. Failed
virtio_gpu_virgl_init() will result in a timed out virtio commands
for a guest OS.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-gl.c | 29 +++++++++++++++++++++--------
include/hw/virtio/virtio-gpu.h | 11 +++++++++--
2 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index e06be60dfbfc..38a2b1bd3916 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -29,9 +29,14 @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g,
struct virtio_gpu_scanout *s,
uint32_t resource_id)
{
+ VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
uint32_t width, height;
uint32_t pixels, *data;
+ if (gl->renderer_state != RS_INITED) {
+ return;
+ }
+
data = virgl_renderer_get_cursor_data(resource_id, &width, &height);
if (!data) {
return;
@@ -65,13 +70,21 @@ static void virtio_gpu_gl_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
return;
}
- if (!gl->renderer_inited) {
- virtio_gpu_virgl_init(g);
- gl->renderer_inited = true;
- }
- if (gl->renderer_reset) {
- gl->renderer_reset = false;
+ switch (gl->renderer_state) {
+ case RS_RESET:
virtio_gpu_virgl_reset(g);
+ /* fallthrough */
+ case RS_START:
+ if (virtio_gpu_virgl_init(g)) {
+ gl->renderer_state = RS_INIT_FAILED;
+ } else {
+ gl->renderer_state = RS_INITED;
+ }
+ break;
+ case RS_INIT_FAILED:
+ return;
+ case RS_INITED:
+ break;
}
cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
@@ -98,9 +111,9 @@ static void virtio_gpu_gl_reset(VirtIODevice *vdev)
* GL functions must be called with the associated GL context in main
* thread, and when the renderer is unblocked.
*/
- if (gl->renderer_inited && !gl->renderer_reset) {
+ if (gl->renderer_state == RS_INITED) {
virtio_gpu_virgl_reset_scanout(g);
- gl->renderer_reset = true;
+ gl->renderer_state = RS_RESET;
}
}
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 7ff989a45a5c..6e71d799e5da 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -224,11 +224,18 @@ struct VirtIOGPUClass {
Error **errp);
};
+/* VirtIOGPUGL renderer states */
+typedef enum {
+ RS_START, /* starting state */
+ RS_INIT_FAILED, /* failed initialisation */
+ RS_INITED, /* initialised and working */
+ RS_RESET, /* inited and reset pending, moves to start after reset */
+} RenderState;
+
struct VirtIOGPUGL {
struct VirtIOGPU parent_obj;
- bool renderer_inited;
- bool renderer_reset;
+ RenderState renderer_state;
QEMUTimer *fence_poll;
QEMUTimer *print_stats;
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-05-27 3:02 ` [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure Dmitry Osipenko
@ 2024-06-02 5:34 ` Akihiko Odaki
2024-06-03 5:26 ` Dmitry Osipenko
2024-06-04 14:21 ` Marc-André Lureau
1 sibling, 1 reply; 28+ messages in thread
From: Akihiko Odaki @ 2024-06-02 5:34 UTC (permalink / raw)
To: Dmitry Osipenko, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 2024/05/27 12:02, Dmitry Osipenko wrote:
> virtio_gpu_virgl_init() may fail, leading to a further Qemu crash
> because Qemu assumes it never fails. Check virtio_gpu_virgl_init()
> return code and don't execute virtio commands on error. Failed
> virtio_gpu_virgl_init() will result in a timed out virtio commands
> for a guest OS.
>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu-gl.c | 29 +++++++++++++++++++++--------
> include/hw/virtio/virtio-gpu.h | 11 +++++++++--
> 2 files changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
> index e06be60dfbfc..38a2b1bd3916 100644
> --- a/hw/display/virtio-gpu-gl.c
> +++ b/hw/display/virtio-gpu-gl.c
> @@ -29,9 +29,14 @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g,
> struct virtio_gpu_scanout *s,
> uint32_t resource_id)
> {
> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
> uint32_t width, height;
> uint32_t pixels, *data;
>
> + if (gl->renderer_state != RS_INITED) {
> + return;
> + }
> +
> data = virgl_renderer_get_cursor_data(resource_id, &width, &height);
> if (!data) {
> return;
> @@ -65,13 +70,21 @@ static void virtio_gpu_gl_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
> return;
> }
>
> - if (!gl->renderer_inited) {
> - virtio_gpu_virgl_init(g);
> - gl->renderer_inited = true;
> - }
> - if (gl->renderer_reset) {
> - gl->renderer_reset = false;
> + switch (gl->renderer_state) {
> + case RS_RESET:
> virtio_gpu_virgl_reset(g);
> + /* fallthrough */
> + case RS_START:
> + if (virtio_gpu_virgl_init(g)) {
> + gl->renderer_state = RS_INIT_FAILED;
> + } else {
> + gl->renderer_state = RS_INITED;
> + }
> + break;
> + case RS_INIT_FAILED:
> + return;
> + case RS_INITED:
> + break;
> }
>
> cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
> @@ -98,9 +111,9 @@ static void virtio_gpu_gl_reset(VirtIODevice *vdev)
> * GL functions must be called with the associated GL context in main
> * thread, and when the renderer is unblocked.
> */
> - if (gl->renderer_inited && !gl->renderer_reset) {
> + if (gl->renderer_state == RS_INITED) {
> virtio_gpu_virgl_reset_scanout(g);
> - gl->renderer_reset = true;
> + gl->renderer_state = RS_RESET;
> }
> }
>
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index 7ff989a45a5c..6e71d799e5da 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -224,11 +224,18 @@ struct VirtIOGPUClass {
> Error **errp);
> };
>
> +/* VirtIOGPUGL renderer states */
> +typedef enum {
> + RS_START, /* starting state */
> + RS_INIT_FAILED, /* failed initialisation */
Is the distinction between RS_START and RS_INIT_FAILED really necessary?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-06-02 5:34 ` Akihiko Odaki
@ 2024-06-03 5:26 ` Dmitry Osipenko
2024-06-03 5:44 ` Akihiko Odaki
0 siblings, 1 reply; 28+ messages in thread
From: Dmitry Osipenko @ 2024-06-03 5:26 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 6/2/24 08:34, Akihiko Odaki wrote:
>> +typedef enum {
>> + RS_START, /* starting state */
>> + RS_INIT_FAILED, /* failed initialisation */
>
> Is the distinction between RS_START and RS_INIT_FAILED really necessary?
The state stays in RS_INIT_FAILED once was failed until virtio-gpu is
reset, re-initializing virglrenderer isn't allowed in this state.
The RS_START state allows to initialize virglrenderer and moves to
either RS_INITED or RS_INIT_FAILED state after initialization.
The distinction is necessary
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-06-03 5:26 ` Dmitry Osipenko
@ 2024-06-03 5:44 ` Akihiko Odaki
2024-06-09 19:02 ` Dmitry Osipenko
0 siblings, 1 reply; 28+ messages in thread
From: Akihiko Odaki @ 2024-06-03 5:44 UTC (permalink / raw)
To: Dmitry Osipenko, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 2024/06/03 14:26, Dmitry Osipenko wrote:
> On 6/2/24 08:34, Akihiko Odaki wrote:
>>> +typedef enum {
>>> + RS_START, /* starting state */
>>> + RS_INIT_FAILED, /* failed initialisation */
>>
>> Is the distinction between RS_START and RS_INIT_FAILED really necessary?
>
> The state stays in RS_INIT_FAILED once was failed until virtio-gpu is
> reset, re-initializing virglrenderer isn't allowed in this state.
Can you elaborate more? Why isn't re-initializing allowed?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-06-03 5:44 ` Akihiko Odaki
@ 2024-06-09 19:02 ` Dmitry Osipenko
2024-06-10 3:38 ` Akihiko Odaki
0 siblings, 1 reply; 28+ messages in thread
From: Dmitry Osipenko @ 2024-06-09 19:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 6/3/24 08:44, Akihiko Odaki wrote:
> On 2024/06/03 14:26, Dmitry Osipenko wrote:
>> On 6/2/24 08:34, Akihiko Odaki wrote:
>>>> +typedef enum {
>>>> + RS_START, /* starting state */
>>>> + RS_INIT_FAILED, /* failed initialisation */
>>>
>>> Is the distinction between RS_START and RS_INIT_FAILED really necessary?
>>
>> The state stays in RS_INIT_FAILED once was failed until virtio-gpu is
>> reset, re-initializing virglrenderer isn't allowed in this state.
>
> Can you elaborate more? Why isn't re-initializing allowed?
In practice, if virglrenderer initialization failed once, it will fail
second time. Otherwise we will be retrying to init endlessly because
guest won't stop sending virgl commands even if they all are timing out.
Each initialization failure produces a error msg.
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-06-09 19:02 ` Dmitry Osipenko
@ 2024-06-10 3:38 ` Akihiko Odaki
2024-06-15 22:51 ` Dmitry Osipenko
0 siblings, 1 reply; 28+ messages in thread
From: Akihiko Odaki @ 2024-06-10 3:38 UTC (permalink / raw)
To: Dmitry Osipenko, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 2024/06/10 4:02, Dmitry Osipenko wrote:
> On 6/3/24 08:44, Akihiko Odaki wrote:
>> On 2024/06/03 14:26, Dmitry Osipenko wrote:
>>> On 6/2/24 08:34, Akihiko Odaki wrote:
>>>>> +typedef enum {
>>>>> + RS_START, /* starting state */
>>>>> + RS_INIT_FAILED, /* failed initialisation */
>>>>
>>>> Is the distinction between RS_START and RS_INIT_FAILED really necessary?
>>>
>>> The state stays in RS_INIT_FAILED once was failed until virtio-gpu is
>>> reset, re-initializing virglrenderer isn't allowed in this state.
>>
>> Can you elaborate more? Why isn't re-initializing allowed?
>
> In practice, if virglrenderer initialization failed once, it will fail
> second time. Otherwise we will be retrying to init endlessly because
> guest won't stop sending virgl commands even if they all are timing out.
> Each initialization failure produces a error msg.
>
I see.
A better solution is to add a new function to GraphicHwOps to call back
after initializating the displays and before starting the guest. You can
do virgl initialization in such a function, and exit(1) if the
initialization fails because the guest has not started yet, saving this
enum. I don't require you to make such a change however; this is not a
regression of your patches so you have no obligation to fix it.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-06-10 3:38 ` Akihiko Odaki
@ 2024-06-15 22:51 ` Dmitry Osipenko
0 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-06-15 22:51 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 6/10/24 06:38, Akihiko Odaki wrote:
> On 2024/06/10 4:02, Dmitry Osipenko wrote:
>> On 6/3/24 08:44, Akihiko Odaki wrote:
>>> On 2024/06/03 14:26, Dmitry Osipenko wrote:
>>>> On 6/2/24 08:34, Akihiko Odaki wrote:
>>>>>> +typedef enum {
>>>>>> + RS_START, /* starting state */
>>>>>> + RS_INIT_FAILED, /* failed initialisation */
>>>>>
>>>>> Is the distinction between RS_START and RS_INIT_FAILED really
>>>>> necessary?
>>>>
>>>> The state stays in RS_INIT_FAILED once was failed until virtio-gpu is
>>>> reset, re-initializing virglrenderer isn't allowed in this state.
>>>
>>> Can you elaborate more? Why isn't re-initializing allowed?
>>
>> In practice, if virglrenderer initialization failed once, it will fail
>> second time. Otherwise we will be retrying to init endlessly because
>> guest won't stop sending virgl commands even if they all are timing out.
>> Each initialization failure produces a error msg.
>>
> I see.
>
> A better solution is to add a new function to GraphicHwOps to call back
> after initializating the displays and before starting the guest. You can
> do virgl initialization in such a function, and exit(1) if the
> initialization fails because the guest has not started yet, saving this
> enum. I don't require you to make such a change however; this is not a
> regression of your patches so you have no obligation to fix it.
I'll keep this idea for a follow up patch, thanks! It will take me some
extra time to look through the display code, making sure that callback
is added properly and nothing is missed.
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-05-27 3:02 ` [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure Dmitry Osipenko
2024-06-02 5:34 ` Akihiko Odaki
@ 2024-06-04 14:21 ` Marc-André Lureau
2024-06-09 19:05 ` Dmitry Osipenko
1 sibling, 1 reply; 28+ messages in thread
From: Marc-André Lureau @ 2024-06-04 14:21 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Akihiko Odaki, Huang Rui, Philippe Mathieu-Daudé,
Gerd Hoffmann, Michael S . Tsirkin, Stefano Stabellini,
Antonio Caggiano, Dr . David Alan Gilbert, Robert Beckett,
Gert Wollny, Alex Bennée, qemu-devel, Gurchetan Singh,
ernunes, Alyssa Ross, Roger Pau Monné, Alex Deucher,
Stefano Stabellini, Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
[-- Attachment #1: Type: text/plain, Size: 3751 bytes --]
Hi
On Mon, May 27, 2024 at 7:03 AM Dmitry Osipenko <
dmitry.osipenko@collabora.com> wrote:
> virtio_gpu_virgl_init() may fail, leading to a further Qemu crash
> because Qemu assumes it never fails. Check virtio_gpu_virgl_init()
> return code and don't execute virtio commands on error. Failed
> virtio_gpu_virgl_init() will result in a timed out virtio commands
> for a guest OS.
>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu-gl.c | 29 +++++++++++++++++++++--------
> include/hw/virtio/virtio-gpu.h | 11 +++++++++--
> 2 files changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
> index e06be60dfbfc..38a2b1bd3916 100644
> --- a/hw/display/virtio-gpu-gl.c
> +++ b/hw/display/virtio-gpu-gl.c
> @@ -29,9 +29,14 @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU
> *g,
> struct virtio_gpu_scanout *s,
> uint32_t resource_id)
> {
> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
> uint32_t width, height;
> uint32_t pixels, *data;
>
> + if (gl->renderer_state != RS_INITED) {
> + return;
> + }
> +
> data = virgl_renderer_get_cursor_data(resource_id, &width, &height);
> if (!data) {
> return;
> @@ -65,13 +70,21 @@ static void virtio_gpu_gl_handle_ctrl(VirtIODevice
> *vdev, VirtQueue *vq)
> return;
> }
>
> - if (!gl->renderer_inited) {
> - virtio_gpu_virgl_init(g);
> - gl->renderer_inited = true;
> - }
> - if (gl->renderer_reset) {
> - gl->renderer_reset = false;
> + switch (gl->renderer_state) {
> + case RS_RESET:
> virtio_gpu_virgl_reset(g);
> + /* fallthrough */
> + case RS_START:
> + if (virtio_gpu_virgl_init(g)) {
> + gl->renderer_state = RS_INIT_FAILED;
> + } else {
> + gl->renderer_state = RS_INITED;
> + }
> + break;
> + case RS_INIT_FAILED:
> + return;
> + case RS_INITED:
> + break;
> }
>
>
This still lets it go through the cmd processing after setting
gl->renderer_state = RS_INIT_FAILED, the first time.
> cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
> @@ -98,9 +111,9 @@ static void virtio_gpu_gl_reset(VirtIODevice *vdev)
> * GL functions must be called with the associated GL context in main
> * thread, and when the renderer is unblocked.
> */
> - if (gl->renderer_inited && !gl->renderer_reset) {
> + if (gl->renderer_state == RS_INITED) {
> virtio_gpu_virgl_reset_scanout(g);
> - gl->renderer_reset = true;
> + gl->renderer_state = RS_RESET;
> }
> }
>
> diff --git a/include/hw/virtio/virtio-gpu.h
> b/include/hw/virtio/virtio-gpu.h
> index 7ff989a45a5c..6e71d799e5da 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -224,11 +224,18 @@ struct VirtIOGPUClass {
> Error **errp);
> };
>
> +/* VirtIOGPUGL renderer states */
> +typedef enum {
> + RS_START, /* starting state */
> + RS_INIT_FAILED, /* failed initialisation */
> + RS_INITED, /* initialised and working */
> + RS_RESET, /* inited and reset pending, moves to start after
> reset */
> +} RenderState;
> +
> struct VirtIOGPUGL {
> struct VirtIOGPU parent_obj;
>
> - bool renderer_inited;
> - bool renderer_reset;
> + RenderState renderer_state;
>
> QEMUTimer *fence_poll;
> QEMUTimer *print_stats;
> --
> 2.44.0
>
>
--
Marc-André Lureau
[-- Attachment #2: Type: text/html, Size: 4914 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure
2024-06-04 14:21 ` Marc-André Lureau
@ 2024-06-09 19:05 ` Dmitry Osipenko
0 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-06-09 19:05 UTC (permalink / raw)
To: Marc-André Lureau
Cc: Akihiko Odaki, Huang Rui, Philippe Mathieu-Daudé,
Gerd Hoffmann, Michael S . Tsirkin, Stefano Stabellini,
Antonio Caggiano, Dr . David Alan Gilbert, Robert Beckett,
Gert Wollny, Alex Bennée, qemu-devel, Gurchetan Singh,
ernunes, Alyssa Ross, Roger Pau Monné, Alex Deucher,
Stefano Stabellini, Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 6/4/24 17:21, Marc-André Lureau wrote:
>> @@ -65,13 +70,21 @@ static void virtio_gpu_gl_handle_ctrl(VirtIODevice
>> *vdev, VirtQueue *vq)
>> return;
>> }
>>
>> - if (!gl->renderer_inited) {
>> - virtio_gpu_virgl_init(g);
>> - gl->renderer_inited = true;
>> - }
>> - if (gl->renderer_reset) {
>> - gl->renderer_reset = false;
>> + switch (gl->renderer_state) {
>> + case RS_RESET:
>> virtio_gpu_virgl_reset(g);
>> + /* fallthrough */
>> + case RS_START:
>> + if (virtio_gpu_virgl_init(g)) {
>> + gl->renderer_state = RS_INIT_FAILED;
>> + } else {
>> + gl->renderer_state = RS_INITED;
>> + }
>> + break;
>> + case RS_INIT_FAILED:
>> + return;
>> + case RS_INITED:
>> + break;
>> }
>>
>>
> This still lets it go through the cmd processing after setting
> gl->renderer_state = RS_INIT_FAILED, the first time.
Good catch, thanks!
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v13 04/13] virtio-gpu: Unrealize GL device
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (2 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 03/13] virtio-gpu: Handle virtio_gpu_virgl_init() failure Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-06-04 14:23 ` Marc-André Lureau
2024-05-27 3:02 ` [PATCH v13 05/13] virtio-gpu: Use pkgconfig version to decide which virgl features are available Dmitry Osipenko
` (8 subsequent siblings)
12 siblings, 1 reply; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
Even though GL GPU doesn't support hotplugging today, free virgl
resources when GL device is unrealized. For consistency.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-gl.c | 13 +++++++++++++
hw/display/virtio-gpu-virgl.c | 11 +++++++++++
include/hw/virtio/virtio-gpu.h | 1 +
3 files changed, 25 insertions(+)
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index 38a2b1bd3916..7978b2985e17 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -149,6 +149,18 @@ static Property virtio_gpu_gl_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
+{
+ VirtIOGPU *g = VIRTIO_GPU(qdev);
+ VirtIOGPUGL *gl = VIRTIO_GPU_GL(qdev);
+
+ if (gl->renderer_state >= RS_INITED) {
+ virtio_gpu_virgl_deinit(g);
+ }
+
+ gl->renderer_state = RS_START;
+}
+
static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -162,6 +174,7 @@ static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
vgc->update_cursor_data = virtio_gpu_gl_update_cursor_data;
vdc->realize = virtio_gpu_gl_device_realize;
+ vdc->unrealize = virtio_gpu_gl_device_unrealize;
vdc->reset = virtio_gpu_gl_reset;
device_class_set_props(dc, virtio_gpu_gl_properties);
}
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index fa0da8f5c7f1..66c4aab9b283 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -669,3 +669,14 @@ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
return capset2_max_ver ? 2 : 1;
}
+
+void virtio_gpu_virgl_deinit(VirtIOGPU *g)
+{
+ VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
+
+ if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
+ timer_free(gl->print_stats);
+ }
+ timer_free(gl->fence_poll);
+ virgl_renderer_cleanup(NULL);
+}
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 6e71d799e5da..2faeda6f6abe 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -345,6 +345,7 @@ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g);
void virtio_gpu_virgl_reset(VirtIOGPU *g);
int virtio_gpu_virgl_init(VirtIOGPU *g);
+void virtio_gpu_virgl_deinit(VirtIOGPU *g);
int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
#endif
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v13 04/13] virtio-gpu: Unrealize GL device
2024-05-27 3:02 ` [PATCH v13 04/13] virtio-gpu: Unrealize GL device Dmitry Osipenko
@ 2024-06-04 14:23 ` Marc-André Lureau
0 siblings, 0 replies; 28+ messages in thread
From: Marc-André Lureau @ 2024-06-04 14:23 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Akihiko Odaki, Huang Rui, Philippe Mathieu-Daudé,
Gerd Hoffmann, Michael S . Tsirkin, Stefano Stabellini,
Antonio Caggiano, Dr . David Alan Gilbert, Robert Beckett,
Gert Wollny, Alex Bennée, qemu-devel, Gurchetan Singh,
ernunes, Alyssa Ross, Roger Pau Monné, Alex Deucher,
Stefano Stabellini, Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
[-- Attachment #1: Type: text/plain, Size: 2885 bytes --]
Hi
On Mon, May 27, 2024 at 7:03 AM Dmitry Osipenko <
dmitry.osipenko@collabora.com> wrote:
> Even though GL GPU doesn't support hotplugging today, free virgl
> resources when GL device is unrealized. For consistency.
>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu-gl.c | 13 +++++++++++++
> hw/display/virtio-gpu-virgl.c | 11 +++++++++++
> include/hw/virtio/virtio-gpu.h | 1 +
> 3 files changed, 25 insertions(+)
>
> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
> index 38a2b1bd3916..7978b2985e17 100644
> --- a/hw/display/virtio-gpu-gl.c
> +++ b/hw/display/virtio-gpu-gl.c
> @@ -149,6 +149,18 @@ static Property virtio_gpu_gl_properties[] = {
> DEFINE_PROP_END_OF_LIST(),
> };
>
> +static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
> +{
> + VirtIOGPU *g = VIRTIO_GPU(qdev);
> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(qdev);
> +
> + if (gl->renderer_state >= RS_INITED) {
> + virtio_gpu_virgl_deinit(g);
>
The extra function seems unnecessary.
> + }
> +
> + gl->renderer_state = RS_START;
> +}
> +
> static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -162,6 +174,7 @@ static void virtio_gpu_gl_class_init(ObjectClass
> *klass, void *data)
> vgc->update_cursor_data = virtio_gpu_gl_update_cursor_data;
>
> vdc->realize = virtio_gpu_gl_device_realize;
> + vdc->unrealize = virtio_gpu_gl_device_unrealize;
> vdc->reset = virtio_gpu_gl_reset;
> device_class_set_props(dc, virtio_gpu_gl_properties);
> }
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index fa0da8f5c7f1..66c4aab9b283 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -669,3 +669,14 @@ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
>
> return capset2_max_ver ? 2 : 1;
> }
> +
> +void virtio_gpu_virgl_deinit(VirtIOGPU *g)
> +{
> + VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
> +
> + if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
> + timer_free(gl->print_stats);
> + }
> + timer_free(gl->fence_poll);
> + virgl_renderer_cleanup(NULL);
> +}
> diff --git a/include/hw/virtio/virtio-gpu.h
> b/include/hw/virtio/virtio-gpu.h
> index 6e71d799e5da..2faeda6f6abe 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -345,6 +345,7 @@ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
> void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g);
> void virtio_gpu_virgl_reset(VirtIOGPU *g);
> int virtio_gpu_virgl_init(VirtIOGPU *g);
> +void virtio_gpu_virgl_deinit(VirtIOGPU *g);
> int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
>
> #endif
> --
> 2.44.0
>
>
--
Marc-André Lureau
[-- Attachment #2: Type: text/html, Size: 3796 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v13 05/13] virtio-gpu: Use pkgconfig version to decide which virgl features are available
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (3 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 04/13] virtio-gpu: Unrealize GL device Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 06/13] virtio-gpu: Support context-init feature with virglrenderer Dmitry Osipenko
` (7 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
New virglrerenderer features were stabilized with release of v1.0.0.
Presence of symbols in virglrenderer.h doesn't guarantee ABI compatibility
with pre-release development versions of libvirglerender. Use virglrenderer
version to decide reliably which virgl features are available.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
meson.build | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/meson.build b/meson.build
index 638660714455..de97d2426bde 100644
--- a/meson.build
+++ b/meson.build
@@ -2308,11 +2308,8 @@ config_host_data.set('CONFIG_PNG', png.found())
config_host_data.set('CONFIG_VNC', vnc.found())
config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
config_host_data.set('CONFIG_VNC_SASL', sasl.found())
-if virgl.found()
- config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
- cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
- prefix: '#include <virglrenderer.h>',
- dependencies: virgl))
+if virgl.version().version_compare('>=1.0.0')
+ config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT', 1)
endif
config_host_data.set('CONFIG_VIRTFS', have_virtfs)
config_host_data.set('CONFIG_VTE', vte.found())
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v13 06/13] virtio-gpu: Support context-init feature with virglrenderer
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (4 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 05/13] virtio-gpu: Use pkgconfig version to decide which virgl features are available Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 07/13] virtio-gpu: Don't require udmabuf when blobs and virgl are enabled Dmitry Osipenko
` (6 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
From: Huang Rui <ray.huang@amd.com>
Patch "virtio-gpu: CONTEXT_INIT feature" has added the context_init
feature flags. Expose this feature and support creating virglrenderer
context with flags using context_id if libvirglrenderer is new enough.
Originally-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Antonio Caggiano <quic_acaggian@quicinc.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-gl.c | 4 ++++
hw/display/virtio-gpu-virgl.c | 20 ++++++++++++++++++--
meson.build | 1 +
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index 7978b2985e17..9822d79c5e81 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -140,6 +140,10 @@ static void virtio_gpu_gl_device_realize(DeviceState *qdev, Error **errp)
VIRTIO_GPU_BASE(g)->virtio_config.num_capsets =
virtio_gpu_virgl_get_num_capsets(g);
+#ifdef HAVE_VIRGL_CONTEXT_CREATE_WITH_FLAGS
+ g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED;
+#endif
+
virtio_gpu_device_realize(qdev, errp);
}
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 66c4aab9b283..4b2d4a643e30 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -106,8 +106,24 @@ static void virgl_cmd_context_create(VirtIOGPU *g,
trace_virtio_gpu_cmd_ctx_create(cc.hdr.ctx_id,
cc.debug_name);
- virgl_renderer_context_create(cc.hdr.ctx_id, cc.nlen,
- cc.debug_name);
+ if (cc.context_init) {
+ if (!virtio_gpu_context_init_enabled(g->parent_obj.conf)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: context_init disabled",
+ __func__);
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ return;
+ }
+
+#ifdef HAVE_VIRGL_CONTEXT_CREATE_WITH_FLAGS
+ virgl_renderer_context_create_with_flags(cc.hdr.ctx_id,
+ cc.context_init,
+ cc.nlen,
+ cc.debug_name);
+ return;
+#endif
+ }
+
+ virgl_renderer_context_create(cc.hdr.ctx_id, cc.nlen, cc.debug_name);
}
static void virgl_cmd_context_destroy(VirtIOGPU *g,
diff --git a/meson.build b/meson.build
index de97d2426bde..65fddfbbc3a7 100644
--- a/meson.build
+++ b/meson.build
@@ -2310,6 +2310,7 @@ config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
config_host_data.set('CONFIG_VNC_SASL', sasl.found())
if virgl.version().version_compare('>=1.0.0')
config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT', 1)
+ config_host_data.set('HAVE_VIRGL_CONTEXT_CREATE_WITH_FLAGS', 1)
endif
config_host_data.set('CONFIG_VIRTFS', have_virtfs)
config_host_data.set('CONFIG_VTE', vte.found())
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v13 07/13] virtio-gpu: Don't require udmabuf when blobs and virgl are enabled
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (5 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 06/13] virtio-gpu: Support context-init feature with virglrenderer Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 08/13] virtio-gpu: Add virgl resource management Dmitry Osipenko
` (5 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
The udmabuf usage is mandatory when virgl is disabled and blobs feature
enabled in the Qemu machine configuration. If virgl and blobs are enabled,
then udmabuf requirement is optional. Since udmabuf isn't widely supported
by a popular Linux distros today, let's relax the udmabuf requirement for
blobs=on,virgl=on. Now, a full-featured virtio-gpu acceleration is
available to Qemu users without a need to have udmabuf available in the
system.
Reviewed-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Antonio Caggiano <quic_acaggian@quicinc.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index d60b1b2973af..672279e57f3f 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1485,6 +1485,7 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
if (!virtio_gpu_rutabaga_enabled(g->parent_obj.conf) &&
+ !virtio_gpu_virgl_enabled(g->parent_obj.conf) &&
!virtio_gpu_have_udmabuf()) {
error_setg(errp, "need rutabaga or udmabuf for blob resources");
return;
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v13 08/13] virtio-gpu: Add virgl resource management
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (6 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 07/13] virtio-gpu: Don't require udmabuf when blobs and virgl are enabled Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 09/13] virtio-gpu: Support blob scanout using dmabuf fd Dmitry Osipenko
` (4 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
From: Huang Rui <ray.huang@amd.com>
In a preparation to adding host blobs support to virtio-gpu, add virgl
resource management that allows to retrieve resource based on its ID
and virgl resource wrapper on top of simple resource that will be contain
fields specific to virgl.
Signed-off-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Antonio Caggiano <quic_acaggian@quicinc.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-virgl.c | 76 +++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 4b2d4a643e30..8392d0fde984 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -22,6 +22,23 @@
#include <virglrenderer.h>
+struct virtio_gpu_virgl_resource {
+ struct virtio_gpu_simple_resource base;
+};
+
+static struct virtio_gpu_virgl_resource *
+virtio_gpu_virgl_find_resource(VirtIOGPU *g, uint32_t resource_id)
+{
+ struct virtio_gpu_simple_resource *res;
+
+ res = virtio_gpu_find_resource(g, resource_id);
+ if (!res) {
+ return NULL;
+ }
+
+ return container_of(res, struct virtio_gpu_virgl_resource, base);
+}
+
#if VIRGL_RENDERER_CALLBACKS_VERSION >= 4
static void *
virgl_get_egl_display(G_GNUC_UNUSED void *cookie)
@@ -35,11 +52,34 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
{
struct virtio_gpu_resource_create_2d c2d;
struct virgl_renderer_resource_create_args args;
+ struct virtio_gpu_virgl_resource *res;
VIRTIO_GPU_FILL_CMD(c2d);
trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,
c2d.width, c2d.height);
+ if (c2d.resource_id == 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+ __func__);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ res = virtio_gpu_virgl_find_resource(g, c2d.resource_id);
+ if (res) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+ __func__, c2d.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ res = g_new0(struct virtio_gpu_virgl_resource, 1);
+ res->base.width = c2d.width;
+ res->base.height = c2d.height;
+ res->base.format = c2d.format;
+ res->base.resource_id = c2d.resource_id;
+ QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);
+
args.handle = c2d.resource_id;
args.target = 2;
args.format = c2d.format;
@@ -59,11 +99,34 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
{
struct virtio_gpu_resource_create_3d c3d;
struct virgl_renderer_resource_create_args args;
+ struct virtio_gpu_virgl_resource *res;
VIRTIO_GPU_FILL_CMD(c3d);
trace_virtio_gpu_cmd_res_create_3d(c3d.resource_id, c3d.format,
c3d.width, c3d.height, c3d.depth);
+ if (c3d.resource_id == 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+ __func__);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ res = virtio_gpu_virgl_find_resource(g, c3d.resource_id);
+ if (res) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+ __func__, c3d.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ res = g_new0(struct virtio_gpu_virgl_resource, 1);
+ res->base.width = c3d.width;
+ res->base.height = c3d.height;
+ res->base.format = c3d.format;
+ res->base.resource_id = c3d.resource_id;
+ QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);
+
args.handle = c3d.resource_id;
args.target = c3d.target;
args.format = c3d.format;
@@ -82,12 +145,21 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
{
struct virtio_gpu_resource_unref unref;
+ struct virtio_gpu_virgl_resource *res;
struct iovec *res_iovs = NULL;
int num_iovs = 0;
VIRTIO_GPU_FILL_CMD(unref);
trace_virtio_gpu_cmd_res_unref(unref.resource_id);
+ res = virtio_gpu_virgl_find_resource(g, unref.resource_id);
+ if (!res) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not exist %d\n",
+ __func__, unref.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
virgl_renderer_resource_detach_iov(unref.resource_id,
&res_iovs,
&num_iovs);
@@ -95,6 +167,10 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
virtio_gpu_cleanup_mapping_iov(g, res_iovs, num_iovs);
}
virgl_renderer_resource_unref(unref.resource_id);
+
+ QTAILQ_REMOVE(&g->reslist, &res->base, next);
+
+ g_free(res);
}
static void virgl_cmd_context_create(VirtIOGPU *g,
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v13 09/13] virtio-gpu: Support blob scanout using dmabuf fd
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (7 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 08/13] virtio-gpu: Add virgl resource management Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-06-04 14:39 ` Marc-André Lureau
2024-05-27 3:02 ` [PATCH v13 10/13] virtio-gpu: Support suspension of commands processing Dmitry Osipenko
` (3 subsequent siblings)
12 siblings, 1 reply; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
From: Robert Beckett <bob.beckett@collabora.com>
Support displaying blob resources by handling SET_SCANOUT_BLOB
command.
Signed-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Antonio Caggiano <quic_acaggian@quicinc.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-virgl.c | 109 +++++++++++++++++++++++++++++++++
hw/display/virtio-gpu.c | 12 ++--
include/hw/virtio/virtio-gpu.h | 7 +++
meson.build | 1 +
4 files changed, 123 insertions(+), 6 deletions(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 8392d0fde984..7f45b4fa5fd7 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -17,6 +17,8 @@
#include "trace.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-bswap.h"
+#include "hw/virtio/virtio-gpu-pixman.h"
#include "ui/egl-helpers.h"
@@ -78,6 +80,7 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
res->base.height = c2d.height;
res->base.format = c2d.format;
res->base.resource_id = c2d.resource_id;
+ res->base.dmabuf_fd = -1;
QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);
args.handle = c2d.resource_id;
@@ -125,6 +128,7 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
res->base.height = c3d.height;
res->base.format = c3d.format;
res->base.resource_id = c3d.resource_id;
+ res->base.dmabuf_fd = -1;
QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);
args.handle = c3d.resource_id;
@@ -509,6 +513,106 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
g_free(resp);
}
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
+ struct virtio_gpu_ctrl_command *cmd)
+{
+ struct virtio_gpu_framebuffer fb = { 0 };
+ struct virgl_renderer_resource_info info;
+ struct virtio_gpu_virgl_resource *res;
+ struct virtio_gpu_set_scanout_blob ss;
+ uint64_t fbend;
+
+ VIRTIO_GPU_FILL_CMD(ss);
+ virtio_gpu_scanout_blob_bswap(&ss);
+ trace_virtio_gpu_cmd_set_scanout_blob(ss.scanout_id, ss.resource_id,
+ ss.r.width, ss.r.height, ss.r.x,
+ ss.r.y);
+
+ if (ss.scanout_id >= g->parent_obj.conf.max_outputs) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
+ __func__, ss.scanout_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
+ return;
+ }
+
+ if (ss.resource_id == 0) {
+ virtio_gpu_disable_scanout(g, ss.scanout_id);
+ return;
+ }
+
+ if (ss.width < 16 ||
+ ss.height < 16 ||
+ ss.r.x + ss.r.width > ss.width ||
+ ss.r.y + ss.r.height > ss.height) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
+ " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n",
+ __func__, ss.scanout_id, ss.resource_id,
+ ss.r.x, ss.r.y, ss.r.width, ss.r.height,
+ ss.width, ss.height);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+ return;
+ }
+
+ res = virtio_gpu_virgl_find_resource(g, ss.resource_id);
+ if (!res) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not exist %d\n",
+ __func__, ss.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+ if (virgl_renderer_resource_get_info(ss.resource_id, &info)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not have info %d\n",
+ __func__, ss.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+ if (res->base.dmabuf_fd < 0) {
+ res->base.dmabuf_fd = info.fd;
+ }
+ if (res->base.dmabuf_fd < 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource not backed by dmabuf %d\n",
+ __func__, ss.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ fb.format = virtio_gpu_get_pixman_format(ss.format);
+ if (!fb.format) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: pixel format not supported %d\n",
+ __func__, ss.format);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+ return;
+ }
+
+ fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
+ fb.width = ss.width;
+ fb.height = ss.height;
+ fb.stride = ss.strides[0];
+ fb.offset = ss.offsets[0] + ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
+
+ fbend = fb.offset;
+ fbend += fb.stride * (ss.r.height - 1);
+ fbend += fb.bytes_pp * ss.r.width;
+ if (fbend > res->base.blob_size) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: fb end out of range\n",
+ __func__);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+ return;
+ }
+
+ g->parent_obj.enable = 1;
+ if (virtio_gpu_update_dmabuf(g, ss.scanout_id, &res->base, &fb, &ss.r)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to update dmabuf\n",
+ __func__);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+ return;
+ }
+
+ virtio_gpu_update_scanout(g, ss.scanout_id, &res->base, &fb, &ss.r);
+}
+#endif /* HAVE_VIRGL_RESOURCE_BLOB */
+
void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
{
@@ -575,6 +679,11 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
case VIRTIO_GPU_CMD_GET_EDID:
virtio_gpu_get_edid(g, cmd);
break;
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+ case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
+ virgl_cmd_set_scanout_blob(g, cmd);
+ break;
+#endif /* HAVE_VIRGL_RESOURCE_BLOB */
default:
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
break;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 672279e57f3f..f3d2def9a49f 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -380,7 +380,7 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
}
-static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
+void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
{
struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
struct virtio_gpu_simple_resource *res;
@@ -597,11 +597,11 @@ static void virtio_unref_resource(pixman_image_t *image, void *data)
pixman_image_unref(data);
}
-static void virtio_gpu_update_scanout(VirtIOGPU *g,
- uint32_t scanout_id,
- struct virtio_gpu_simple_resource *res,
- struct virtio_gpu_framebuffer *fb,
- struct virtio_gpu_rect *r)
+void virtio_gpu_update_scanout(VirtIOGPU *g,
+ uint32_t scanout_id,
+ struct virtio_gpu_simple_resource *res,
+ struct virtio_gpu_framebuffer *fb,
+ struct virtio_gpu_rect *r)
{
struct virtio_gpu_simple_resource *ores;
struct virtio_gpu_scanout *scanout;
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 2faeda6f6abe..0bfdfd91db46 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -338,6 +338,13 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g,
struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_rect *r);
+void virtio_gpu_update_scanout(VirtIOGPU *g,
+ uint32_t scanout_id,
+ struct virtio_gpu_simple_resource *res,
+ struct virtio_gpu_framebuffer *fb,
+ struct virtio_gpu_rect *r);
+void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id);
+
/* virtio-gpu-3d.c */
void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd);
diff --git a/meson.build b/meson.build
index 65fddfbbc3a7..e753da4c76c3 100644
--- a/meson.build
+++ b/meson.build
@@ -2311,6 +2311,7 @@ config_host_data.set('CONFIG_VNC_SASL', sasl.found())
if virgl.version().version_compare('>=1.0.0')
config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT', 1)
config_host_data.set('HAVE_VIRGL_CONTEXT_CREATE_WITH_FLAGS', 1)
+ config_host_data.set('HAVE_VIRGL_RESOURCE_BLOB', 1)
endif
config_host_data.set('CONFIG_VIRTFS', have_virtfs)
config_host_data.set('CONFIG_VTE', vte.found())
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v13 09/13] virtio-gpu: Support blob scanout using dmabuf fd
2024-05-27 3:02 ` [PATCH v13 09/13] virtio-gpu: Support blob scanout using dmabuf fd Dmitry Osipenko
@ 2024-06-04 14:39 ` Marc-André Lureau
0 siblings, 0 replies; 28+ messages in thread
From: Marc-André Lureau @ 2024-06-04 14:39 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Akihiko Odaki, Huang Rui, Philippe Mathieu-Daudé,
Gerd Hoffmann, Michael S . Tsirkin, Stefano Stabellini,
Antonio Caggiano, Dr . David Alan Gilbert, Robert Beckett,
Gert Wollny, Alex Bennée, qemu-devel, Gurchetan Singh,
ernunes, Alyssa Ross, Roger Pau Monné, Alex Deucher,
Stefano Stabellini, Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
[-- Attachment #1: Type: text/plain, Size: 9919 bytes --]
Hi
On Mon, May 27, 2024 at 7:03 AM Dmitry Osipenko <
dmitry.osipenko@collabora.com> wrote:
> From: Robert Beckett <bob.beckett@collabora.com>
>
> Support displaying blob resources by handling SET_SCANOUT_BLOB
> command.
>
> Signed-by: Antonio Caggiano <antonio.caggiano@collabora.com>
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
> Signed-off-by: Huang Rui <ray.huang@amd.com>
> Reviewed-by: Antonio Caggiano <quic_acaggian@quicinc.com>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu-virgl.c | 109 +++++++++++++++++++++++++++++++++
> hw/display/virtio-gpu.c | 12 ++--
> include/hw/virtio/virtio-gpu.h | 7 +++
> meson.build | 1 +
> 4 files changed, 123 insertions(+), 6 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index 8392d0fde984..7f45b4fa5fd7 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -17,6 +17,8 @@
> #include "trace.h"
> #include "hw/virtio/virtio.h"
> #include "hw/virtio/virtio-gpu.h"
> +#include "hw/virtio/virtio-gpu-bswap.h"
> +#include "hw/virtio/virtio-gpu-pixman.h"
>
> #include "ui/egl-helpers.h"
>
> @@ -78,6 +80,7 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
> res->base.height = c2d.height;
> res->base.format = c2d.format;
> res->base.resource_id = c2d.resource_id;
> + res->base.dmabuf_fd = -1;
> QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);
>
> args.handle = c2d.resource_id;
> @@ -125,6 +128,7 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
> res->base.height = c3d.height;
> res->base.format = c3d.format;
> res->base.resource_id = c3d.resource_id;
> + res->base.dmabuf_fd = -1;
> QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);
>
> args.handle = c3d.resource_id;
> @@ -509,6 +513,106 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
> g_free(resp);
> }
>
> +#ifdef HAVE_VIRGL_RESOURCE_BLOB
> +static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
> + struct virtio_gpu_ctrl_command
> *cmd)
> +{
> + struct virtio_gpu_framebuffer fb = { 0 };
> + struct virgl_renderer_resource_info info;
> + struct virtio_gpu_virgl_resource *res;
> + struct virtio_gpu_set_scanout_blob ss;
> + uint64_t fbend;
> +
> + VIRTIO_GPU_FILL_CMD(ss);
> + virtio_gpu_scanout_blob_bswap(&ss);
> + trace_virtio_gpu_cmd_set_scanout_blob(ss.scanout_id, ss.resource_id,
> + ss.r.width, ss.r.height, ss.r.x,
> + ss.r.y);
> +
> + if (ss.scanout_id >= g->parent_obj.conf.max_outputs) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified
> %d",
> + __func__, ss.scanout_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
> + return;
> + }
> +
> + if (ss.resource_id == 0) {
> + virtio_gpu_disable_scanout(g, ss.scanout_id);
> + return;
> + }
> +
> + if (ss.width < 16 ||
> + ss.height < 16 ||
> + ss.r.x + ss.r.width > ss.width ||
> + ss.r.y + ss.r.height > ss.height) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
> + " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n",
> + __func__, ss.scanout_id, ss.resource_id,
> + ss.r.x, ss.r.y, ss.r.width, ss.r.height,
> + ss.width, ss.height);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
> + return;
> + }
> +
> + res = virtio_gpu_virgl_find_resource(g, ss.resource_id);
> + if (!res) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not exist %d\n",
> + __func__, ss.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> + if (virgl_renderer_resource_get_info(ss.resource_id, &info)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not have info
> %d\n",
> + __func__, ss.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> + if (res->base.dmabuf_fd < 0) {
> + res->base.dmabuf_fd = info.fd;
> + }
> + if (res->base.dmabuf_fd < 0) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource not backed by dmabuf
> %d\n",
> + __func__, ss.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> +
> + fb.format = virtio_gpu_get_pixman_format(ss.format);
> + if (!fb.format) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: pixel format not supported
> %d\n",
> + __func__, ss.format);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
> + return;
> + }
> +
> + fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
> + fb.width = ss.width;
> + fb.height = ss.height;
> + fb.stride = ss.strides[0];
> + fb.offset = ss.offsets[0] + ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
> +
> + fbend = fb.offset;
> + fbend += fb.stride * (ss.r.height - 1);
> + fbend += fb.bytes_pp * ss.r.width;
> + if (fbend > res->base.blob_size) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: fb end out of range\n",
> + __func__);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
> + return;
> + }
> +
> + g->parent_obj.enable = 1;
> + if (virtio_gpu_update_dmabuf(g, ss.scanout_id, &res->base, &fb,
> &ss.r)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to update dmabuf\n",
> + __func__);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
> + return;
> + }
> +
> + virtio_gpu_update_scanout(g, ss.scanout_id, &res->base, &fb, &ss.r);
> +}
> +#endif /* HAVE_VIRGL_RESOURCE_BLOB */
> +
> void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
> struct virtio_gpu_ctrl_command *cmd)
> {
> @@ -575,6 +679,11 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
> case VIRTIO_GPU_CMD_GET_EDID:
> virtio_gpu_get_edid(g, cmd);
> break;
> +#ifdef HAVE_VIRGL_RESOURCE_BLOB
> + case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
> + virgl_cmd_set_scanout_blob(g, cmd);
> + break;
> +#endif /* HAVE_VIRGL_RESOURCE_BLOB */
> default:
> cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
> break;
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index 672279e57f3f..f3d2def9a49f 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -380,7 +380,7 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU
> *g,
> QTAILQ_INSERT_HEAD(&g->reslist, res, next);
> }
>
> -static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
> +void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
> {
> struct virtio_gpu_scanout *scanout =
> &g->parent_obj.scanout[scanout_id];
> struct virtio_gpu_simple_resource *res;
> @@ -597,11 +597,11 @@ static void virtio_unref_resource(pixman_image_t
> *image, void *data)
> pixman_image_unref(data);
> }
>
> -static void virtio_gpu_update_scanout(VirtIOGPU *g,
> - uint32_t scanout_id,
> - struct virtio_gpu_simple_resource
> *res,
> - struct virtio_gpu_framebuffer *fb,
> - struct virtio_gpu_rect *r)
> +void virtio_gpu_update_scanout(VirtIOGPU *g,
> + uint32_t scanout_id,
> + struct virtio_gpu_simple_resource *res,
> + struct virtio_gpu_framebuffer *fb,
> + struct virtio_gpu_rect *r)
> {
> struct virtio_gpu_simple_resource *ores;
> struct virtio_gpu_scanout *scanout;
> diff --git a/include/hw/virtio/virtio-gpu.h
> b/include/hw/virtio/virtio-gpu.h
> index 2faeda6f6abe..0bfdfd91db46 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -338,6 +338,13 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g,
> struct virtio_gpu_framebuffer *fb,
> struct virtio_gpu_rect *r);
>
> +void virtio_gpu_update_scanout(VirtIOGPU *g,
> + uint32_t scanout_id,
> + struct virtio_gpu_simple_resource *res,
> + struct virtio_gpu_framebuffer *fb,
> + struct virtio_gpu_rect *r);
> +void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id);
> +
> /* virtio-gpu-3d.c */
> void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
> struct virtio_gpu_ctrl_command *cmd);
> diff --git a/meson.build b/meson.build
> index 65fddfbbc3a7..e753da4c76c3 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2311,6 +2311,7 @@ config_host_data.set('CONFIG_VNC_SASL', sasl.found())
> if virgl.version().version_compare('>=1.0.0')
> config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT', 1)
> config_host_data.set('HAVE_VIRGL_CONTEXT_CREATE_WITH_FLAGS', 1)
> + config_host_data.set('HAVE_VIRGL_RESOURCE_BLOB', 1)
>
Instead of accumulating various #define values, we could simply have
HAVE_VIRGL1 or something..
Alternatively, virgl.version().version_compare('>=1.0.1') and use #if
VIRGL_MAJOR_VERSION >= 1 in the code.
(the VIRGL_CHECK_VERSION macro is borked, it needs a 1.0.2 release)
--
Marc-André Lureau
[-- Attachment #2: Type: text/html, Size: 12421 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v13 10/13] virtio-gpu: Support suspension of commands processing
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (8 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 09/13] virtio-gpu: Support blob scanout using dmabuf fd Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-06-04 14:44 ` Marc-André Lureau
2024-05-27 3:02 ` [PATCH v13 11/13] virtio-gpu: Handle resource blob commands Dmitry Osipenko
` (2 subsequent siblings)
12 siblings, 1 reply; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
Check whether command processing has been finished; otherwise, stop
processing commands and retry the command again next time. This allows
us to support asynchronous execution of non-fenced commands needed for
unmapping host blobs safely.
Suggested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f3d2def9a49f..8e05a2d0c7c5 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1054,6 +1054,11 @@ void virtio_gpu_process_cmdq(VirtIOGPU *g)
/* process command */
vgc->process_cmd(g, cmd);
+ /* command suspended */
+ if (!cmd->finished && !(cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE)) {
+ break;
+ }
+
QTAILQ_REMOVE(&g->cmdq, cmd, next);
if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
g->stats.requests++;
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v13 10/13] virtio-gpu: Support suspension of commands processing
2024-05-27 3:02 ` [PATCH v13 10/13] virtio-gpu: Support suspension of commands processing Dmitry Osipenko
@ 2024-06-04 14:44 ` Marc-André Lureau
0 siblings, 0 replies; 28+ messages in thread
From: Marc-André Lureau @ 2024-06-04 14:44 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Akihiko Odaki, Huang Rui, Philippe Mathieu-Daudé,
Gerd Hoffmann, Michael S . Tsirkin, Stefano Stabellini,
Antonio Caggiano, Dr . David Alan Gilbert, Robert Beckett,
Gert Wollny, Alex Bennée, qemu-devel, Gurchetan Singh,
ernunes, Alyssa Ross, Roger Pau Monné, Alex Deucher,
Stefano Stabellini, Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
[-- Attachment #1: Type: text/plain, Size: 1465 bytes --]
Hi
On Mon, May 27, 2024 at 7:03 AM Dmitry Osipenko <
dmitry.osipenko@collabora.com> wrote:
> Check whether command processing has been finished; otherwise, stop
> processing commands and retry the command again next time. This allows
> us to support asynchronous execution of non-fenced commands needed for
> unmapping host blobs safely.
>
> Suggested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index f3d2def9a49f..8e05a2d0c7c5 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -1054,6 +1054,11 @@ void virtio_gpu_process_cmdq(VirtIOGPU *g)
> /* process command */
> vgc->process_cmd(g, cmd);
>
> + /* command suspended */
> + if (!cmd->finished && !(cmd->cmd_hdr.flags &
> VIRTIO_GPU_FLAG_FENCE)) {
>
Since this is not tracked in "inflight" debugging, it would be worth adding
a trace for this early break.
Btw, if you could replace the fprintf below with a trace as well, this
would be a nice cleanup too
> + break;
> + }
> +
> QTAILQ_REMOVE(&g->cmdq, cmd, next);
> if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
> g->stats.requests++;
> --
> 2.44.0
>
>
--
Marc-André Lureau
[-- Attachment #2: Type: text/html, Size: 2370 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v13 11/13] virtio-gpu: Handle resource blob commands
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (9 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 10/13] virtio-gpu: Support suspension of commands processing Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-06-02 5:45 ` Akihiko Odaki
2024-05-27 3:02 ` [PATCH v13 12/13] virtio-gpu: Register capsets dynamically Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 13/13] virtio-gpu: Support Venus context Dmitry Osipenko
12 siblings, 1 reply; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
From: Antonio Caggiano <antonio.caggiano@collabora.com>
Support BLOB resources creation, mapping and unmapping by calling the
new stable virglrenderer 0.10 interface. Only enabled when available and
via the blob config. E.g. -device virtio-vga-gl,blob=true
Signed-off-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Signed-off-by: Xenia Ragiadakou <xenia.ragiadakou@amd.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-virgl.c | 320 ++++++++++++++++++++++++++++++++-
hw/display/virtio-gpu.c | 4 +-
include/hw/virtio/virtio-gpu.h | 2 +
3 files changed, 322 insertions(+), 4 deletions(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 7f45b4fa5fd7..0c73d9ba65f9 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -26,6 +26,7 @@
struct virtio_gpu_virgl_resource {
struct virtio_gpu_simple_resource base;
+ MemoryRegion *mr;
};
static struct virtio_gpu_virgl_resource *
@@ -49,6 +50,159 @@ virgl_get_egl_display(G_GNUC_UNUSED void *cookie)
}
#endif
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+typedef enum {
+ HOSTMEM_MR_MAPPED,
+ HOSTMEM_MR_UNMAPPING,
+ HOSTMEM_MR_FINISH_UNMAPPING,
+} HostmemMRState;
+
+struct virtio_gpu_virgl_hostmem_region {
+ MemoryRegion mr;
+ struct VirtIOGPU *g;
+ HostmemMRState state;
+};
+
+static struct virtio_gpu_virgl_hostmem_region *
+to_hostmem_region(MemoryRegion *mr)
+{
+ return container_of(mr, struct virtio_gpu_virgl_hostmem_region, mr);
+}
+
+static void virtio_gpu_virgl_resume_cmdq_bh(void *opaque)
+{
+ VirtIOGPU *g = opaque;
+
+ virtio_gpu_process_cmdq(g);
+}
+
+static void virtio_gpu_virgl_hostmem_region_free(void *obj)
+{
+ MemoryRegion *mr = MEMORY_REGION(obj);
+ struct virtio_gpu_virgl_hostmem_region *vmr;
+ VirtIOGPUBase *b;
+ VirtIOGPUGL *gl;
+
+ vmr = to_hostmem_region(mr);
+ vmr->state = HOSTMEM_MR_FINISH_UNMAPPING;
+
+ b = VIRTIO_GPU_BASE(vmr->g);
+ b->renderer_blocked--;
+
+ /*
+ * memory_region_unref() is executed from RCU thread context, while
+ * virglrenderer works only on the main-loop thread that's holding GL
+ * context.
+ */
+ gl = VIRTIO_GPU_GL(vmr->g);
+ qemu_bh_schedule(gl->cmdq_resume_bh);
+}
+
+static int
+virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
+ struct virtio_gpu_virgl_resource *res,
+ uint64_t offset)
+{
+ struct virtio_gpu_virgl_hostmem_region *vmr;
+ VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
+ MemoryRegion *mr;
+ uint64_t size;
+ void *data;
+ int ret;
+
+ if (!virtio_gpu_hostmem_enabled(b->conf)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: hostmem disabled\n", __func__);
+ return -EOPNOTSUPP;
+ }
+
+ ret = virgl_renderer_resource_map(res->base.resource_id, &data, &size);
+ if (ret) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map virgl resource: %s\n",
+ __func__, strerror(-ret));
+ return ret;
+ }
+
+ vmr = g_new0(struct virtio_gpu_virgl_hostmem_region, 1);
+ vmr->g = g;
+
+ mr = &vmr->mr;
+ memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
+ memory_region_add_subregion(&b->hostmem, offset, mr);
+ memory_region_set_enabled(mr, true);
+
+ /*
+ * MR could outlive the resource if MR's reference is held outside of
+ * virtio-gpu. In order to prevent unmapping resource while MR is alive,
+ * and thus, making the data pointer invalid, we will block virtio-gpu
+ * command processing until MR is fully unreferenced and freed.
+ */
+ OBJECT(mr)->free = virtio_gpu_virgl_hostmem_region_free;
+
+ res->mr = mr;
+
+ return 0;
+}
+
+static int
+virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
+ struct virtio_gpu_virgl_resource *res,
+ bool *cmd_suspended)
+{
+ struct virtio_gpu_virgl_hostmem_region *vmr;
+ VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
+ MemoryRegion *mr = res->mr;
+ int ret;
+
+ if (!mr) {
+ return 0;
+ }
+
+ vmr = to_hostmem_region(res->mr);
+
+ /*
+ * Perform async unmapping in 3 steps:
+ *
+ * 1. Begin async unmapping with memory_region_del_subregion()
+ * and suspend/block cmd processing.
+ * 2. Wait for res->mr to be freed and cmd processing resumed
+ * asynchronously by virtio_gpu_virgl_hostmem_region_free().
+ * 3. Finish the unmapping with final virgl_renderer_resource_unmap().
+ */
+
+ switch (vmr->state) {
+ case HOSTMEM_MR_MAPPED:
+ vmr->state = HOSTMEM_MR_UNMAPPING;
+
+ *cmd_suspended = true;
+
+ /* render will be unblocked once MR is freed */
+ b->renderer_blocked++;
+
+ /* memory region owns self res->mr object and frees it by itself */
+ memory_region_set_enabled(mr, false);
+ memory_region_del_subregion(&b->hostmem, mr);
+ object_unparent(OBJECT(mr));
+ break;
+ case HOSTMEM_MR_FINISH_UNMAPPING:
+ ret = virgl_renderer_resource_unmap(res->base.resource_id);
+ if (ret) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: failed to unmap virgl resource: %s\n",
+ __func__, strerror(-ret));
+ return ret;
+ }
+ res->mr = NULL;
+ g_free(vmr);
+ break;
+ case HOSTMEM_MR_UNMAPPING:
+ *cmd_suspended = true;
+ break;
+ }
+
+ return 0;
+}
+#endif /* HAVE_VIRGL_RESOURCE_BLOB */
+
static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
{
@@ -146,7 +300,8 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
}
static void virgl_cmd_resource_unref(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
+ struct virtio_gpu_ctrl_command *cmd,
+ bool *cmd_suspended)
{
struct virtio_gpu_resource_unref unref;
struct virtio_gpu_virgl_resource *res;
@@ -164,6 +319,16 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
return;
}
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+ if (virtio_gpu_virgl_unmap_resource_blob(g, res, cmd_suspended)) {
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ return;
+ }
+ if (*cmd_suspended) {
+ return;
+ }
+#endif
+
virgl_renderer_resource_detach_iov(unref.resource_id,
&res_iovs,
&num_iovs);
@@ -514,6 +679,133 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
}
#ifdef HAVE_VIRGL_RESOURCE_BLOB
+static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
+ struct virtio_gpu_ctrl_command *cmd)
+{
+ struct virgl_renderer_resource_create_blob_args virgl_args = { 0 };
+ struct virtio_gpu_resource_create_blob cblob;
+ struct virtio_gpu_virgl_resource *res;
+ int ret;
+
+ if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+ return;
+ }
+
+ VIRTIO_GPU_FILL_CMD(cblob);
+ virtio_gpu_create_blob_bswap(&cblob);
+ trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
+
+ if (cblob.resource_id == 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+ __func__);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ res = virtio_gpu_virgl_find_resource(g, cblob.resource_id);
+ if (res) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+ __func__, cblob.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ res = g_new0(struct virtio_gpu_virgl_resource, 1);
+ res->base.resource_id = cblob.resource_id;
+ res->base.blob_size = cblob.size;
+ res->base.dmabuf_fd = -1;
+
+ if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_HOST3D) {
+ ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
+ cmd, &res->base.addrs,
+ &res->base.iov, &res->base.iov_cnt);
+ if (!ret) {
+ g_free(res);
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ return;
+ }
+ }
+
+ virgl_args.res_handle = cblob.resource_id;
+ virgl_args.ctx_id = cblob.hdr.ctx_id;
+ virgl_args.blob_mem = cblob.blob_mem;
+ virgl_args.blob_id = cblob.blob_id;
+ virgl_args.blob_flags = cblob.blob_flags;
+ virgl_args.size = cblob.size;
+ virgl_args.iovecs = res->base.iov;
+ virgl_args.num_iovs = res->base.iov_cnt;
+
+ ret = virgl_renderer_resource_create_blob(&virgl_args);
+ if (ret) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: virgl blob create error: %s\n",
+ __func__, strerror(-ret));
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ virtio_gpu_cleanup_mapping(g, &res->base);
+ g_free(res);
+ return;
+ }
+
+ QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);
+}
+
+static void virgl_cmd_resource_map_blob(VirtIOGPU *g,
+ struct virtio_gpu_ctrl_command *cmd)
+{
+ struct virtio_gpu_resource_map_blob mblob;
+ struct virtio_gpu_virgl_resource *res;
+ struct virtio_gpu_resp_map_info resp;
+ int ret;
+
+ VIRTIO_GPU_FILL_CMD(mblob);
+ virtio_gpu_map_blob_bswap(&mblob);
+
+ res = virtio_gpu_virgl_find_resource(g, mblob.resource_id);
+ if (!res) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not exist %d\n",
+ __func__, mblob.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ ret = virtio_gpu_virgl_map_resource_blob(g, res, mblob.offset);
+ if (ret) {
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ return;
+ }
+
+ memset(&resp, 0, sizeof(resp));
+ resp.hdr.type = VIRTIO_GPU_RESP_OK_MAP_INFO;
+ virgl_renderer_resource_get_map_info(mblob.resource_id, &resp.map_info);
+ virtio_gpu_ctrl_response(g, cmd, &resp.hdr, sizeof(resp));
+}
+
+static void virgl_cmd_resource_unmap_blob(VirtIOGPU *g,
+ struct virtio_gpu_ctrl_command *cmd,
+ bool *cmd_suspended)
+{
+ struct virtio_gpu_resource_unmap_blob ublob;
+ struct virtio_gpu_virgl_resource *res;
+ int ret;
+
+ VIRTIO_GPU_FILL_CMD(ublob);
+ virtio_gpu_unmap_blob_bswap(&ublob);
+
+ res = virtio_gpu_virgl_find_resource(g, ublob.resource_id);
+ if (!res) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not exist %d\n",
+ __func__, ublob.resource_id);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+ return;
+ }
+
+ ret = virtio_gpu_virgl_unmap_resource_blob(g, res, cmd_suspended);
+ if (ret) {
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ return;
+ }
+}
+
static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
{
@@ -616,6 +908,8 @@ static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
{
+ bool cmd_suspended = false;
+
VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr);
virgl_renderer_force_ctx_0();
@@ -657,7 +951,7 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
virgl_cmd_resource_flush(g, cmd);
break;
case VIRTIO_GPU_CMD_RESOURCE_UNREF:
- virgl_cmd_resource_unref(g, cmd);
+ virgl_cmd_resource_unref(g, cmd, &cmd_suspended);
break;
case VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE:
/* TODO add security */
@@ -680,6 +974,15 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
virtio_gpu_get_edid(g, cmd);
break;
#ifdef HAVE_VIRGL_RESOURCE_BLOB
+ case VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB:
+ virgl_cmd_resource_create_blob(g, cmd);
+ break;
+ case VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB:
+ virgl_cmd_resource_map_blob(g, cmd);
+ break;
+ case VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB:
+ virgl_cmd_resource_unmap_blob(g, cmd, &cmd_suspended);
+ break;
case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
virgl_cmd_set_scanout_blob(g, cmd);
break;
@@ -689,7 +992,7 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
break;
}
- if (cmd->finished) {
+ if (cmd_suspended || cmd->finished) {
return;
}
if (cmd->error) {
@@ -858,6 +1161,13 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
timer_mod(gl->print_stats,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000);
}
+
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+ gl->cmdq_resume_bh = aio_bh_new(qemu_get_aio_context(),
+ virtio_gpu_virgl_resume_cmdq_bh,
+ g);
+#endif
+
return 0;
}
@@ -875,6 +1185,10 @@ void virtio_gpu_virgl_deinit(VirtIOGPU *g)
{
VirtIOGPUGL *gl = VIRTIO_GPU_GL(g);
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+ qemu_bh_delete(gl->cmdq_resume_bh);
+#endif
+
if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
timer_free(gl->print_stats);
}
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 8e05a2d0c7c5..d423bc9a7bf5 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1496,10 +1496,12 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
return;
}
+#ifndef HAVE_VIRGL_RESOURCE_BLOB
if (virtio_gpu_virgl_enabled(g->parent_obj.conf)) {
- error_setg(errp, "blobs and virgl are not compatible (yet)");
+ error_setg(errp, "old virglrenderer, blob resources unsupported");
return;
}
+#endif
}
if (!virtio_gpu_base_device_realize(qdev,
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 0bfdfd91db46..368f96a813c9 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -239,6 +239,8 @@ struct VirtIOGPUGL {
QEMUTimer *fence_poll;
QEMUTimer *print_stats;
+
+ QEMUBH *cmdq_resume_bh;
};
struct VhostUserGPU {
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v13 11/13] virtio-gpu: Handle resource blob commands
2024-05-27 3:02 ` [PATCH v13 11/13] virtio-gpu: Handle resource blob commands Dmitry Osipenko
@ 2024-06-02 5:45 ` Akihiko Odaki
2024-06-03 5:32 ` Dmitry Osipenko
0 siblings, 1 reply; 28+ messages in thread
From: Akihiko Odaki @ 2024-06-02 5:45 UTC (permalink / raw)
To: Dmitry Osipenko, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 2024/05/27 12:02, Dmitry Osipenko wrote:
> From: Antonio Caggiano <antonio.caggiano@collabora.com>
>
> Support BLOB resources creation, mapping and unmapping by calling the
> new stable virglrenderer 0.10 interface. Only enabled when available and
> via the blob config. E.g. -device virtio-vga-gl,blob=true
>
> Signed-off-by: Antonio Caggiano <antonio.caggiano@collabora.com>
> Signed-off-by: Xenia Ragiadakou <xenia.ragiadakou@amd.com>
> Signed-off-by: Huang Rui <ray.huang@amd.com>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu-virgl.c | 320 ++++++++++++++++++++++++++++++++-
> hw/display/virtio-gpu.c | 4 +-
> include/hw/virtio/virtio-gpu.h | 2 +
> 3 files changed, 322 insertions(+), 4 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index 7f45b4fa5fd7..0c73d9ba65f9 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -26,6 +26,7 @@
>
> struct virtio_gpu_virgl_resource {
> struct virtio_gpu_simple_resource base;
> + MemoryRegion *mr;
> };
>
> static struct virtio_gpu_virgl_resource *
> @@ -49,6 +50,159 @@ virgl_get_egl_display(G_GNUC_UNUSED void *cookie)
> }
> #endif
>
> +#ifdef HAVE_VIRGL_RESOURCE_BLOB
> +typedef enum {
> + HOSTMEM_MR_MAPPED,
> + HOSTMEM_MR_UNMAPPING,
> + HOSTMEM_MR_FINISH_UNMAPPING,
> +} HostmemMRState;
> +
> +struct virtio_gpu_virgl_hostmem_region {
> + MemoryRegion mr;
> + struct VirtIOGPU *g;
> + HostmemMRState state;
> +};
> +
> +static struct virtio_gpu_virgl_hostmem_region *
> +to_hostmem_region(MemoryRegion *mr)
> +{
> + return container_of(mr, struct virtio_gpu_virgl_hostmem_region, mr);
> +}
> +
> +static void virtio_gpu_virgl_resume_cmdq_bh(void *opaque)
> +{
> + VirtIOGPU *g = opaque;
> +
> + virtio_gpu_process_cmdq(g);
> +}
> +
> +static void virtio_gpu_virgl_hostmem_region_free(void *obj)
> +{
> + MemoryRegion *mr = MEMORY_REGION(obj);
> + struct virtio_gpu_virgl_hostmem_region *vmr;
> + VirtIOGPUBase *b;
> + VirtIOGPUGL *gl;
> +
> + vmr = to_hostmem_region(mr);
> + vmr->state = HOSTMEM_MR_FINISH_UNMAPPING;
> +
> + b = VIRTIO_GPU_BASE(vmr->g);
> + b->renderer_blocked--;
> +
> + /*
> + * memory_region_unref() is executed from RCU thread context, while
> + * virglrenderer works only on the main-loop thread that's holding GL
> + * context.
> + */
> + gl = VIRTIO_GPU_GL(vmr->g);
> + qemu_bh_schedule(gl->cmdq_resume_bh);
> +}
> +
> +static int
> +virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
> + struct virtio_gpu_virgl_resource *res,
> + uint64_t offset)
> +{
> + struct virtio_gpu_virgl_hostmem_region *vmr;
> + VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
> + MemoryRegion *mr;
> + uint64_t size;
> + void *data;
> + int ret;
> +
> + if (!virtio_gpu_hostmem_enabled(b->conf)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: hostmem disabled\n", __func__);
> + return -EOPNOTSUPP;
> + }
> +
> + ret = virgl_renderer_resource_map(res->base.resource_id, &data, &size);
> + if (ret) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map virgl resource: %s\n",
> + __func__, strerror(-ret));
> + return ret;
> + }
> +
> + vmr = g_new0(struct virtio_gpu_virgl_hostmem_region, 1);
> + vmr->g = g;
> +
> + mr = &vmr->mr;
> + memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
> + memory_region_add_subregion(&b->hostmem, offset, mr);
> + memory_region_set_enabled(mr, true);
> +
> + /*
> + * MR could outlive the resource if MR's reference is held outside of
> + * virtio-gpu. In order to prevent unmapping resource while MR is alive,
> + * and thus, making the data pointer invalid, we will block virtio-gpu
> + * command processing until MR is fully unreferenced and freed.
> + */
> + OBJECT(mr)->free = virtio_gpu_virgl_hostmem_region_free;
> +
> + res->mr = mr;
> +
> + return 0;
> +}
> +
> +static int
> +virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
> + struct virtio_gpu_virgl_resource *res,
> + bool *cmd_suspended)
> +{
> + struct virtio_gpu_virgl_hostmem_region *vmr;
> + VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
> + MemoryRegion *mr = res->mr;
> + int ret;
> +
> + if (!mr) {
> + return 0;
> + }
> +
> + vmr = to_hostmem_region(res->mr);
> +
> + /*
> + * Perform async unmapping in 3 steps:
> + *
> + * 1. Begin async unmapping with memory_region_del_subregion()
> + * and suspend/block cmd processing.
> + * 2. Wait for res->mr to be freed and cmd processing resumed
> + * asynchronously by virtio_gpu_virgl_hostmem_region_free().
> + * 3. Finish the unmapping with final virgl_renderer_resource_unmap().
> + */
> +
> + switch (vmr->state) {
> + case HOSTMEM_MR_MAPPED:
> + vmr->state = HOSTMEM_MR_UNMAPPING;
> +
> + *cmd_suspended = true;
> +
> + /* render will be unblocked once MR is freed */
> + b->renderer_blocked++;
> +
> + /* memory region owns self res->mr object and frees it by itself */
> + memory_region_set_enabled(mr, false);
> + memory_region_del_subregion(&b->hostmem, mr);
> + object_unparent(OBJECT(mr));
> + break;
> + case HOSTMEM_MR_FINISH_UNMAPPING:
> + ret = virgl_renderer_resource_unmap(res->base.resource_id);
> + if (ret) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: failed to unmap virgl resource: %s\n",
> + __func__, strerror(-ret));
> + return ret;
> + }
> + res->mr = NULL;
> + g_free(vmr);
> + break;
> + case HOSTMEM_MR_UNMAPPING:
> + *cmd_suspended = true;
This code path should be unreachable since the command processing is
blocked while unmapping.
> + break;
> + }
> +
> + return 0;
> +}
> +#endif /* HAVE_VIRGL_RESOURCE_BLOB */
> +
> static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
> struct virtio_gpu_ctrl_command *cmd)
> {
> @@ -146,7 +300,8 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
> }
>
> static void virgl_cmd_resource_unref(VirtIOGPU *g,
> - struct virtio_gpu_ctrl_command *cmd)
> + struct virtio_gpu_ctrl_command *cmd,
> + bool *cmd_suspended)
> {
> struct virtio_gpu_resource_unref unref;
> struct virtio_gpu_virgl_resource *res;
> @@ -164,6 +319,16 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
> return;
> }
>
> +#ifdef HAVE_VIRGL_RESOURCE_BLOB
> + if (virtio_gpu_virgl_unmap_resource_blob(g, res, cmd_suspended)) {
> + cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
> + return;
> + }
> + if (*cmd_suspended) {
> + return;
> + }
> +#endif
> +
> virgl_renderer_resource_detach_iov(unref.resource_id,
> &res_iovs,
> &num_iovs);
> @@ -514,6 +679,133 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
> }
>
> #ifdef HAVE_VIRGL_RESOURCE_BLOB
> +static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
> + struct virtio_gpu_ctrl_command *cmd)
> +{
> + struct virgl_renderer_resource_create_blob_args virgl_args = { 0 };
> + struct virtio_gpu_resource_create_blob cblob;
> + struct virtio_gpu_virgl_resource *res;
> + int ret;
> +
> + if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
> + return;
> + }
> +
> + VIRTIO_GPU_FILL_CMD(cblob);
> + virtio_gpu_create_blob_bswap(&cblob);
> + trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
> +
> + if (cblob.resource_id == 0) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
> + __func__);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> +
> + res = virtio_gpu_virgl_find_resource(g, cblob.resource_id);
> + if (res) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
> + __func__, cblob.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> +
> + res = g_new0(struct virtio_gpu_virgl_resource, 1);
> + res->base.resource_id = cblob.resource_id;
> + res->base.blob_size = cblob.size;
> + res->base.dmabuf_fd = -1;
> +
> + if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_HOST3D) {
> + ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
> + cmd, &res->base.addrs,
> + &res->base.iov, &res->base.iov_cnt);
> + if (!ret) {
> + g_free(res);
As noted for an earlier version:
> Use g_autofree instead of writing duplicate g_free() calls. See
> docs/devel/style.rst for details.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 11/13] virtio-gpu: Handle resource blob commands
2024-06-02 5:45 ` Akihiko Odaki
@ 2024-06-03 5:32 ` Dmitry Osipenko
2024-06-03 5:43 ` Akihiko Odaki
0 siblings, 1 reply; 28+ messages in thread
From: Dmitry Osipenko @ 2024-06-03 5:32 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 6/2/24 08:45, Akihiko Odaki wrote:
...
>> + case HOSTMEM_MR_FINISH_UNMAPPING:
>> + ret = virgl_renderer_resource_unmap(res->base.resource_id);
>> + if (ret) {
>> + qemu_log_mask(LOG_GUEST_ERROR,
>> + "%s: failed to unmap virgl resource: %s\n",
>> + __func__, strerror(-ret));
>> + return ret;
>> + }
>> + res->mr = NULL;
>> + g_free(vmr);
>> + break;
>> + case HOSTMEM_MR_UNMAPPING:
>> + *cmd_suspended = true;
>
> This code path should be unreachable since the command processing is
> blocked while unmapping.
Will change to abort()
>> + if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_HOST3D) {
>> + ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries,
>> sizeof(cblob),
>> + cmd, &res->base.addrs,
>> + &res->base.iov,
>> &res->base.iov_cnt);
>> + if (!ret) {
>> + g_free(res);
>
> As noted for an earlier version:
>> Use g_autofree instead of writing duplicate g_free() calls. See
>> docs/devel/style.rst for details.
The g_autofree isn't appropriate for this code. It's intended to be used
if you allocate a tmp variable that should be freed in all code paths.
This is not the case here, the res variable isn't temporal and shall not
be freed on success.
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v13 11/13] virtio-gpu: Handle resource blob commands
2024-06-03 5:32 ` Dmitry Osipenko
@ 2024-06-03 5:43 ` Akihiko Odaki
0 siblings, 0 replies; 28+ messages in thread
From: Akihiko Odaki @ 2024-06-03 5:43 UTC (permalink / raw)
To: Dmitry Osipenko, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
On 2024/06/03 14:32, Dmitry Osipenko wrote:
> On 6/2/24 08:45, Akihiko Odaki wrote:
> ...
>>> + case HOSTMEM_MR_FINISH_UNMAPPING:
>>> + ret = virgl_renderer_resource_unmap(res->base.resource_id);
>>> + if (ret) {
>>> + qemu_log_mask(LOG_GUEST_ERROR,
>>> + "%s: failed to unmap virgl resource: %s\n",
>>> + __func__, strerror(-ret));
>>> + return ret;
>>> + }
>>> + res->mr = NULL;
>>> + g_free(vmr);
>>> + break;
>>> + case HOSTMEM_MR_UNMAPPING:
>>> + *cmd_suspended = true;
>>
>> This code path should be unreachable since the command processing is
>> blocked while unmapping.
>
> Will change to abort()
I don't think abort() call is needed here. You can just do what you do
for HOSTMEM_MR_MAPPED; the reference counter will automatically catch
the double-free condition and abort.
>
>>> + if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_HOST3D) {
>>> + ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries,
>>> sizeof(cblob),
>>> + cmd, &res->base.addrs,
>>> + &res->base.iov,
>>> &res->base.iov_cnt);
>>> + if (!ret) {
>>> + g_free(res);
>>
>> As noted for an earlier version:
>>> Use g_autofree instead of writing duplicate g_free() calls. See
>>> docs/devel/style.rst for details.
>
> The g_autofree isn't appropriate for this code. It's intended to be used
> if you allocate a tmp variable that should be freed in all code paths.
> This is not the case here, the res variable isn't temporal and shall not
> be freed on success.
You can assign NULL to res after QTAILQ_INSERT_HEAD(). See
rutabaga_cmd_resource_create_blob() for example.
Usually g_steal_pointer() should be used in such a situation but
unfortunately it is not possible in this case due to how
QTAILQ_INSERT_HEAD() macro is implemented.
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v13 12/13] virtio-gpu: Register capsets dynamically
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (10 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 11/13] virtio-gpu: Handle resource blob commands Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
2024-05-27 3:02 ` [PATCH v13 13/13] virtio-gpu: Support Venus context Dmitry Osipenko
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
virtio_gpu_virgl_get_num_capsets will return "num_capsets", but we can't
assume that capset_index 1 is always VIRGL2 once we'll support more capsets,
like Venus and DRM capsets. Register capsets dynamically to avoid that problem.
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-gl.c | 6 ++++--
hw/display/virtio-gpu-virgl.c | 33 +++++++++++++++++++++------------
include/hw/virtio/virtio-gpu.h | 4 +++-
3 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index 9822d79c5e81..34a2bd2fa426 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -137,8 +137,8 @@ static void virtio_gpu_gl_device_realize(DeviceState *qdev, Error **errp)
}
g->parent_obj.conf.flags |= (1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED);
- VIRTIO_GPU_BASE(g)->virtio_config.num_capsets =
- virtio_gpu_virgl_get_num_capsets(g);
+ g->capset_ids = virtio_gpu_virgl_get_capsets(g);
+ VIRTIO_GPU_BASE(g)->virtio_config.num_capsets = g->capset_ids->len;
#ifdef HAVE_VIRGL_CONTEXT_CREATE_WITH_FLAGS
g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED;
@@ -163,6 +163,8 @@ static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
}
gl->renderer_state = RS_START;
+
+ g_array_unref(g->capset_ids);
}
static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 0c73d9ba65f9..d3ae3e3d4e24 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -636,19 +636,13 @@ static void virgl_cmd_get_capset_info(VirtIOGPU *g,
VIRTIO_GPU_FILL_CMD(info);
memset(&resp, 0, sizeof(resp));
- if (info.capset_index == 0) {
- resp.capset_id = VIRTIO_GPU_CAPSET_VIRGL;
- virgl_renderer_get_cap_set(resp.capset_id,
- &resp.capset_max_version,
- &resp.capset_max_size);
- } else if (info.capset_index == 1) {
- resp.capset_id = VIRTIO_GPU_CAPSET_VIRGL2;
+
+ if (info.capset_index < g->capset_ids->len) {
+ resp.capset_id = g_array_index(g->capset_ids, uint32_t,
+ info.capset_index);
virgl_renderer_get_cap_set(resp.capset_id,
&resp.capset_max_version,
&resp.capset_max_size);
- } else {
- resp.capset_max_version = 0;
- resp.capset_max_size = 0;
}
resp.hdr.type = VIRTIO_GPU_RESP_OK_CAPSET_INFO;
virtio_gpu_ctrl_response(g, cmd, &resp.hdr, sizeof(resp));
@@ -1171,14 +1165,29 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
return 0;
}
-int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)
+static void virtio_gpu_virgl_add_capset(GArray *capset_ids, uint32_t capset_id)
+{
+ g_array_append_val(capset_ids, capset_id);
+}
+
+GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g)
{
uint32_t capset2_max_ver, capset2_max_size;
+ GArray *capset_ids;
+
+ capset_ids = g_array_new(false, false, sizeof(uint32_t));
+
+ /* VIRGL is always supported. */
+ virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_VIRGL);
+
virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_VIRGL2,
&capset2_max_ver,
&capset2_max_size);
+ if (capset2_max_ver) {
+ virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_VIRGL2);
+ }
- return capset2_max_ver ? 2 : 1;
+ return capset_ids;
}
void virtio_gpu_virgl_deinit(VirtIOGPU *g)
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 368f96a813c9..b9de761fd673 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -209,6 +209,8 @@ struct VirtIOGPU {
QTAILQ_HEAD(, VGPUDMABuf) bufs;
VGPUDMABuf *primary[VIRTIO_GPU_MAX_SCANOUTS];
} dmabuf;
+
+ GArray *capset_ids;
};
struct VirtIOGPUClass {
@@ -355,6 +357,6 @@ void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g);
void virtio_gpu_virgl_reset(VirtIOGPU *g);
int virtio_gpu_virgl_init(VirtIOGPU *g);
void virtio_gpu_virgl_deinit(VirtIOGPU *g);
-int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
+GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g);
#endif
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v13 13/13] virtio-gpu: Support Venus context
2024-05-27 3:02 [PATCH v13 00/13] Support blob memory and venus on qemu Dmitry Osipenko
` (11 preceding siblings ...)
2024-05-27 3:02 ` [PATCH v13 12/13] virtio-gpu: Register capsets dynamically Dmitry Osipenko
@ 2024-05-27 3:02 ` Dmitry Osipenko
12 siblings, 0 replies; 28+ messages in thread
From: Dmitry Osipenko @ 2024-05-27 3:02 UTC (permalink / raw)
To: Akihiko Odaki, Huang Rui, Marc-André Lureau,
Philippe Mathieu-Daudé, Gerd Hoffmann, Michael S . Tsirkin,
Stefano Stabellini, Antonio Caggiano, Dr . David Alan Gilbert,
Robert Beckett, Gert Wollny, Alex Bennée
Cc: qemu-devel, Gurchetan Singh, ernunes, Alyssa Ross,
Roger Pau Monné, Alex Deucher, Stefano Stabellini,
Christian König, Xenia Ragiadakou,
Pierre-Eric Pelloux-Prayer, Honglei Huang, Julia Zhang,
Chen Jiqian, Yiwei Zhang
From: Antonio Caggiano <antonio.caggiano@collabora.com>
Request Venus when initializing VirGL and if venus=true flag is set for
virtio-gpu-gl device.
Signed-off-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
hw/display/virtio-gpu-gl.c | 2 ++
hw/display/virtio-gpu-virgl.c | 22 ++++++++++++++++++----
hw/display/virtio-gpu.c | 13 +++++++++++++
include/hw/virtio/virtio-gpu.h | 3 +++
meson.build | 1 +
5 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index 34a2bd2fa426..50292826e7cf 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -150,6 +150,8 @@ static void virtio_gpu_gl_device_realize(DeviceState *qdev, Error **errp)
static Property virtio_gpu_gl_properties[] = {
DEFINE_PROP_BIT("stats", VirtIOGPU, parent_obj.conf.flags,
VIRTIO_GPU_FLAG_STATS_ENABLED, false),
+ DEFINE_PROP_BIT("venus", VirtIOGPU, parent_obj.conf.flags,
+ VIRTIO_GPU_FLAG_VENUS_ENABLED, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index d3ae3e3d4e24..c9d20a8a60d0 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -1139,6 +1139,11 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
flags |= VIRGL_RENDERER_D3D11_SHARE_TEXTURE;
}
#endif
+#ifdef VIRGL_RENDERER_VENUS
+ if (virtio_gpu_venus_enabled(g->parent_obj.conf)) {
+ flags |= VIRGL_RENDERER_VENUS | VIRGL_RENDERER_RENDER_SERVER;
+ }
+#endif
ret = virgl_renderer_init(g, flags, &virtio_gpu_3d_cbs);
if (ret != 0) {
@@ -1172,7 +1177,7 @@ static void virtio_gpu_virgl_add_capset(GArray *capset_ids, uint32_t capset_id)
GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g)
{
- uint32_t capset2_max_ver, capset2_max_size;
+ uint32_t capset_max_ver, capset_max_size;
GArray *capset_ids;
capset_ids = g_array_new(false, false, sizeof(uint32_t));
@@ -1181,12 +1186,21 @@ GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g)
virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_VIRGL);
virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_VIRGL2,
- &capset2_max_ver,
- &capset2_max_size);
- if (capset2_max_ver) {
+ &capset_max_ver,
+ &capset_max_size);
+ if (capset_max_ver) {
virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_VIRGL2);
}
+ if (virtio_gpu_venus_enabled(g->parent_obj.conf)) {
+ virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_VENUS,
+ &capset_max_ver,
+ &capset_max_size);
+ if (capset_max_size) {
+ virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_VENUS);
+ }
+ }
+
return capset_ids;
}
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index d423bc9a7bf5..0618801715a6 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1504,6 +1504,19 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
#endif
}
+ if (virtio_gpu_venus_enabled(g->parent_obj.conf)) {
+#ifdef HAVE_VIRGL_VENUS
+ if (!virtio_gpu_blob_enabled(g->parent_obj.conf) ||
+ !virtio_gpu_hostmem_enabled(g->parent_obj.conf)) {
+ error_setg(errp, "venus requires enabled blob and hostmem options");
+ return;
+ }
+#else
+ error_setg(errp, "old virglrenderer, venus unsupported");
+ return;
+#endif
+ }
+
if (!virtio_gpu_base_device_realize(qdev,
virtio_gpu_handle_ctrl_cb,
virtio_gpu_handle_cursor_cb,
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index b9de761fd673..910c5c3bcd45 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -99,6 +99,7 @@ enum virtio_gpu_base_conf_flags {
VIRTIO_GPU_FLAG_BLOB_ENABLED,
VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
+ VIRTIO_GPU_FLAG_VENUS_ENABLED,
};
#define virtio_gpu_virgl_enabled(_cfg) \
@@ -117,6 +118,8 @@ enum virtio_gpu_base_conf_flags {
(_cfg.flags & (1 << VIRTIO_GPU_FLAG_RUTABAGA_ENABLED))
#define virtio_gpu_hostmem_enabled(_cfg) \
(_cfg.hostmem > 0)
+#define virtio_gpu_venus_enabled(_cfg) \
+ (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VENUS_ENABLED))
struct virtio_gpu_base_conf {
uint32_t max_outputs;
diff --git a/meson.build b/meson.build
index e753da4c76c3..1d7346b70311 100644
--- a/meson.build
+++ b/meson.build
@@ -2312,6 +2312,7 @@ if virgl.version().version_compare('>=1.0.0')
config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT', 1)
config_host_data.set('HAVE_VIRGL_CONTEXT_CREATE_WITH_FLAGS', 1)
config_host_data.set('HAVE_VIRGL_RESOURCE_BLOB', 1)
+ config_host_data.set('HAVE_VIRGL_VENUS', 1)
endif
config_host_data.set('CONFIG_VIRTFS', have_virtfs)
config_host_data.set('CONFIG_VTE', vte.found())
--
2.44.0
^ permalink raw reply related [flat|nested] 28+ messages in thread