All-black X windows with etnaviv/xwayland/glamor

Submitted by Lukas Hartmann on March 2, 2018, 4:33 p.m.


Message ID
State New
Headers show
Series "All-black X windows with etnaviv/xwayland/glamor" ( rev: 1 ) in

Not browsing as part of any series.

Commit Message

Lukas Hartmann March 2, 2018, 4:33 p.m.

I made XWayland with Glamor work on etnaviv with a few hacks a while ago
and wanted to leave my findings here so that they could be of use in
future updates of XWayland and weston.

The first two changes are in XWayland: the GBM_BO_USE_SCANOUT had to be
removed to not force rendering into a linear buffer which etnaviv
apparently has trouble rendering (the cause of the black surface).
After this change, scrambled output will appear instead of black output,
because there is no support for layout modifiers yet.

Lukas F. Hartmann / mntmn

>> On 14. Feb 2018, at 10:13, Michel Dänzer <> wrote:
>>> On 2018-02-13 07:34 PM, Lukas F. Hartmann wrote:
>>> Michel Dänzer <> writes:
>>>>> On 2018-02-13 04:23 PM, Lukas F. Hartmann wrote:
>>>>> - Xwayland/glamor registers its gbm buffer with wl_drm_create_prime_buffer (passing a fd) which ends up in drm_create_prime_buffer on the server side. I might have made mistakes, but when mapping the gbm_bo on that side (using gbm_bo_import and then gbm_map_bo), it appears that the buffer is empty (maybe it cannot be transferred correctly?).
>>>> Unless there's a dma-buf API usage mistake in userspace, it sounds like
>>>> a kernel issue, since the two processes are seeing different contents in
>>>> what should be one and the same BO.
>>>> Can you test Xorg with DRI3? Do OpenGL apps work correctly with that?
>>> I just rebuilt Xorg and started it with a minimal modesetting conf:
>>> - with AccelMethod "none", I get a working/visible unaccelerated desktop,
>>>  glxinfo showing softpipe
>>> - with AccelMethod "glamor", I get an invisible desktop (possibly same problem as
>>>  in Xwayland). DRI3 is enabled which I confirmed by stepping with gdb
>>>  through glamor_egl_screen_init. glxinfo shows "Vivante GC3000 rev
>>>  5450" and "Max compat profile version: 2.1.", glxgears has a high
>>>  framerate. But I cannot see any of this output.
>> That seems to confirm a kernel issue. The (unlikely) alternative is that
>> you've discovered a long standing bug in the dma-buf related userspace
>> code, which doesn't affect other platforms.
>> -- 
>> Earthling Michel Dänzer               |     
>> Libre software enthusiast             |             Mesa and X developer

Patch hide | download patch | download mbox

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 8ffb40d..f0ed87a 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -193,7 +193,7 @@  xwl_glamor_create_pixmap(ScreenPtr screen,
          hint == CREATE_PIXMAP_USAGE_SHARED)) {
         bo = gbm_bo_create(xwl_screen->gbm, width, height,
-                           GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+                           GBM_BO_USE_RENDERING);
         if (bo)
             return xwl_glamor_create_pixmap_for_bo(screen, bo, depth);
@@ -538,7 +538,7 @@  xwl_dri3_pixmap_from_fd(ScreenPtr screen, int fd,
     data.stride = stride;
     data.format = gbm_format_for_depth(depth);
     bo = gbm_bo_import(xwl_screen->gbm, GBM_BO_IMPORT_FD, &data,
-                       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+                       GBM_BO_USE_RENDERING);
     if (bo == NULL)
         return NULL;

The second change is to force the XWayland root surface size to a magic
number as a quick & dirty way of marking it for special treatment by the
etnaviv gallium driver. If I understood correctly, a clean way of
communicating buffer layouts is coming with dri3 modifiers?

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 73bc47a..bf1af9c 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -991,6 +991,9 @@  xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
+    /* magic number as signal to drm/etnaviv */
+    xwl_screen->width=1288;
     ret = fbScreenInit(pScreen, NULL,
                        xwl_screen->width, xwl_screen->height,
                        96, 96, 0,

Finally, this hack makes etna_resource_from_handle recognize the buffer
and interpret its layout as ETNA_LAYOUT_SUPER_TILED. This unscrambles
the output and makes XWayland usable (there are still some glitches with
GLX applications, but that is another topic).

diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c
index d70152e0..979bdd91 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_resource.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c
@@ -512,10 +512,15 @@  etna_resource_from_handle(struct pipe_screen *pscreen,
    rsc->layout = modifier_to_layout(handle->modifier);
    rsc->halign = TEXTURE_HALIGN_FOUR;
    level->width = tmpl->width0;
    level->height = tmpl->height0;
+   /* magic number from xwayland */
+   if (level->stride == 5376) {
+      rsc->layout = ETNA_LAYOUT_SUPER_TILED;
+   }
    /* Determine padding of the imported resource. */
    unsigned paddingX = 0, paddingY = 0;
    etna_layout_multiple(rsc->layout, screen->specs.pixel_pipes,