vc4: Don't try to blit from MSAA surfaces with mismatched width to dst.
authorEric Anholt <eric@anholt.net>
Wed, 20 Apr 2016 21:11:04 +0000 (14:11 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 22 Apr 2016 18:27:11 +0000 (11:27 -0700)
I had made the previous blit fix non-MSAA only because I was thinking
about how the hardware infers stride from the RENDERING_CONFIG packet.
However, I'm also inferring the stride for both MSAA src and dst in
vc4_render_cl.c from the width argument in the ioctl.

Fixes 15 EXT_framebuffer_multisample piglit tests.

src/gallium/drivers/vc4/vc4_blit.c

index 128a3e50ee26e4da101a402254fb49de43044232..029170a5dc59303f993886c9c5cfb6bc3ed2c8de 100644 (file)
@@ -93,20 +93,23 @@ vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
          * destination surface) to determine the stride.  This may be wrong
          * when reading from texture miplevels > 0, which are stored in
          * POT-sized areas.  For MSAA, the tile addresses are computed
-         * explicitly by the RCL.
+         * explicitly by the RCL, but still use the destination width to
+         * determine the stride (which could be fixed by explicitly supplying
+         * it in the ABI).
          */
-        if (info->src.resource->nr_samples <= 1) {
-                struct vc4_resource *rsc = vc4_resource(info->src.resource);
+        struct vc4_resource *rsc = vc4_resource(info->src.resource);
 
-                uint32_t stride = dst_surface_width * rsc->cpp;
-                if (rsc->slices[info->src.level].tiling == VC4_TILING_FORMAT_T)
-                        stride = align(stride, 128);
-                else
-                        stride = align(stride, 16);
+        uint32_t stride;
 
-                if (stride != rsc->slices[info->src.level].stride)
-                        return false;
-        }
+        if (info->src.resource->nr_samples > 1)
+                stride = align(dst_surface_width, 32) * 4 * rsc->cpp;
+        else if (rsc->slices[info->src.level].tiling == VC4_TILING_FORMAT_T)
+                stride = align(dst_surface_width * rsc->cpp, 128);
+        else
+                stride = align(dst_surface_width * rsc->cpp, 16);
+
+        if (stride != rsc->slices[info->src.level].stride)
+                return false;
 
         if (info->dst.resource->format != info->src.resource->format)
                 return false;