+/* 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 bool r600_decompress_subresource(struct pipe_context *ctx,
+ struct pipe_resource *tex,
+ unsigned level,
+ unsigned first_layer, unsigned last_layer)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct r600_texture *rtex = (struct r600_texture*)tex;
+
+ if (rtex->is_depth && !rtex->is_flushing_texture) {
+ if (rctx->b.chip_class >= EVERGREEN ||
+ r600_can_read_depth(rtex)) {
+ r600_blit_decompress_depth_in_place(rctx, rtex,
+ level, level,
+ first_layer, last_layer);
+ } else {
+ if (!r600_init_flushed_depth_texture(ctx, tex, NULL))
+ return false; /* error */
+
+ r600_blit_decompress_depth(ctx, rtex, NULL,
+ level, level,
+ first_layer, last_layer,
+ 0, u_max_sample(tex));
+ }
+ } else if (rtex->fmask_size && rtex->cmask_size) {
+ r600_blit_decompress_color(ctx, rtex, level, level,
+ first_layer, last_layer);
+ }
+ return true;
+}
+
+static boolean is_simple_msaa_resolve(const struct pipe_blit_info *info)
+{
+ unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
+ unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
+ struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
+ unsigned dst_tile_mode = dst->surface.level[info->dst.level].mode;
+
+ return info->dst.resource->format == info->src.resource->format &&
+ info->dst.resource->format == info->dst.format &&
+ info->src.resource->format == info->src.format &&
+ !info->scissor_enable &&
+ info->mask == PIPE_MASK_RGBA &&
+ dst_width == info->src.resource->width0 &&
+ dst_height == info->src.resource->height0 &&
+ info->dst.box.x == 0 &&
+ info->dst.box.y == 0 &&
+ info->dst.box.width == dst_width &&
+ info->dst.box.height == dst_height &&
+ info->src.box.x == 0 &&
+ info->src.box.y == 0 &&
+ info->src.box.width == dst_width &&
+ info->src.box.height == dst_height &&
+ /* Dst must be tiled. If it's not, we have to use a temporary
+ * resource which is tiled. */
+ dst_tile_mode >= RADEON_SURF_MODE_1D;
+}
+
+static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst,
+ unsigned offset, unsigned size, unsigned char value);
+
+static void evergreen_set_clear_color(struct pipe_surface *cbuf,
+ const union pipe_color_union *color)
+{
+ unsigned *clear_value = ((struct r600_texture *)cbuf->texture)->color_clear_value;
+ union util_color uc;
+
+ memset(&uc, 0, sizeof(uc));
+
+ if (util_format_is_pure_uint(cbuf->format)) {
+ util_format_write_4ui(cbuf->format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
+ } else if (util_format_is_pure_sint(cbuf->format)) {
+ util_format_write_4i(cbuf->format, color->i, 0, &uc, 0, 0, 0, 1, 1);
+ } else {
+ util_pack_color(color->f, cbuf->format, &uc);
+ }
+
+ memcpy(clear_value, &uc, 2 * sizeof(uint32_t));
+}
+
+static bool can_fast_clear_color(struct pipe_context *ctx)
+{
+ struct r600_context *rctx = (struct r600_context *)ctx;
+ struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
+ int i;
+
+ if (rctx->b.chip_class < EVERGREEN) {
+ return false;
+ }
+
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ struct r600_texture *tex = (struct r600_texture *)fb->cbufs[i]->texture;
+
+ if (tex->cmask_size == 0) {
+ return false;
+ }
+
+ /* 128-bit formats are unuspported */
+ if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) {
+ return false;
+ }
+
+ /* the clear is allowed if all layers are bound */
+ if (fb->cbufs[i]->u.tex.first_layer != 0 ||
+ fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+