static void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct r600_context *rctx = (struct r600_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 = src_box; boolean restore_orig[2]; memset(orig_info, 0, sizeof(orig_info)); /* Fallback for buffers. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } /* This must be done before entering u_blitter to avoid recursion. */ if (rsrc->is_depth && !rsrc->is_flushing_texture) { si_blit_decompress_depth_in_place(rctx, rsrc, src_level, src_level, src_box->z, src_box->z + src_box->depth - 1); } restore_orig[0] = restore_orig[1] = FALSE; 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); sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; psbox=&sbox; 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); util_blitter_copy_texture(rctx->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, psbox, PIPE_MASK_RGBAZS, TRUE); r600_blitter_end(ctx); if (restore_orig[0]) r600_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); }
static void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_texture *rsrc = (struct r600_texture*)src; struct texture_orig_info orig_info[2]; struct pipe_box sbox; const struct pipe_box *psbox = src_box; boolean restore_orig[2]; unsigned last_sample, i; memset(orig_info, 0, sizeof(orig_info)); /* Handle buffers first. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { r600_copy_buffer(ctx, dst, dstx, src, src_box); return; } assert(u_max_sample(dst) == u_max_sample(src)); last_sample = u_max_sample(dst); /* This must be done before entering u_blitter to avoid recursion. */ if (rsrc->is_depth && !rsrc->is_flushing_texture) { if (!r600_init_flushed_depth_texture(ctx, src, NULL)) return; /* error */ r600_blit_uncompress_depth(ctx, rsrc, NULL, src_level, src_level, src_box->z, src_box->z + src_box->depth - 1, 0, u_max_sample(src)); } restore_orig[0] = restore_orig[1] = FALSE; 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); sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; psbox = &sbox; 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)) { if (util_format_is_subsampled_2x1_32bpp(src->format) && util_format_is_subsampled_2x1_32bpp(dst->format)) { r600_subsampled_2x1_32bpp_to_blittable(src, src_level, &orig_info[0]); r600_subsampled_2x1_32bpp_to_blittable(dst, dst_level, &orig_info[1]); sbox = *src_box; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); psbox = &sbox; dstx = util_format_get_nblocksx(orig_info[1].format, dstx); } else { 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; } for (i = 0; i <= last_sample; i++) { r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_copy_texture(rctx->blitter, dst, dst_level, 1 << i, dstx, dsty, dstz, src, src_level, i, psbox); r600_blitter_end(ctx); } if (restore_orig[0]) r600_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); }