Example #1
0
void r600_decompress_depth_textures(struct r600_context *rctx,
			       struct r600_samplerview_state *textures)
{
	unsigned i;
	unsigned depth_texture_mask = textures->compressed_depthtex_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);

		if (rctx->chip_class >= EVERGREEN ||
		    r600_can_read_depth(tex)) {
			r600_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));
		} else {
			r600_blit_decompress_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));
		}
	}
}
Example #2
0
void r600_decompress_color_textures(struct r600_context *rctx,
				    struct r600_samplerview_state *textures)
{
	unsigned i;
	unsigned mask = textures->compressed_colortex_mask;

	/* Cayman cannot decompress an MSAA colorbuffer,
	 * but it can read it compressed, so skip this. */
	assert(rctx->chip_class != CAYMAN);
	if (rctx->chip_class == CAYMAN) {
		return;
	}

	while (mask) {
		struct pipe_sampler_view *view;
		struct r600_texture *tex;

		i = u_bit_scan(&mask);

		view = &textures->views[i]->base;
		assert(view);

		tex = (struct r600_texture *)view->texture;
		assert(tex->cmask_size && tex->fmask_size);

		r600_blit_decompress_color(&rctx->context, tex,
					   view->u.tex.first_level, view->u.tex.last_level,
					   0, u_max_layer(&tex->resource.b.b, view->u.tex.first_level));
	}
}
Example #3
0
static void r600_blit_decompress_depth_in_place(struct r600_context *rctx,
                                                struct r600_texture *texture,
                                                unsigned first_level, unsigned last_level,
                                                unsigned first_layer, unsigned last_layer)
{
	struct pipe_surface *zsurf, surf_tmpl = {{0}};
	unsigned layer, max_layer, checked_last_layer, level;

	/* Enable decompression in DB_RENDER_CONTROL */
	rctx->db_misc_state.flush_depthstencil_in_place = true;
	rctx->db_misc_state.atom.dirty = true;

	surf_tmpl.format = texture->resource.b.b.format;

	for (level = first_level; level <= last_level; level++) {
		if (!(texture->dirty_level_mask & (1 << level)))
			continue;

		surf_tmpl.u.tex.level = level;

		/* The smaller the mipmap level, the less layers there are
		 * as far as 3D textures are concerned. */
		max_layer = u_max_layer(&texture->resource.b.b, level);
		checked_last_layer = last_layer < max_layer ? last_layer : max_layer;

		for (layer = first_layer; layer <= checked_last_layer; layer++) {
			surf_tmpl.u.tex.first_layer = layer;
			surf_tmpl.u.tex.last_layer = layer;

			zsurf = rctx->context.create_surface(&rctx->context, &texture->resource.b.b, &surf_tmpl);

			r600_blitter_begin(&rctx->context, R600_DECOMPRESS);
			util_blitter_custom_depth_stencil(rctx->blitter, zsurf, NULL, ~0,
							  rctx->custom_dsa_flush, 1.0f);
			r600_blitter_end(&rctx->context);

			pipe_surface_reference(&zsurf, NULL);
		}

		/* The texture will always be dirty if some layers or samples aren't flushed.
		 * I don't think this case occurs often though. */
		if (first_layer == 0 && last_layer == max_layer) {
			texture->dirty_level_mask &= ~(1 << level);
		}
	}

	/* Disable decompression in DB_RENDER_CONTROL */
	rctx->db_misc_state.flush_depthstencil_in_place = false;
	rctx->db_misc_state.atom.dirty = true;
}
Example #4
0
static void r600_blit_decompress_color(struct pipe_context *ctx,
		struct r600_texture *rtex,
		unsigned first_level, unsigned last_level,
		unsigned first_layer, unsigned last_layer)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	unsigned layer, level, checked_last_layer, max_layer;

	assert(rctx->chip_class != CAYMAN);

	if (!rtex->dirty_level_mask)
		return;

	for (level = first_level; level <= last_level; level++) {
		if (!(rtex->dirty_level_mask & (1 << level)))
			continue;

		/* The smaller the mipmap level, the less layers there are
		 * as far as 3D textures are concerned. */
		max_layer = u_max_layer(&rtex->resource.b.b, level);
		checked_last_layer = last_layer < max_layer ? last_layer : max_layer;

		for (layer = first_layer; layer <= checked_last_layer; layer++) {
			struct pipe_surface *cbsurf, surf_tmpl;

			surf_tmpl.format = rtex->resource.b.b.format;
			surf_tmpl.u.tex.level = level;
			surf_tmpl.u.tex.first_layer = layer;
			surf_tmpl.u.tex.last_layer = layer;
			surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
			cbsurf = ctx->create_surface(ctx, &rtex->resource.b.b, &surf_tmpl);

			r600_blitter_begin(ctx, R600_DECOMPRESS);
			util_blitter_custom_color(rctx->blitter, cbsurf,
						  rctx->custom_blend_decompress);
			r600_blitter_end(ctx);

			pipe_surface_reference(&cbsurf, NULL);
		}

		/* The texture will always be dirty if some layers or samples aren't flushed.
		 * I don't think this case occurs often though. */
		if (first_layer == 0 && last_layer == max_layer) {
			rtex->dirty_level_mask &= ~(1 << level);
		}
	}
}
Example #5
0
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));
	}
}
Example #6
0
void r600_decompress_color_textures(struct r600_context *rctx,
				    struct r600_samplerview_state *textures)
{
	unsigned i;
	unsigned mask = textures->compressed_colortex_mask;

	while (mask) {
		struct pipe_sampler_view *view;
		struct r600_texture *tex;

		i = u_bit_scan(&mask);

		view = &textures->views[i]->base;
		assert(view);

		tex = (struct r600_texture *)view->texture;
		assert(tex->cmask_size && tex->fmask_size);

		r600_blit_decompress_color(&rctx->context, tex,
					   view->u.tex.first_level, view->u.tex.last_level,
					   0, u_max_layer(&tex->resource.b.b, view->u.tex.first_level));
	}
}
Example #7
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));
    }
}
Example #8
0
void si_blit_uncompress_depth(struct pipe_context *ctx,
		struct r600_resource_texture *texture,
		struct r600_resource_texture *staging,
		unsigned first_level, unsigned last_level,
		unsigned first_layer, unsigned last_layer)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	unsigned layer, level, checked_last_layer, max_layer;
	float depth = 1.0f;
	const struct util_format_description *desc;
	void *custom_dsa;
	struct r600_resource_texture *flushed_depth_texture = staging ?
			staging : texture->flushed_depth_texture;

	if (!staging && !texture->dirty_db_mask)
		return;

	desc = util_format_description(flushed_depth_texture->resource.b.b.format);
	switch (util_format_has_depth(desc) | util_format_has_stencil(desc) << 1) {
	default:
		assert(!"No depth or stencil to uncompress");
	case 3:
		custom_dsa = rctx->custom_dsa_flush_depth_stencil;
		break;
	case 2:
		custom_dsa = rctx->custom_dsa_flush_stencil;
		break;
	case 1:
		custom_dsa = rctx->custom_dsa_flush_depth;
		break;
	}

	for (level = first_level; level <= last_level; level++) {
		if (!staging && !(texture->dirty_db_mask & (1 << level)))
			continue;

		/* The smaller the mipmap level, the less layers there are
		 * as far as 3D textures are concerned. */
		max_layer = u_max_layer(&texture->resource.b.b, level);
		checked_last_layer = last_layer < max_layer ? last_layer : max_layer;

		for (layer = first_layer; layer <= checked_last_layer; layer++) {
			struct pipe_surface *zsurf, *cbsurf, surf_tmpl;

			surf_tmpl.format = texture->real_format;
			surf_tmpl.u.tex.level = level;
			surf_tmpl.u.tex.first_layer = layer;
			surf_tmpl.u.tex.last_layer = layer;

			zsurf = ctx->create_surface(ctx, &texture->resource.b.b, &surf_tmpl);

			surf_tmpl.format = flushed_depth_texture->real_format;
			cbsurf = ctx->create_surface(ctx,
					(struct pipe_resource*)flushed_depth_texture, &surf_tmpl);

			r600_blitter_begin(ctx, R600_DECOMPRESS);
			util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, ~0, custom_dsa, depth);
			r600_blitter_end(ctx);

			pipe_surface_reference(&zsurf, NULL);
			pipe_surface_reference(&cbsurf, NULL);
		}

		/* The texture will always be dirty if some layers aren't flushed.
		 * I don't think this case can occur though. */
		if (!staging && first_layer == 0 && last_layer == max_layer) {
			texture->dirty_db_mask &= ~(1 << level);
		}
	}
}
Example #9
0
void r600_blit_uncompress_depth(struct pipe_context *ctx,
                                struct r600_texture *texture,
                                struct r600_texture *staging,
                                unsigned first_level, unsigned last_level,
                                unsigned first_layer, unsigned last_layer,
                                unsigned first_sample, unsigned last_sample)
{
    struct r600_context *rctx = (struct r600_context *)ctx;
    unsigned layer, level, sample, checked_last_layer, max_layer, max_sample;
    struct r600_texture *flushed_depth_texture = staging ?
                staging : texture->flushed_depth_texture;
    const struct util_format_description *desc =
        util_format_description(texture->resource.b.b.format);
    float depth;

    if (!staging && !texture->dirty_db_mask)
        return;

    if (rctx->family == CHIP_RV610 || rctx->family == CHIP_RV630 ||
            rctx->family == CHIP_RV620 || rctx->family == CHIP_RV635)
        depth = 0.0f;
    else
        depth = 1.0f;

    /* Enable decompression in DB_RENDER_CONTROL */
    rctx->db_misc_state.flush_depthstencil_through_cb = true;
    rctx->db_misc_state.copy_depth = util_format_has_depth(desc);
    rctx->db_misc_state.copy_stencil = util_format_has_stencil(desc);
    rctx->db_misc_state.copy_sample = first_sample;
    r600_atom_dirty(rctx, &rctx->db_misc_state.atom);

    max_sample = u_max_sample(&texture->resource.b.b);

    for (level = first_level; level <= last_level; level++) {
        if (!staging && !(texture->dirty_db_mask & (1 << level)))
            continue;

        /* The smaller the mipmap level, the less layers there are
         * as far as 3D textures are concerned. */
        max_layer = u_max_layer(&texture->resource.b.b, level);
        checked_last_layer = last_layer < max_layer ? last_layer : max_layer;

        for (layer = first_layer; layer <= checked_last_layer; layer++) {
            for (sample = first_sample; sample <= last_sample; sample++) {
                struct pipe_surface *zsurf, *cbsurf, surf_tmpl;

                if (sample != rctx->db_misc_state.copy_sample) {
                    rctx->db_misc_state.copy_sample = sample;
                    r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
                }

                surf_tmpl.format = texture->resource.b.b.format;
                surf_tmpl.u.tex.level = level;
                surf_tmpl.u.tex.first_layer = layer;
                surf_tmpl.u.tex.last_layer = layer;
                surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL;

                zsurf = ctx->create_surface(ctx, &texture->resource.b.b, &surf_tmpl);

                surf_tmpl.format = flushed_depth_texture->resource.b.b.format;
                surf_tmpl.u.tex.level = level;
                surf_tmpl.u.tex.first_layer = layer;
                surf_tmpl.u.tex.last_layer = layer;
                surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
                cbsurf = ctx->create_surface(ctx,
                                             &flushed_depth_texture->resource.b.b, &surf_tmpl);

                r600_blitter_begin(ctx, R600_DECOMPRESS);
                util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, 1 << sample,
                                                  rctx->custom_dsa_flush, depth);
                r600_blitter_end(ctx);

                pipe_surface_reference(&zsurf, NULL);
                pipe_surface_reference(&cbsurf, NULL);
            }
        }

        /* The texture will always be dirty if some layers or samples aren't flushed.
         * I don't think this case occurs often though. */
        if (!staging &&
                first_layer == 0 && last_layer == max_layer &&
                first_sample == 0 && last_sample == max_sample) {
            texture->dirty_db_mask &= ~(1 << level);
        }
    }

    /* reenable compression in DB_RENDER_CONTROL */
    rctx->db_misc_state.flush_depthstencil_through_cb = false;
    r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
}
Example #10
0
static void r600_blit_decompress_color(struct pipe_context *ctx,
		struct r600_texture *rtex,
		unsigned first_level, unsigned last_level,
		unsigned first_layer, unsigned last_layer)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	unsigned layer, level, checked_last_layer, max_layer;
	void *blend_decompress;

	if (!rtex->dirty_level_mask)
		return;

	switch (rctx->screen->msaa_texture_support) {
	case MSAA_TEXTURE_DECOMPRESSED:
		blend_decompress = rctx->custom_blend_decompress;
		break;
	case MSAA_TEXTURE_COMPRESSED:
		/* XXX the 2x and 4x cases are broken. */
		if (rtex->resource.b.b.nr_samples == 8)
			blend_decompress = rctx->custom_blend_fmask_decompress;
		else
			blend_decompress = rctx->custom_blend_decompress;
		break;
	case MSAA_TEXTURE_SAMPLE_ZERO:
	default:
		/* Nothing to do. */
		rtex->dirty_level_mask = 0;
		return;
	}

	for (level = first_level; level <= last_level; level++) {
		if (!(rtex->dirty_level_mask & (1 << level)))
			continue;

		/* The smaller the mipmap level, the less layers there are
		 * as far as 3D textures are concerned. */
		max_layer = u_max_layer(&rtex->resource.b.b, level);
		checked_last_layer = last_layer < max_layer ? last_layer : max_layer;

		for (layer = first_layer; layer <= checked_last_layer; layer++) {
			struct pipe_surface *cbsurf, surf_tmpl;

			surf_tmpl.format = rtex->resource.b.b.format;
			surf_tmpl.u.tex.level = level;
			surf_tmpl.u.tex.first_layer = layer;
			surf_tmpl.u.tex.last_layer = layer;
			cbsurf = ctx->create_surface(ctx, &rtex->resource.b.b, &surf_tmpl);

			r600_blitter_begin(ctx, R600_DECOMPRESS);
			util_blitter_custom_color(rctx->blitter, cbsurf, blend_decompress);
			r600_blitter_end(ctx);

			pipe_surface_reference(&cbsurf, NULL);
		}

		/* The texture will always be dirty if some layers aren't flushed.
		 * I don't think this case occurs often though. */
		if (first_layer == 0 && last_layer == max_layer) {
			rtex->dirty_level_mask &= ~(1 << level);
		}
	}
}