radeonsi: make sure copying of all texture formats is accelerated
authorMarek Olšák <maraeo@gmail.com>
Fri, 11 Jan 2013 11:14:28 +0000 (12:14 +0100)
committerMichel Dänzer <michel@daenzer.net>
Thu, 24 Jan 2013 07:46:31 +0000 (08:46 +0100)
[ Cherry-picked from r600g commit 7c371f46958910dd2ca9487c89af1b72bbfdada9 ]

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/r600_blit.c
src/gallium/drivers/radeonsi/r600_texture.c

index b7aedb11524b364195cfe552b20b288265a82107..35c8f9594460f6b549e01dd1d0b45ef0c9b7ff3a 100644 (file)
@@ -338,9 +338,27 @@ static void r600_compressed_to_blittable(struct pipe_resource *tex,
        rtex->surface.level[level].npix_y = util_format_get_nblocksy(orig->format, orig->npix_y);
 }
 
-static void r600_reset_blittable_to_compressed(struct pipe_resource *tex,
-                                              unsigned level,
-                                              struct texture_orig_info *orig)
+static void r600_change_format(struct pipe_resource *tex,
+                              unsigned level,
+                              struct texture_orig_info *orig,
+                              enum pipe_format format)
+{
+       struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
+
+       orig->format = tex->format;
+       orig->width0 = tex->width0;
+       orig->height0 = tex->height0;
+       orig->npix0_x = rtex->surface.level[0].npix_x;
+       orig->npix0_y = rtex->surface.level[0].npix_y;
+       orig->npix_x = rtex->surface.level[level].npix_x;
+       orig->npix_y = rtex->surface.level[level].npix_y;
+
+       tex->format = format;
+}
+
+static void r600_reset_blittable_to_orig(struct pipe_resource *tex,
+                                        unsigned level,
+                                        struct texture_orig_info *orig)
 {
        struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
 
@@ -365,7 +383,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
        struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
        struct texture_orig_info orig_info[2];
        struct pipe_box sbox;
-       const struct pipe_box *psbox;
+       const struct pipe_box *psbox = src_box;
        boolean restore_orig[2];
 
        memset(orig_info, 0, sizeof(orig_info));
@@ -386,7 +404,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
 
        restore_orig[0] = restore_orig[1] = FALSE;
 
-       if (util_format_is_compressed(src->format)) {
+       if (util_format_is_compressed(src->format) &&
+           util_format_is_compressed(dst->format)) {
                r600_compressed_to_blittable(src, src_level, &orig_info[0]);
                restore_orig[0] = TRUE;
                sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x);
@@ -396,15 +415,36 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
                sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height);
                sbox.depth = src_box->depth;
                psbox=&sbox;
-       } else
-               psbox=src_box;
 
-       if (util_format_is_compressed(dst->format)) {
                r600_compressed_to_blittable(dst, dst_level, &orig_info[1]);
                restore_orig[1] = TRUE;
                /* translate the dst box as well */
                dstx = util_format_get_nblocksx(orig_info[1].format, dstx);
                dsty = util_format_get_nblocksy(orig_info[1].format, dsty);
+       } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src,
+                                                  PIPE_MASK_RGBAZS)) {
+               unsigned blocksize = util_format_get_blocksize(src->format);
+
+               switch (blocksize) {
+               case 1:
+                       r600_change_format(src, src_level, &orig_info[0],
+                                          PIPE_FORMAT_R8_UNORM);
+                       r600_change_format(dst, dst_level, &orig_info[1],
+                                          PIPE_FORMAT_R8_UNORM);
+                       break;
+               case 4:
+                       r600_change_format(src, src_level, &orig_info[0],
+                                          PIPE_FORMAT_R8G8B8A8_UNORM);
+                       r600_change_format(dst, dst_level, &orig_info[1],
+                                          PIPE_FORMAT_R8G8B8A8_UNORM);
+                       break;
+               default:
+                       fprintf(stderr, "Unhandled format %s with blocksize %u\n",
+                               util_format_short_name(src->format), blocksize);
+                       assert(0);
+               }
+               restore_orig[0] = TRUE;
+               restore_orig[1] = TRUE;
        }
 
        r600_blitter_begin(ctx, R600_COPY);
@@ -413,10 +453,10 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
        r600_blitter_end(ctx);
 
        if (restore_orig[0])
-               r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]);
+               r600_reset_blittable_to_orig(src, src_level, &orig_info[0]);
 
        if (restore_orig[1])
-               r600_reset_blittable_to_compressed(dst, dst_level, &orig_info[1]);
+               r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]);
 }
 
 static void si_blit(struct pipe_context *ctx,
index 2bbf2ebb2122009eff1b2419557d3130f6bcb99c..3f75adbdcef1e444409a969599eaee2d29133588 100644 (file)
@@ -192,47 +192,6 @@ static int r600_setup_surface(struct pipe_screen *screen,
        return 0;
 }
 
-/* Figure out whether u_blitter will fallback to a transfer operation.
- * If so, don't use a staging resource.
- */
-static boolean permit_hardware_blit(struct pipe_screen *screen,
-                                       const struct pipe_resource *res)
-{
-       unsigned bind;
-
-       if (util_format_is_depth_or_stencil(res->format))
-               bind = PIPE_BIND_DEPTH_STENCIL;
-       else
-               bind = PIPE_BIND_RENDER_TARGET;
-
-       /* hackaround for S3TC */
-       if (util_format_is_compressed(res->format))
-               return TRUE;
-
-       if (!screen->is_format_supported(screen,
-                               res->format,
-                               res->target,
-                               res->nr_samples,
-                                bind))
-               return FALSE;
-
-       if (!screen->is_format_supported(screen,
-                               res->format,
-                               res->target,
-                               res->nr_samples,
-                                PIPE_BIND_SAMPLER_VIEW))
-               return FALSE;
-
-       switch (res->usage) {
-       case PIPE_USAGE_STREAM:
-       case PIPE_USAGE_STAGING:
-               return FALSE;
-
-       default:
-               return TRUE;
-       }
-}
-
 static boolean r600_texture_get_handle(struct pipe_screen* screen,
                                        struct pipe_resource *ptex,
                                        struct winsys_handle *whandle)
@@ -310,8 +269,7 @@ static void *si_texture_transfer_map(struct pipe_context *ctx,
                                        PIPE_TRANSFER_UNSYNCHRONIZED)))
                use_staging_texture = TRUE;
 
-       if (!permit_hardware_blit(ctx->screen, texture) ||
-               (texture->flags & R600_RESOURCE_FLAG_TRANSFER))
+       if (texture->flags & R600_RESOURCE_FLAG_TRANSFER)
                use_staging_texture = FALSE;
 
        if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
@@ -483,9 +441,8 @@ r600_texture_create_object(struct pipe_screen *screen,
        rtex->pitch_override = pitch_in_bytes_override;
        rtex->real_format = base->format;
 
-       /* only mark depth textures the HW can hit as depth textures */
-       if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base))
-               rtex->is_depth = 1;
+       /* don't include stencil-only formats which we don't support for rendering */
+       rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
 
        rtex->surface = *surface;
        r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override);
@@ -568,9 +525,7 @@ struct pipe_resource *si_texture_create(struct pipe_screen *screen,
 
        if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
            !(templ->bind & PIPE_BIND_SCANOUT)) {
-               if (permit_hardware_blit(screen, templ)) {
-                       array_mode = V_009910_ARRAY_1D_TILED_THIN1;
-               }
+               array_mode = V_009910_ARRAY_1D_TILED_THIN1;
        }
 
        r = r600_init_surface(rscreen, &surface, templ, array_mode,