freedreno/a6xx: Drop render condition check in blitter
authorKristian H. Kristensen <hoegsberg@chromium.org>
Thu, 7 Feb 2019 19:40:29 +0000 (11:40 -0800)
committerKristian H. Kristensen <hoegsberg@chromium.org>
Mon, 11 Feb 2019 20:26:21 +0000 (12:26 -0800)
We already check earlier in the call chain in fd_blit().
glBlitFramebuffer always sets render_condition_enable and thus we
would never try the blitter path for that.

Now that we get all of dEQP-GLES3.functional.fbo.blit.conversion.*
down this path, it turs out that the

  fail_if(info->mask != util_format_get_mask(info->src.format));
  fail_if(info->mask != util_format_get_mask(info->dst.format));

conditions weren't accurate.  util_format_get_mask() returns
PIPE_MASK_RGBA for any format with any color channels, while
info->mask is the exact set of channels to blit.  So we reject things
we could blit - for example, PIPE_FORMAT_R16G16_FLOAT where info->mask
is RG while util_format_get_mask() returns RGBA - and accept things we
can't.  It turns out that the blitter is happy to blit different
number of channels, but fails to blit formats with different numerical
formats and srgb formats.

Signed-off-by: Kristian H. Kristensen <hoegsberg@chromium.org>
Reviewed-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a6xx/fd6_blitter.c

index c871963618212271e8751f964626c8796c05f0a4..1699b292d89bf231890e9a9c7e29a9c351028f97 100644 (file)
@@ -119,14 +119,25 @@ can_do_blit(const struct pipe_blit_info *info)
 
        fail_if(info->window_rectangle_include);
 
-       fail_if(info->render_condition_enable);
+       fail_if(util_format_is_srgb(info->src.format));
+       fail_if(util_format_is_srgb(info->dst.format));
+
+       const struct util_format_description *src_desc =
+               util_format_description(info->src.format);
+       const struct util_format_description *dst_desc =
+               util_format_description(info->dst.format);
+       const int common_channels = MIN2(src_desc->nr_channels, dst_desc->nr_channels);
+
+       if (info->mask & PIPE_MASK_RGBA) {
+               for (int i = 0; i < common_channels; i++) {
+                       fail_if(memcmp(&src_desc->channel[i],
+                                                  &dst_desc->channel[i],
+                                                  sizeof(src_desc->channel[0])));
+               }
+       }
 
        fail_if(info->alpha_blend);
 
-       fail_if(info->mask != util_format_get_mask(info->src.format));
-
-       fail_if(info->mask != util_format_get_mask(info->dst.format));
-
        return true;
 }