static void r600_texture_state_cb(struct r600_screen *rscreen, struct r600_resource_texture *rtexture, unsigned cb, unsigned level)
{
	struct radeon_state *rstate;
	struct r600_resource *rbuffer;
	unsigned pitch, slice;
	unsigned color_info;
	unsigned format, swap, ntype;
	const struct util_format_description *desc;

	rstate = &rtexture->cb[cb][level];
	radeon_state_init(rstate, rscreen->rw, R600_STATE_CB0 + cb, 0, 0);
	rbuffer = &rtexture->resource;

	/* set states (most default value are 0 and struct already
	 * initialized to 0, thus avoid resetting them)
	 */
	pitch = (rtexture->pitch[level] / rtexture->bpt) / 8 - 1;
	slice = (rtexture->pitch[level] / rtexture->bpt) * rtexture->height[level] / 64 - 1;
	ntype = 0;
	desc = util_format_description(rbuffer->base.b.format);
	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
		ntype = V_0280A0_NUMBER_SRGB;
	format = r600_translate_colorformat(rtexture->resource.base.b.format);
	swap = r600_translate_colorswap(rtexture->resource.base.b.format);
	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
		rstate->bo[0] = radeon_bo_incref(rscreen->rw, rtexture->uncompressed);
		rstate->bo[1] = radeon_bo_incref(rscreen->rw, rtexture->uncompressed);
		rstate->bo[2] = radeon_bo_incref(rscreen->rw, rtexture->uncompressed);
		rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
		rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
		rstate->placement[4] = RADEON_GEM_DOMAIN_GTT;
		rstate->nbo = 3;
		color_info = 0;
	} else {
		rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
		rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
		rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
		rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
		rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
		rstate->placement[4] = RADEON_GEM_DOMAIN_GTT;
		rstate->nbo = 3;
		color_info = S_0280A0_SOURCE_FORMAT(1);
	}
	color_info |= S_0280A0_FORMAT(format) |
		S_0280A0_COMP_SWAP(swap) |
		S_0280A0_BLEND_CLAMP(1) |
		S_0280A0_NUMBER_TYPE(ntype);
	rstate->states[R600_CB0__CB_COLOR0_BASE] = rtexture->offset[level] >> 8;
	rstate->states[R600_CB0__CB_COLOR0_INFO] = color_info;
	rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) |
						S_028060_SLICE_TILE_MAX(slice);

	radeon_state_pm4(rstate);
}
static void vi_get_fast_clear_parameters(enum pipe_format surface_format,
					 const union pipe_color_union *color,
					 uint32_t* reset_value,
					 bool* clear_words_needed)
{
	bool values[4] = {};
	int i;
	bool main_value = false;
	bool extra_value = false;
	int extra_channel;
	const struct util_format_description *desc = util_format_description(surface_format);

	*clear_words_needed = true;
	*reset_value = 0x20202020U;

	/* If we want to clear without needing a fast clear eliminate step, we
	 * can set each channel to 0 or 1 (or 0/max for integer formats). We
	 * have two sets of flags, one for the last or first channel(extra) and
	 * one for the other channels(main).
	 */

	if (surface_format == PIPE_FORMAT_R11G11B10_FLOAT ||
	    surface_format == PIPE_FORMAT_B5G6R5_UNORM ||
	    surface_format == PIPE_FORMAT_B5G6R5_SRGB) {
		extra_channel = -1;
	} else if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
		if(r600_translate_colorswap(surface_format) <= 1)
			extra_channel = desc->nr_channels - 1;
		else
			extra_channel = 0;
	} else
		return;

	for (i = 0; i < 4; ++i) {
		int index = desc->swizzle[i] - UTIL_FORMAT_SWIZZLE_X;

		if (desc->swizzle[i] < UTIL_FORMAT_SWIZZLE_X ||
		    desc->swizzle[i] > UTIL_FORMAT_SWIZZLE_W)
			continue;

		if (util_format_is_pure_sint(surface_format)) {
			values[i] = color->i[i] != 0;
			if (color->i[i] != 0 && color->i[i] != INT32_MAX)
				return;
		} else if (util_format_is_pure_uint(surface_format)) {
			values[i] = color->ui[i] != 0U;
			if (color->ui[i] != 0U && color->ui[i] != UINT32_MAX)
				return;
		} else {
			values[i] = color->f[i] != 0.0F;
			if (color->f[i] != 0.0F && color->f[i] != 1.0F)
				return;
		}

		if (index == extra_channel)
			extra_value = values[i];
		else
			main_value = values[i];
	}

	for (int i = 0; i < 4; ++i)
		if (values[i] != main_value &&
		    desc->swizzle[i] - UTIL_FORMAT_SWIZZLE_X != extra_channel &&
		    desc->swizzle[i] >= UTIL_FORMAT_SWIZZLE_X &&
		    desc->swizzle[i] <= UTIL_FORMAT_SWIZZLE_W)
			return;

	*clear_words_needed = false;
	if (main_value)
		*reset_value |= 0x80808080U;

	if (extra_value)
		*reset_value |= 0x40404040U;
}