static void si_blit(struct pipe_context *ctx, const struct pipe_blit_info *info) { struct r600_context *rctx = (struct r600_context*)ctx; struct r600_resource_texture *rsrc = (struct r600_resource_texture*)info->src.resource; assert(util_blitter_is_blit_supported(rctx->blitter, info)); if (info->src.resource->nr_samples > 1 && info->dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info->src.resource->format) && !util_format_is_pure_integer(info->src.resource->format)) { debug_printf("radeonsi: color resolve is unimplemented\n"); return; } if (rsrc->is_depth && !rsrc->is_flushing_texture) { si_blit_decompress_depth_in_place(rctx, rsrc, info->src.level, info->src.level, info->src.box.z, info->src.box.z + info->src.box.depth - 1); } r600_blitter_begin(ctx, R600_BLIT); util_blitter_blit(rctx->blitter, info); r600_blitter_end(ctx); }
void si_flush_depth_textures(struct si_context *sctx, struct si_textures_info *textures) { unsigned i; unsigned mask = textures->depth_texture_mask; while (mask) { struct pipe_sampler_view *view; struct si_sampler_view *sview; struct r600_texture *tex; i = u_bit_scan(&mask); view = textures->views.views[i]; assert(view); sview = (struct si_sampler_view*)view; tex = (struct r600_texture *)view->texture; assert(tex->is_depth && !tex->is_flushing_texture); si_blit_decompress_depth_in_place(sctx, tex, sview->is_stencil_sampler, view->u.tex.first_level, view->u.tex.last_level, 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level)); } }
/* Helper for decompressing a portion of a color or depth resource before * blitting if any decompression is needed. * The driver doesn't decompress resources automatically while u_blitter is * rendering. */ static void si_decompress_subresource(struct pipe_context *ctx, struct pipe_resource *tex, unsigned level, unsigned first_layer, unsigned last_layer) { struct si_context *sctx = (struct si_context *)ctx; struct r600_texture *rtex = (struct r600_texture*)tex; if (rtex->is_depth && !rtex->is_flushing_texture) { si_blit_decompress_depth_in_place(sctx, rtex, false, level, level, first_layer, last_layer); if (rtex->surface.flags & RADEON_SURF_SBUFFER) si_blit_decompress_depth_in_place(sctx, rtex, true, level, level, first_layer, last_layer); } else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_buffer) { si_blit_decompress_color(ctx, rtex, level, level, first_layer, last_layer); } }
/* Helper for decompressing a portion of a color or depth resource before * blitting if any decompression is needed. * The driver doesn't decompress resources automatically while u_blitter is * rendering. */ static void si_decompress_subresource(struct pipe_context *ctx, struct pipe_resource *tex, unsigned level, unsigned first_layer, unsigned last_layer) { struct si_context *sctx = (struct si_context *)ctx; struct r600_texture *rtex = (struct r600_texture*)tex; if (rtex->is_depth && !rtex->is_flushing_texture) { si_blit_decompress_depth_in_place(sctx, rtex, level, level, first_layer, last_layer); } else if (rtex->fmask.size || rtex->cmask.size) { si_blit_decompress_color(ctx, rtex, level, level, first_layer, last_layer); } }
void si_flush_depth_textures(struct r600_context *rctx, struct r600_textures_info *textures) { unsigned i; for (i = 0; i < textures->n_views; ++i) { struct pipe_sampler_view *view; struct r600_resource_texture *tex; view = &textures->views[i]->base; if (!view) continue; tex = (struct r600_resource_texture *)view->texture; if (!tex->is_depth || tex->is_flushing_texture) continue; si_blit_decompress_depth_in_place(rctx, tex, view->u.tex.first_level, view->u.tex.last_level, 0, u_max_layer(&tex->resource.b.b, view->u.tex.first_level)); } }
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]); }