예제 #1
0
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;
}
예제 #2
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);
	}
}
예제 #3
0
파일: r600_blit.c 프로젝트: dezelin/mesa
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);
}
예제 #4
0
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;
}
예제 #5
0
파일: r600_blit.c 프로젝트: dezelin/mesa
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));
    }
}
예제 #6
0
파일: r600_blit.c 프로젝트: dezelin/mesa
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]);
}