Exemplo n.º 1
0
static void r600_clear(struct pipe_context *ctx, unsigned buffers,
		       const union pipe_color_union *color,
		       double depth, unsigned stencil)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;

	/* fast color clear on AA framebuffers (EG+) */
	if ((buffers & PIPE_CLEAR_COLOR) && can_fast_clear_color(ctx)) {
		int i;

		for (i = 0; i < fb->nr_cbufs; i++) {
			struct r600_texture *tex = (struct r600_texture *)fb->cbufs[i]->texture;

			evergreen_set_clear_color(fb->cbufs[i], color);
			r600_clear_buffer(ctx, fb->cbufs[i]->texture,
					tex->cmask_offset, tex->cmask_size, 0);
			tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
		}

		rctx->framebuffer.atom.dirty = true;

		buffers &= ~PIPE_CLEAR_COLOR;
		if (!buffers)
			return;
	}

	/* if hyperz enabled just clear hyperz */
	if (fb->zsbuf && (buffers & PIPE_CLEAR_DEPTH)) {
		struct r600_texture *rtex;
		unsigned level = fb->zsbuf->u.tex.level;

		rtex = (struct r600_texture*)fb->zsbuf->texture;

		/* We can't use hyperz fast clear if each slice of a texture
		 * array are clear to different value. To simplify code just
		 * disable fast clear for texture array.
		 */
		/* Only use htile for first level */
		if (rtex->htile && !level && rtex->surface.array_size == 1) {
			if (rtex->depth_clear != depth) {
				rtex->depth_clear = depth;
				rctx->db_state.atom.dirty = true;
			}
			rctx->db_misc_state.htile_clear = true;
			rctx->db_misc_state.atom.dirty = true;
		}
	}

	r600_blitter_begin(ctx, R600_CLEAR);
	util_blitter_clear(rctx->blitter, fb->width, fb->height,
			   buffers, color, depth, stencil);
	r600_blitter_end(ctx);

	/* disable fast clear */
	if (rctx->db_misc_state.htile_clear) {
		rctx->db_misc_state.htile_clear = false;
		rctx->db_misc_state.atom.dirty = true;
	}
}
Exemplo n.º 2
0
void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
				   struct pipe_framebuffer_state *fb,
				   struct r600_atom *fb_state,
				   unsigned *buffers,
				   const union pipe_color_union *color)
{
	int i;

	if (rctx->current_render_cond)
		return;

	for (i = 0; i < fb->nr_cbufs; i++) {
		struct r600_texture *tex;
		unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;

		if (!fb->cbufs[i])
			continue;

		/* if this colorbuffer is not being cleared */
		if (!(*buffers & clear_bit))
			continue;

		tex = (struct r600_texture *)fb->cbufs[i]->texture;

		/* 128-bit formats are unusupported */
		if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) {
			continue;
		}

		/* 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)) {
			continue;
		}

		/* cannot clear mipmapped textures */
		if (fb->cbufs[i]->texture->last_level != 0) {
			continue;
		}

		/* only supported on tiled surfaces */
		if (tex->surface.level[0].mode < RADEON_SURF_MODE_1D) {
			continue;
		}

		/* fast color clear with 1D tiling doesn't work on old kernels and CIK */
		if (tex->surface.level[0].mode == RADEON_SURF_MODE_1D &&
		    rctx->chip_class >= CIK &&
		    rctx->screen->info.drm_major == 2 &&
		    rctx->screen->info.drm_minor < 38) {
			continue;
		}

		/* ensure CMASK is enabled */
		r600_texture_alloc_cmask_separate(rctx->screen, tex);
		if (tex->cmask.size == 0) {
			continue;
		}

		/* Do the fast clear. */
		evergreen_set_clear_color(tex, fb->cbufs[i]->format, color);
		rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
				   tex->cmask.offset, tex->cmask.size, 0, true);

		tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
		rctx->set_atom_dirty(rctx, fb_state, true);
		*buffers &= ~clear_bit;
	}
}