int r600_texture_from_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level) { struct r600_screen *rscreen = r600_screen(ctx->screen); int r; if (!rtexture->depth) { /* This shouldn't happen maybe print a warning */ return 0; } if (rtexture->uncompressed && !rtexture->dirty) { /* Uncompressed bo already in good state */ return 0; } /* allocate uncompressed texture */ if (rtexture->uncompressed == NULL) { rtexture->uncompressed = radeon_bo(rscreen->rw, 0, rtexture->size, 4096, NULL); if (rtexture->uncompressed == NULL) { return -ENOMEM; } } /* render a rectangle covering whole buffer to uncompress depth */ r = r600_blit_uncompress_depth(ctx, rtexture, level); if (r) { return r; } rtexture->dirty = 0; return 0; }
void r600_flush_depth_textures(struct r600_pipe_context *rctx) { unsigned int i; /* FIXME: This handles fragment shader textures only. */ for (i = 0; i < rctx->ps_samplers.n_views; ++i) { struct r600_pipe_sampler_view *view; struct r600_resource_texture *tex; view = rctx->ps_samplers.views[i]; if (!view) continue; tex = (struct r600_resource_texture *)view->base.texture; if (!tex->depth) continue; if (tex->is_flushing_texture) continue; r600_blit_uncompress_depth(&rctx->context, tex); } /* also check CB here */ for (i = 0; i < rctx->framebuffer.nr_cbufs; i++) { struct r600_resource_texture *tex; tex = (struct r600_resource_texture *)rctx->framebuffer.cbufs[i]->texture; if (!tex->depth) continue; if (tex->is_flushing_texture) continue; r600_blit_uncompress_depth(&rctx->context, tex); } }
static void r600_copy_first_sample(struct pipe_context *ctx, const struct pipe_resolve_info *info) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_texture *rsrc = (struct r600_texture*)info->src.res; struct pipe_surface *dst_view, dst_templ; struct pipe_sampler_view src_templ, *src_view; struct pipe_box box; if (rsrc->is_depth && !rsrc->is_flushing_texture) { if (!r600_init_flushed_depth_texture(ctx, info->src.res, NULL)) return; /* error */ /* Decompress the first sample only. */ r600_blit_uncompress_depth(ctx, rsrc, NULL, 0, 0, info->src.layer, info->src.layer, 0, 0); } /* this is correct for upside-down blits too */ u_box_2d(info->src.x0, info->src.y0, info->src.x1 - info->src.x0, info->src.y1 - info->src.y0, &box); /* Initialize the surface. */ util_blitter_default_dst_texture(&dst_templ, info->dst.res, info->dst.level, info->dst.layer, &box); dst_view = ctx->create_surface(ctx, info->dst.res, &dst_templ); /* Initialize the sampler view. */ util_blitter_default_src_texture(&src_templ, info->src.res, 0); src_view = ctx->create_sampler_view(ctx, info->src.res, &src_templ); /* Copy the first sample into dst. */ r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_copy_texture_view(rctx->blitter, dst_view, ~0, info->dst.x0, info->dst.y0, src_view, 0, &box, info->src.res->width0, info->src.res->height0, info->mask); r600_blitter_end(ctx); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); }
int r600_texture_depth_flush(struct pipe_context *ctx, struct pipe_resource *texture, boolean just_create) { struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; struct pipe_resource resource; if (rtex->flushed_depth_texture) goto out; resource.target = texture->target; resource.format = texture->format; resource.width0 = texture->width0; resource.height0 = texture->height0; resource.depth0 = texture->depth0; resource.array_size = texture->array_size; resource.last_level = texture->last_level; resource.nr_samples = texture->nr_samples; resource.usage = PIPE_USAGE_DYNAMIC; resource.bind = texture->bind | PIPE_BIND_DEPTH_STENCIL; resource.flags = R600_RESOURCE_FLAG_TRANSFER | texture->flags; rtex->flushed_depth_texture = (struct r600_resource_texture *)ctx->screen->resource_create(ctx->screen, &resource); if (rtex->flushed_depth_texture == NULL) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); return -ENOMEM; } ((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE; out: if (just_create) return 0; /* XXX: only do this if the depth texture has actually changed: */ r600_blit_uncompress_depth(ctx, rtex); return 0; }
void r600_flush_depth_textures(struct r600_context *rctx, struct r600_samplerview_state *textures) { unsigned i; unsigned depth_texture_mask = textures->depth_texture_mask; while (depth_texture_mask) { struct pipe_sampler_view *view; struct r600_texture *tex; i = u_bit_scan(&depth_texture_mask); view = &textures->views[i]->base; assert(view); tex = (struct r600_texture *)view->texture; assert(tex->is_depth && !tex->is_flushing_texture); r600_blit_uncompress_depth(&rctx->context, tex, NULL, view->u.tex.first_level, view->u.tex.last_level, 0, u_max_layer(&tex->resource.b.b, view->u.tex.first_level), 0, u_max_sample(&tex->resource.b.b)); } }
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]); }