Message ID | 20241006232350.3198759-3-dmitry.osipenko@collabora.com |
---|---|
State | New |
Headers | show |
Series | Support virtio-gpu DRM native context | expand |
On 2024/10/07 8:23, Dmitry Osipenko wrote: > From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> > > If EGL is used, we can rely on dmabuf to import textures without > doing copies. > > To get this working on X11, we use the existing SDL hint: > SDL_HINT_VIDEO_X11_FORCE_EGL (because dmabuf can't be used with GLX). > > Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> > Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> > --- > include/ui/sdl2.h | 5 +++++ > ui/sdl2-gl.c | 39 +++++++++++++++++++++++++++++++++++++++ > ui/sdl2.c | 8 ++++++++ > 3 files changed, 52 insertions(+) > > diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h > index dbe6e3d9739b..b14552f5cd71 100644 > --- a/include/ui/sdl2.h > +++ b/include/ui/sdl2.h > @@ -96,5 +96,10 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl, > void *d3d_tex2d); > void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, > uint32_t x, uint32_t y, uint32_t w, uint32_t h); > +void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl, > + QemuDmaBuf *dmabuf); > +void sdl2_gl_release_dmabuf(DisplayChangeListener *dcl, > + QemuDmaBuf *dmabuf); > +bool sdl2_gl_has_dmabuf(DisplayChangeListener *dcl); > > #endif /* SDL2_H */ > diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c > index b1fe96d6af22..24aa9108682e 100644 > --- a/ui/sdl2-gl.c > +++ b/ui/sdl2-gl.c > @@ -26,6 +26,7 @@ > */ > > #include "qemu/osdep.h" > +#include "qemu/main-loop.h" > #include "ui/console.h" > #include "ui/input.h" > #include "ui/sdl2.h" > @@ -227,6 +228,44 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl, > backing_id, false); > } > > +void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl, > + QemuDmaBuf *dmabuf) > +{ > + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); > + > + assert(scon->opengl); > + SDL_GL_MakeCurrent(scon->real_window, scon->winctx); > + > + egl_dmabuf_import_texture(dmabuf); > + if (!qemu_dmabuf_get_texture(dmabuf)) { > + fprintf(stderr, "sdl2_gl_scanout_dmabuf failed fd=%d\n", > + qemu_dmabuf_get_fd(dmabuf)); Use error_report(). Use __func__ to print the function name. > + } > + > + sdl2_gl_scanout_texture(dcl, qemu_dmabuf_get_texture(dmabuf), false, > + qemu_dmabuf_get_width(dmabuf), > + qemu_dmabuf_get_height(dmabuf), > + 0, 0, > + qemu_dmabuf_get_width(dmabuf), > + qemu_dmabuf_get_height(dmabuf), > + NULL); > + > + if (qemu_dmabuf_get_allow_fences(dmabuf)) { > + scon->guest_fb.dmabuf = dmabuf; > + } > +} > + > +void sdl2_gl_release_dmabuf(DisplayChangeListener *dcl, > + QemuDmaBuf *dmabuf) > +{ > + egl_dmabuf_release_texture(dmabuf); > +} > + > +bool sdl2_gl_has_dmabuf(DisplayChangeListener *dcl) > +{ > + return qemu_egl_has_dmabuf(); > +} > + > void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, > uint32_t x, uint32_t y, uint32_t w, uint32_t h) > { > diff --git a/ui/sdl2.c b/ui/sdl2.c > index bd4f5a9da14a..8c7b01c5e62f 100644 > --- a/ui/sdl2.c > +++ b/ui/sdl2.c > @@ -120,6 +120,9 @@ void sdl2_window_create(struct sdl2_console *scon) > /* The SDL renderer is only used by sdl2-2D, when OpenGL is disabled */ > scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0); > } > + > + qemu_egl_display = eglGetCurrentDisplay(); > + > sdl_update_caption(scon); > } > > @@ -820,6 +823,10 @@ static const DisplayChangeListenerOps dcl_gl_ops = { > .dpy_gl_scanout_disable = sdl2_gl_scanout_disable, > .dpy_gl_scanout_texture = sdl2_gl_scanout_texture, > .dpy_gl_update = sdl2_gl_scanout_flush, > + > + .dpy_gl_scanout_dmabuf = sdl2_gl_scanout_dmabuf, > + .dpy_gl_release_dmabuf = sdl2_gl_release_dmabuf, > + .dpy_has_dmabuf = sdl2_gl_has_dmabuf, > }; > > static bool > @@ -877,6 +884,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) > SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); > #endif > SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); > + SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1"); I think it needs to handle cases where X11 is not used or only GLX is available. > SDL_EnableScreenSaver(); > memset(&info, 0, sizeof(info)); > SDL_VERSION(&info.version);
diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index dbe6e3d9739b..b14552f5cd71 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -96,5 +96,10 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl, void *d3d_tex2d); void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h); +void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf); +void sdl2_gl_release_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf); +bool sdl2_gl_has_dmabuf(DisplayChangeListener *dcl); #endif /* SDL2_H */ diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index b1fe96d6af22..24aa9108682e 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -26,6 +26,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "ui/console.h" #include "ui/input.h" #include "ui/sdl2.h" @@ -227,6 +228,44 @@ void sdl2_gl_scanout_texture(DisplayChangeListener *dcl, backing_id, false); } +void sdl2_gl_scanout_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); + + assert(scon->opengl); + SDL_GL_MakeCurrent(scon->real_window, scon->winctx); + + egl_dmabuf_import_texture(dmabuf); + if (!qemu_dmabuf_get_texture(dmabuf)) { + fprintf(stderr, "sdl2_gl_scanout_dmabuf failed fd=%d\n", + qemu_dmabuf_get_fd(dmabuf)); + } + + sdl2_gl_scanout_texture(dcl, qemu_dmabuf_get_texture(dmabuf), false, + qemu_dmabuf_get_width(dmabuf), + qemu_dmabuf_get_height(dmabuf), + 0, 0, + qemu_dmabuf_get_width(dmabuf), + qemu_dmabuf_get_height(dmabuf), + NULL); + + if (qemu_dmabuf_get_allow_fences(dmabuf)) { + scon->guest_fb.dmabuf = dmabuf; + } +} + +void sdl2_gl_release_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + egl_dmabuf_release_texture(dmabuf); +} + +bool sdl2_gl_has_dmabuf(DisplayChangeListener *dcl) +{ + return qemu_egl_has_dmabuf(); +} + void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { diff --git a/ui/sdl2.c b/ui/sdl2.c index bd4f5a9da14a..8c7b01c5e62f 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -120,6 +120,9 @@ void sdl2_window_create(struct sdl2_console *scon) /* The SDL renderer is only used by sdl2-2D, when OpenGL is disabled */ scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0); } + + qemu_egl_display = eglGetCurrentDisplay(); + sdl_update_caption(scon); } @@ -820,6 +823,10 @@ static const DisplayChangeListenerOps dcl_gl_ops = { .dpy_gl_scanout_disable = sdl2_gl_scanout_disable, .dpy_gl_scanout_texture = sdl2_gl_scanout_texture, .dpy_gl_update = sdl2_gl_scanout_flush, + + .dpy_gl_scanout_dmabuf = sdl2_gl_scanout_dmabuf, + .dpy_gl_release_dmabuf = sdl2_gl_release_dmabuf, + .dpy_has_dmabuf = sdl2_gl_has_dmabuf, }; static bool @@ -877,6 +884,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); #endif SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); + SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1"); SDL_EnableScreenSaver(); memset(&info, 0, sizeof(info)); SDL_VERSION(&info.version);