[virglrenderer-devel] [PATCH] vrend: Avoid GL blit fallback if formats are sufficiently compatible

Gert Wollny gert.wollny at collabora.com
Thu Jul 12 14:40:43 UTC 2018


The blit GL code path is selected when one of the textures uses swizzeling,
but formats that are equal, or more general, formats that have equal
swizzle maps should also be able to use the blit code path instead of the
GL fallback.

Signed-off-by: Gert Wollny <gert.wollny at collabora.com>
---
It fixes quite a number of piglits related to 3-component textures, but again
some are unstable:

  fbo-generatemipmap-formats gl_depth_component npot   
  fbo-blit rect 

 src/vrend_formats.c  | 35 +++++++++++++++++++++++++++++++++++
 src/vrend_renderer.c |  5 ++---
 src/vrend_renderer.h |  1 +
 3 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/src/vrend_formats.c b/src/vrend_formats.c
index 8f92903..95e504c 100644
--- a/src/vrend_formats.c
+++ b/src/vrend_formats.c
@@ -503,4 +503,39 @@ boolean format_is_copy_compatible(enum pipe_format src, enum pipe_format dst)
 
    /* compressed formats will be supported later */
    return false;
+}
+
+bool vrend_formats_can_blit(struct vrend_format_table *table,
+                            enum virgl_formats src, enum virgl_formats dst)
+{
+
+   /* Same formats should always be able to blit, just make sure with the blit
+    * that the color componets swizzle state is at the default so that the
+    * components are not moved (not checked here). */
+   if (src != dst)  {
+      const struct vrend_format_table * src_fmt = &table[src];
+      const struct vrend_format_table * dst_fmt = &table[dst];
+      int src_swizzles = 0;
+      int dst_swizzles = 0;
+
+      /* One swizzles, the other not, don't blit
+       * TODO: resolve this too */
+      if ((src_fmt->flags & VREND_BIND_NEED_SWIZZLE) !=
+          (dst_fmt->flags & VREND_BIND_NEED_SWIZZLE))
+         return false;
+
+      /* If src and dst have the same swizzle state and one doesn't swizzle
+       * then there is no swizzeling happaning at all. */
+      if (!(dst_fmt->flags & VREND_BIND_NEED_SWIZZLE))
+         return true;
+
+      /* Different formats, and swizzle is not the same, don't blit
+       * TODO: resolve swizzles for src in a way that we get what dst wants */
+      for (int i = 0; i < 4; ++i) {
+         if (src_fmt->swizzle[src_swizzles] != dst_fmt->swizzle[dst_swizzles]) {
+            return false;
+         }
+      }
+   }
+   return true;
 }
\ No newline at end of file
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index f3b3c2e..d0e9495 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -6518,9 +6518,8 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
    if (info->src.box.depth != info->dst.box.depth)
       use_gl = true;
 
-   if (vrend_format_needs_swizzle(info->dst.format) ||
-       vrend_format_needs_swizzle(info->src.format))
-      use_gl = true;
+   if (!use_gl)
+      use_gl = !vrend_formats_can_blit(tex_conv_table, src_res->base.format, dst_res->base.format);
 
    if (use_gl) {
       vrend_renderer_blit_gl(ctx, src_res, dst_res, info);
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index 8158ea6..ca36af3 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -381,6 +381,7 @@ void vrend_fb_bind_texture(struct vrend_resource *res,
 bool vrend_is_ds_format(enum virgl_formats format);
 bool vrend_format_is_emulated_alpha(enum virgl_formats format);
 boolean format_is_copy_compatible(enum pipe_format src, enum pipe_format dst);
+bool vrend_formats_can_blit(struct vrend_format_table *table, enum virgl_formats src, enum virgl_formats dst);
 
 /* blitter interface */
 void vrend_renderer_blit_gl(struct vrend_context *ctx,
-- 
2.17.1



More information about the virglrenderer-devel mailing list