All-black X windows on glamor with etnaviv

Submitted by Jiaxun Yang on July 4, 2019, 3:28 a.m.

Details

Message ID 8352901f-cba8-3695-3c98-c562fb71a864@flygoat.com
State New
Headers show
Series "All-black X windows on glamor with etnaviv" ( rev: 1 ) in X.org

Not browsing as part of any series.

Commit Message

Jiaxun Yang July 4, 2019, 3:28 a.m.
Hi folks,

We had some reports that glamor is not working correctly with etnaviv 
mesa driver for long time. Previously Lukas Hartmann wad proposed a 
patch [1] replacing linear rendering buffer with a tiled buffer and it 
do works but giving scrambled output. We just dig the issue deeper and 
managed to let it give out a normal output.

Since Vivante hardware doesn't actually support tiled surface/texture, 
once the driver accpet a imported buffer or called to create a resource, 
it will make a shadow tiled buffer, and convert the content in tiled 
buffer to the content it linear buffer when  etna_flush_resource in 
mesa/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c is called. 
However, it was never been called with glamor. By contrast other 
applications like kmscube or weston using EGL GLES have correct behavior.

Our solution is just flush the buffer everytime , it's not a elegant 
way, but it works. Since GC1000 is only giving OpenGL 1.4 rather than 
2.1 as minimal requirement of glamor. We also have to force glamor work 
with GLES.

Any idea if we can solve this issue correctly?

See our patches below:

     /* We need to have the patched data ready for the GPU. */


Thanks

[1]https://patchwork.freedesktop.org/patch/207832/

--

Jiaxun Yang

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/etnaviv/etnaviv_blt.c 
b/src/gallium/drivers/etnaviv/etnaviv_blt.c
index 42d1a44..342758c 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_blt.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_blt.c
@@ -247,6 +247,7 @@  etna_blit_clear_color_blt(struct pipe_context *pctx, 
struct pipe_surface *dst,
     surf->level->clear_value = new_clear_value;
     resource_written(ctx, surf->base.texture);
     etna_resource(surf->base.texture)->seqno++;
+   pctx->flush_resource(pctx, surf->base.texture);
  }

  static void
@@ -323,6 +324,7 @@  etna_blit_clear_zs_blt(struct pipe_context *pctx, 
struct pipe_surface *dst,
     surf->level->clear_value = new_clear_value;
     resource_written(ctx, surf->base.texture);
     etna_resource(surf->base.texture)->seqno++;
+   pctx->flush_resource(pctx, surf->base.texture);
  }

  static void
@@ -519,6 +521,7 @@  etna_try_blt_blit(struct pipe_context *pctx,

     dst->seqno++;
     dst_lev->ts_valid = false;
+   pctx->flush_resource(pctx, blit_info->dst.resource);

     return true;
  }
diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c 
b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
index 45c30cb..b36afbf 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
@@ -24,6 +24,7 @@ 
   *    Wladimir J. van der Laan <laanwj@gmail.com>
   */

+#include <execinfo.h>
  #include "etnaviv_clear_blit.h"

  #include "hw/common.xml.h"
diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c 
b/src/gallium/drivers/etnaviv/etnaviv_context.c
index b0a56c6..13233e7 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.c
@@ -297,10 +297,14 @@  etna_draw_vbo(struct pipe_context *pctx, const 
struct pipe_draw_info *info)
     if (DBG_ENABLED(ETNA_DBG_FLUSH_ALL))
        pctx->flush(pctx, NULL, 0);

-   if (ctx->framebuffer_s.cbufs[0])
+   if (ctx->framebuffer_s.cbufs[0]) {
etna_resource(ctx->framebuffer_s.cbufs[0]->texture)->seqno++;
-   if (ctx->framebuffer_s.zsbuf)
+      pctx->flush_resource(pctx, ctx->framebuffer_s.cbufs[0]->texture);
+   }
+   if (ctx->framebuffer_s.zsbuf) {
etna_resource(ctx->framebuffer_s.zsbuf->texture)->seqno++;
+      pctx->flush_resource(pctx, ctx->framebuffer_s.zsbuf->texture);
+   }
     if (info->index_size && indexbuf != info->index.resource)
        pipe_resource_reference(&indexbuf, NULL);
  }
diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c 
b/src/gallium/drivers/etnaviv/etnaviv_rs.c
index 8c85f32..5fd81e0 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_rs.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c
@@ -325,6 +325,7 @@  etna_blit_clear_color_rs(struct pipe_context *pctx, 
struct pipe_surface *dst,
     surf->level->clear_value = new_clear_value;
     resource_written(ctx, surf->base.texture);
     etna_resource(surf->base.texture)->seqno++;
+   pctx->flush_resource(pctx, surf->base.texture);
  }

  static void
@@ -388,6 +389,7 @@  etna_blit_clear_zs_rs(struct pipe_context *pctx, 
struct pipe_surface *dst,
     surf->level->clear_value = new_clear_value;
     resource_written(ctx, surf->base.texture);
     etna_resource(surf->base.texture)->seqno++;
+   pctx->flush_resource(pctx, surf->base.texture);
  }

  static void
@@ -745,6 +747,7 @@  etna_try_rs_blit(struct pipe_context *pctx,
     dst->seqno++;
     dst->levels[blit_info->dst.level].ts_valid = false;
     ctx->dirty |= ETNA_DIRTY_DERIVE_TS;
+   pctx->flush_resource(pctx, blit_info->dst.resource);

     return true;

diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c 
b/src/gallium/drivers/etnaviv/etnaviv_transfer.c
index d875803..9ec3463 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c
@@ -158,6 +158,7 @@  etna_transfer_unmap(struct pipe_context *pctx, 
struct pipe_transfer *ptrans)
        if (rsc->base.bind & PIPE_BIND_SAMPLER_VIEW) {
           ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;
        }
+      pctx->flush_resource(pctx, ptrans->resource);
     }


Comments

On 2019-07-04 5:28 a.m., Jiaxun Yang wrote:
> Hi folks,
> 
> We had some reports that glamor is not working correctly with etnaviv
> mesa driver for long time. Previously Lukas Hartmann wad proposed a
> patch [1] replacing linear rendering buffer with a tiled buffer and it
> do works but giving scrambled output. We just dig the issue deeper and
> managed to let it give out a normal output.
> 
> Since Vivante hardware doesn't actually support tiled surface/texture,
> once the driver accpet a imported buffer or called to create a resource,
> it will make a shadow tiled buffer, and convert the content in tiled
> buffer to the content it linear buffer when  etna_flush_resource in
> mesa/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c is called.
> However, it was never been called with glamor. By contrast other
> applications like kmscube or weston using EGL GLES have correct behavior.
> 
> Our solution is just flush the buffer everytime , it's not a elegant
> way, but it works. Since GC1000 is only giving OpenGL 1.4 rather than
> 2.1 as minimal requirement of glamor. We also have to force glamor work
> with GLES.
> 
> Any idea if we can solve this issue correctly?

I suspect etna_resource_get_handle needs to check for
PIPE_HANDLE_USAGE_EXPLICIT_FLUSH. If it's not set, the caller will not
call the flush_resource hook for this resource. This needs to be
recorded in struct etna_resource. Then in etna_flush, if this was
recorded for the resource backing any of the cbufs in the current
pipe_framebuffer_state, etna_flush_resource needs to be called for that
resource.

It might be possible to optimize this somewhat, e.g. maybe etna_flush
only needs to do this when it's called with certain PIPE_FLUSH_* flags
(not) set corresponding to glFlush, but not for other internal flushes.