-void si_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 si_context *sctx = (struct si_context *)ctx;
- struct r600_texture *rsrc = (struct r600_texture*)src;
- struct pipe_surface *dst_view, dst_templ;
- struct pipe_sampler_view src_templ, *src_view;
- unsigned dst_width, dst_height, src_width0, src_height0;
- unsigned dst_width0, dst_height0, src_force_level = 0;
- struct pipe_box sbox, dstbox;
-
- /* Handle buffers first. */
- if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
- si_copy_buffer(sctx, dst, src, dstx, src_box->x, src_box->width, 0);
- return;
- }
-
- assert(u_max_sample(dst) == u_max_sample(src));
-
- /* The driver doesn't decompress resources automatically while
- * u_blitter is rendering. */
- si_decompress_subresource(ctx, src, PIPE_MASK_RGBAZS, src_level,
- src_box->z, src_box->z + src_box->depth - 1);
-
- dst_width = u_minify(dst->width0, dst_level);
- dst_height = u_minify(dst->height0, dst_level);
- dst_width0 = dst->width0;
- dst_height0 = dst->height0;
- src_width0 = src->width0;
- src_height0 = src->height0;
-
- util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
- util_blitter_default_src_texture(sctx->blitter, &src_templ, src, src_level);
-
- if (util_format_is_compressed(src->format) ||
- util_format_is_compressed(dst->format)) {
- unsigned blocksize = rsrc->surface.bpe;
-
- if (blocksize == 8)
- src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */
- else
- src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */
- dst_templ.format = src_templ.format;
-
- dst_width = util_format_get_nblocksx(dst->format, dst_width);
- dst_height = util_format_get_nblocksy(dst->format, dst_height);
- dst_width0 = util_format_get_nblocksx(dst->format, dst_width0);
- dst_height0 = util_format_get_nblocksy(dst->format, dst_height0);
- src_width0 = util_format_get_nblocksx(src->format, src_width0);
- src_height0 = util_format_get_nblocksy(src->format, src_height0);
-
- dstx = util_format_get_nblocksx(dst->format, dstx);
- dsty = util_format_get_nblocksy(dst->format, dsty);
-
- sbox.x = util_format_get_nblocksx(src->format, src_box->x);
- sbox.y = util_format_get_nblocksy(src->format, src_box->y);
- sbox.z = src_box->z;
- sbox.width = util_format_get_nblocksx(src->format, src_box->width);
- sbox.height = util_format_get_nblocksy(src->format, src_box->height);
- sbox.depth = src_box->depth;
- src_box = &sbox;
-
- src_force_level = src_level;
- } else if (!util_blitter_is_copy_supported(sctx->blitter, dst, src)) {
- if (util_format_is_subsampled_422(src->format)) {
- src_templ.format = PIPE_FORMAT_R8G8B8A8_UINT;
- dst_templ.format = PIPE_FORMAT_R8G8B8A8_UINT;
-
- dst_width = util_format_get_nblocksx(dst->format, dst_width);
- dst_width0 = util_format_get_nblocksx(dst->format, dst_width0);
- src_width0 = util_format_get_nblocksx(src->format, src_width0);
-
- dstx = util_format_get_nblocksx(dst->format, dstx);
-
- sbox = *src_box;
- sbox.x = util_format_get_nblocksx(src->format, src_box->x);
- sbox.width = util_format_get_nblocksx(src->format, src_box->width);
- src_box = &sbox;
- } else {
- unsigned blocksize = rsrc->surface.bpe;
-
- switch (blocksize) {
- case 1:
- dst_templ.format = PIPE_FORMAT_R8_UNORM;
- src_templ.format = PIPE_FORMAT_R8_UNORM;
- break;
- case 2:
- dst_templ.format = PIPE_FORMAT_R8G8_UNORM;
- src_templ.format = PIPE_FORMAT_R8G8_UNORM;
- break;
- case 4:
- dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
- src_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
- break;
- case 8:
- dst_templ.format = PIPE_FORMAT_R16G16B16A16_UINT;
- src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT;
- break;
- case 16:
- dst_templ.format = PIPE_FORMAT_R32G32B32A32_UINT;
- src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT;
- break;
- default:
- fprintf(stderr, "Unhandled format %s with blocksize %u\n",
- util_format_short_name(src->format), blocksize);
- assert(0);
- }
- }
- }
-
- /* SNORM8 blitting has precision issues on some chips. Use the SINT
- * equivalent instead, which doesn't force DCC decompression.
- * Note that some chips avoid this issue by using SDMA.
- */
- if (util_format_is_snorm8(dst_templ.format)) {
- switch (dst_templ.format) {
- case PIPE_FORMAT_R8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_R8_SINT;
- break;
- case PIPE_FORMAT_R8G8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_R8G8_SINT;
- break;
- case PIPE_FORMAT_R8G8B8X8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_R8G8B8X8_SINT;
- break;
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- /* There are no SINT variants for ABGR and XBGR, so we have to use RGBA. */
- case PIPE_FORMAT_A8B8G8R8_SNORM:
- case PIPE_FORMAT_X8B8G8R8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_R8G8B8A8_SINT;
- break;
- case PIPE_FORMAT_A8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_A8_SINT;
- break;
- case PIPE_FORMAT_L8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_L8_SINT;
- break;
- case PIPE_FORMAT_L8A8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_L8A8_SINT;
- break;
- case PIPE_FORMAT_I8_SNORM:
- dst_templ.format = src_templ.format = PIPE_FORMAT_I8_SINT;
- break;
- default:; /* fall through */
- }
- }
-
- vi_disable_dcc_if_incompatible_format(&sctx->b, dst, dst_level,
- dst_templ.format);
- vi_disable_dcc_if_incompatible_format(&sctx->b, src, src_level,
- src_templ.format);
-
- /* Initialize the surface. */
- dst_view = si_create_surface_custom(ctx, dst, &dst_templ,
- dst_width0, dst_height0,
- dst_width, dst_height);
-
- /* Initialize the sampler view. */
- src_view = si_create_sampler_view_custom(ctx, src, &src_templ,
- src_width0, src_height0,
- src_force_level);
-
- u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height),
- abs(src_box->depth), &dstbox);
-
- /* Copy. */
- si_blitter_begin(ctx, SI_COPY);
- util_blitter_blit_generic(sctx->blitter, dst_view, &dstbox,
- src_view, src_box, src_width0, src_height0,
- PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
- false);
- si_blitter_end(ctx);
-
- pipe_surface_reference(&dst_view, NULL);
- pipe_sampler_view_reference(&src_view, NULL);