예제 #1
0
static void si_check_render_feedback_textures(struct si_context *sctx,
                                              struct si_textures_info *textures)
{
	uint32_t mask = textures->views.desc.enabled_mask;

	while (mask) {
		const struct pipe_sampler_view *view;
		struct r600_texture *tex;
		bool render_feedback = false;

		unsigned i = u_bit_scan(&mask);

		view = textures->views.views[i];
		if(view->texture->target == PIPE_BUFFER)
			continue;

		tex = (struct r600_texture *)view->texture;
		if (!tex->dcc_offset)
			continue;

		for (unsigned j = 0; j < sctx->framebuffer.state.nr_cbufs; ++j) {
			struct r600_surface * surf;

			if (!sctx->framebuffer.state.cbufs[j])
				continue;

			surf = (struct r600_surface*)sctx->framebuffer.state.cbufs[j];

			if (tex == (struct r600_texture*)surf->base.texture &&
			    surf->base.u.tex.level >= view->u.tex.first_level &&
			    surf->base.u.tex.level <= view->u.tex.last_level &&
			    surf->base.u.tex.first_layer <= view->u.tex.last_layer &&
			    surf->base.u.tex.last_layer >= view->u.tex.first_layer)
				render_feedback = true;
		}

		if (render_feedback) {
			struct si_screen *screen = sctx->screen;
			r600_texture_disable_dcc(&screen->b, tex);
		}
	}
}
예제 #2
0
static void
si_set_shader_images(struct pipe_context *pipe, unsigned shader,
		     unsigned start_slot, unsigned count,
		     struct pipe_image_view *views)
{
	struct si_context *ctx = (struct si_context *)pipe;
	struct si_screen *screen = ctx->screen;
	struct si_images_info *images = &ctx->images[shader];
	unsigned i, slot;

	assert(shader < SI_NUM_SHADERS);

	if (!count)
		return;

	assert(start_slot + count <= SI_NUM_IMAGES);

	for (i = 0, slot = start_slot; i < count; ++i, ++slot) {
		struct r600_resource *res;

		if (!views || !views[i].resource) {
			si_disable_shader_image(images, slot);
			continue;
		}

		res = (struct r600_resource *)views[i].resource;
		util_copy_image_view(&images->views[slot], &views[i]);

		si_sampler_view_add_buffer(ctx, &res->b.b,
					   RADEON_USAGE_READWRITE);

		if (res->b.b.target == PIPE_BUFFER) {
			si_make_buffer_descriptor(screen, res,
						  views[i].format,
						  views[i].u.buf.first_element,
						  views[i].u.buf.last_element,
						  images->desc.list + slot * 8);
			images->compressed_colortex_mask &= ~(1 << slot);
		} else {
			static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
			struct r600_texture *tex = (struct r600_texture *)res;
			unsigned level;
			unsigned width, height, depth;

			assert(!tex->is_depth);
			assert(tex->fmask.size == 0);

			if (tex->dcc_offset &&
			    views[i].access & PIPE_IMAGE_ACCESS_WRITE)
				r600_texture_disable_dcc(&screen->b, tex);

			if (is_compressed_colortex(tex)) {
				images->compressed_colortex_mask |= 1 << slot;
			} else {
				images->compressed_colortex_mask &= ~(1 << slot);
			}

			/* Always force the base level to the selected level.
			 *
			 * This is required for 3D textures, where otherwise
			 * selecting a single slice for non-layered bindings
			 * fails. It doesn't hurt the other targets.
			 */
			level = views[i].u.tex.level;
			width = u_minify(res->b.b.width0, level);
			height = u_minify(res->b.b.height0, level);
			depth = u_minify(res->b.b.depth0, level);

			si_make_texture_descriptor(screen, tex, false, res->b.b.target,
						   views[i].format, swizzle,
						   level, 0, 0,
						   views[i].u.tex.first_layer, views[i].u.tex.last_layer,
						   width, height, depth,
						   images->desc.list + slot * 8,
						   NULL);
		}

		images->desc.enabled_mask |= 1u << slot;
		images->desc.dirty_mask |= 1u << slot;
	}
}