/*
 * Copyright (C) 2008-2010  Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * Authors:
 *   Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
 */

#include "main/glheader.h"
#include "main/imports.h"
#include "main/colormac.h"
#include "main/context.h"
#include "main/enums.h"
#include "main/image.h"
#include "main/teximage.h"
#include "main/simple_list.h"
#include "main/texobj.h"

#include "texmem.h"

#include "r600_context.h"
#include "radeon_mipmap_tree.h"
#include "evergreen_diff.h"
#include "evergreen_tex.h"
#include "evergreen_fragprog.h"
#include "evergreen_vertprog.h"

#include "r600_tex.h"

static unsigned int evergreen_translate_wrap_mode(GLenum wrapmode)
{
	switch(wrapmode) {
	case GL_REPEAT: return SQ_TEX_WRAP;
	case GL_CLAMP: return SQ_TEX_CLAMP_HALF_BORDER;
	case GL_CLAMP_TO_EDGE: return SQ_TEX_CLAMP_LAST_TEXEL;
	case GL_CLAMP_TO_BORDER: return SQ_TEX_CLAMP_BORDER;
	case GL_MIRRORED_REPEAT: return SQ_TEX_MIRROR;
	case GL_MIRROR_CLAMP_EXT: return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
	case GL_MIRROR_CLAMP_TO_EDGE_EXT: return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
	case GL_MIRROR_CLAMP_TO_BORDER_EXT: return SQ_TEX_MIRROR_ONCE_BORDER;
	default:
		radeon_error("bad wrap mode in %s", __FUNCTION__);
		return 0;
	}
}

static GLboolean evergreenGetTexFormat(struct gl_texture_object *tObj, gl_format mesa_format)
{
	radeonTexObj *t = radeon_tex_obj(tObj);

	CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
	CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
	CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
	CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
	CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);

	SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
		     FORMAT_COMP_X_shift, 
             FORMAT_COMP_X_mask);
	SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
		     FORMAT_COMP_Y_shift, 
             FORMAT_COMP_Y_mask);
	SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
		     FORMAT_COMP_Z_shift, 
             FORMAT_COMP_Z_mask);
	SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
		     FORMAT_COMP_W_shift, 
             FORMAT_COMP_W_mask);
	
	SETfield(t->SQ_TEX_RESOURCE1, ARRAY_LINEAR_GENERAL,
		     EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift,
		     EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_mask);

	switch (mesa_format) /* This is mesa format. */
	{
	case MESA_FORMAT_RGBA8888:
	case MESA_FORMAT_SIGNED_RGBA8888:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888) {
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_X_shift, FORMAT_COMP_X_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
		}
		break;
	case MESA_FORMAT_RGBA8888_REV:
	case MESA_FORMAT_SIGNED_RGBA8888_REV:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888_REV) {
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_X_shift, FORMAT_COMP_X_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
				 FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
		}
		break;
	case MESA_FORMAT_ARGB8888:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_XRGB8888:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_XRGB8888_REV:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_ARGB8888_REV:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_RGB888:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_RGB565:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_RGB565_REV:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_ARGB4444:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_4_4_4_4,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_ARGB4444_REV:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_4_4_4_4,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_ARGB1555:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_1_5_5_5,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_ARGB1555_REV:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_1_5_5_5,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_AL88:
	case MESA_FORMAT_AL88_REV: /* TODO : Check this. */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_RGB332:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_3_3_2,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_A8: /* ZERO, ZERO, ZERO, X */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_L8: /* X, X, X, ONE */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_I8: /* X, X, X, X */
	case MESA_FORMAT_CI8:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;		
	case MESA_FORMAT_RGB_DXT1: /* not supported yet */
	case MESA_FORMAT_RGBA_DXT1: /* not supported yet */
	case MESA_FORMAT_RGBA_DXT3: /* not supported yet */
	case MESA_FORMAT_RGBA_DXT5: /* not supported yet */
	        return GL_FALSE;

	case MESA_FORMAT_RGBA_FLOAT32:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_32_32_32_32_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_RGBA_FLOAT16:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_16_16_16_16_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_RGB_FLOAT32: /* X, Y, Z, ONE */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_32_32_32_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_RGB_FLOAT16:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_16_16_16_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_ALPHA_FLOAT32: /* ZERO, ZERO, ZERO, X */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_32_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_ALPHA_FLOAT16: /* ZERO, ZERO, ZERO, X */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_16_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_LUMINANCE_FLOAT32: /* X, X, X, ONE */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_32_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_LUMINANCE_FLOAT16: /* X, X, X, ONE */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_16_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_32_32_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_16_16_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_32_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_16_FLOAT,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		break;
	case MESA_FORMAT_Z16:
	case MESA_FORMAT_X8_Z24:
	case MESA_FORMAT_S8_Z24:
	case MESA_FORMAT_Z24_S8:
	case MESA_FORMAT_Z32:
	case MESA_FORMAT_S8:        	
        CLEARbit(t->SQ_TEX_RESOURCE0, EG_SQ_TEX_RESOURCE_WORD0_0__NDTO_bit);        
		SETfield(t->SQ_TEX_RESOURCE1, ARRAY_1D_TILED_THIN1,
			     EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift,
			     EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_mask);
		switch (mesa_format) {
		case MESA_FORMAT_Z16:
			SETfield(t->SQ_TEX_RESOURCE7, FMT_16,
				     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
			break;
		case MESA_FORMAT_X8_Z24:
		case MESA_FORMAT_S8_Z24:
			SETfield(t->SQ_TEX_RESOURCE7, FMT_8_24,
				     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
			break;
		case MESA_FORMAT_Z24_S8:
			SETfield(t->SQ_TEX_RESOURCE7, FMT_24_8,
				     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
			break;
		case MESA_FORMAT_Z32:
			SETfield(t->SQ_TEX_RESOURCE7, FMT_32,
				     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
			break;
		case MESA_FORMAT_S8:
			SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
				     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
			break;
		default:
			break;
		};
		switch (tObj->DepthMode) {
		case GL_LUMINANCE:  /* X, X, X, ONE */
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
			break;
		case GL_INTENSITY:  /* X, X, X, X */
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
			break;
		case GL_ALPHA:     /* ZERO, ZERO, ZERO, X */
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
			break;
		default:
			return GL_FALSE;
		}
		break;
	/* EXT_texture_sRGB */
	case MESA_FORMAT_SRGBA8:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
		break;
	case MESA_FORMAT_SLA8:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
		break;
	case MESA_FORMAT_SL8: /* X, X, X, ONE */
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
		break;
	default:
		/* Not supported format */
		return GL_FALSE;
	};

	return GL_TRUE;
}

static GLuint evergreen_translate_shadow_func(GLenum func)
{
   switch (func) {
   case GL_NEVER:
      return SQ_TEX_DEPTH_COMPARE_NEVER;
   case GL_LESS:
      return SQ_TEX_DEPTH_COMPARE_LESS;
   case GL_LEQUAL:
      return SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
   case GL_GREATER:
      return SQ_TEX_DEPTH_COMPARE_GREATER;
   case GL_GEQUAL:
      return SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
   case GL_NOTEQUAL:
      return SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
   case GL_EQUAL:
      return SQ_TEX_DEPTH_COMPARE_EQUAL;
   case GL_ALWAYS:
      return SQ_TEX_DEPTH_COMPARE_ALWAYS;
   default:
      WARN_ONCE("Unknown shadow compare function! %d", func);
      return 0;
   }
}

static void evergreenUpdateTexWrap(radeonTexObjPtr t)
{
	struct gl_texture_object *tObj = &t->base;

    SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_wrap_mode(tObj->WrapS),
             EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);

	if (tObj->Target != GL_TEXTURE_1D) 
    {
		SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_wrap_mode(tObj->WrapT),
			     EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Y_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Y_mask);

		if (tObj->Target == GL_TEXTURE_3D)
			SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_wrap_mode(tObj->WrapR),
				     EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Z_shift, 
                     EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Z_mask);
	}
}

static void evergreenSetTexDefaultState(radeonTexObjPtr t)
{       
    /* Init text object to default states. */
    t->SQ_TEX_RESOURCE0 = 0;
    t->SQ_TEX_RESOURCE1 = 0;
    t->SQ_TEX_RESOURCE2 = 0;
    t->SQ_TEX_RESOURCE3 = 0;
    t->SQ_TEX_RESOURCE4 = 0;
    t->SQ_TEX_RESOURCE5 = 0;
    t->SQ_TEX_RESOURCE6 = 0;
    t->SQ_TEX_RESOURCE7 = 0;

    SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_2D, 
             EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift, 
             EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);

    CLEARbit(t->SQ_TEX_RESOURCE0, EG_SQ_TEX_RESOURCE_WORD0_0__NDTO_bit);

    SETfield(t->SQ_TEX_RESOURCE1, ARRAY_LINEAR_GENERAL,
             EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift, 
             EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_mask);       
        
    SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
             FORMAT_COMP_X_shift, FORMAT_COMP_X_mask);
    SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
             FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
    SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
             FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
    SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
             FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
    SETfield(t->SQ_TEX_RESOURCE4, SQ_NUM_FORMAT_NORM,
             SQ_TEX_RESOURCE_WORD4_0__NUM_FORMAT_ALL_shift, SQ_TEX_RESOURCE_WORD4_0__NUM_FORMAT_ALL_mask);
    CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__SRF_MODE_ALL_bit);
    CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
    SETfield(t->SQ_TEX_RESOURCE4, SQ_ENDIAN_NONE,
             SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_shift, SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_mask);
        
    SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
	SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
	SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
	SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift,
		     SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
    SETfield(t->SQ_TEX_RESOURCE4, 0, 
             BASE_LEVEL_shift, 
             BASE_LEVEL_mask); /* mip-maps */            

    SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
             EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
             EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
    SETfield(t->SQ_TEX_RESOURCE7, SQ_TEX_VTX_VALID_TEXTURE,
             EG_SQ_TEX_RESOURCE_WORD7_0__TYPE_shift, 
             EG_SQ_TEX_RESOURCE_WORD7_0__TYPE_mask);

    /* Initialize sampler registers */
    t->SQ_TEX_SAMPLER0 = 0;
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, 
             EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift,
	         EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, 
             EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, 
             EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT, 
             EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_mask);
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT, 
             EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE, 
             EG_SQ_TEX_SAMPLER_WORD0_0__Z_FILTER_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__Z_FILTER_mask);
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE, 
             EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_TRANS_BLACK, 
             EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_mask);

    t->SQ_TEX_SAMPLER1 = 0;
    SETfield(t->SQ_TEX_SAMPLER1, 0x7ff, 
             EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_shift, 
             EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_mask);

    t->SQ_TEX_SAMPLER2 = 0;
    SETbit(t->SQ_TEX_SAMPLER2, EG_SQ_TEX_SAMPLER_WORD2_0__TYPE_bit);
}

static void evergreenSetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
{
	/* Force revalidation to account for switches from/to mipmapping. */
	t->validated = GL_FALSE;

	/* Note that EXT_texture_filter_anisotropic is extremely vague about
	 * how anisotropic filtering interacts with the "normal" filter modes.
	 * When anisotropic filtering is enabled, we override min and mag
	 * filter settings completely. This includes driconf's settings.
	 */
	if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) {
		/*t->pp_txfilter |= R300_TX_MAG_FILTER_ANISO
			| R300_TX_MIN_FILTER_ANISO
			| R300_TX_MIN_FILTER_MIP_LINEAR
			| aniso_filter(anisotropy);*/
		radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "Using maximum anisotropy of %f\n", anisotropy);
		return;
	}

	switch (minf) 
    {
	case GL_NEAREST:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
		SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_None,
			     EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
		break;
	case GL_LINEAR:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
		SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_None,
			     EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
		break;
	case GL_NEAREST_MIPMAP_NEAREST:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
		SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Point,
			     EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
		break;
	case GL_NEAREST_MIPMAP_LINEAR:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
		SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Linear,
			     EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
		break;
	case GL_LINEAR_MIPMAP_NEAREST:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
		SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Point,
			     EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
		break;
	case GL_LINEAR_MIPMAP_LINEAR:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
		SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Linear,
			     EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
		break;
	}

	/* Note we don't have 3D mipmaps so only use the mag filter setting
	 * to set the 3D texture filter mode.
	 */
	switch (magf) 
    {
	case GL_NEAREST:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_mask);
		break;
	case GL_LINEAR:
		SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
			     EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_mask);
		break;
	}
}

static void evergreenSetTexBorderColor(radeonTexObjPtr t, const GLfloat color[4])
{
	t->TD_PS_SAMPLER0_BORDER_ALPHA = *((uint32_t*)&(color[3]));
	t->TD_PS_SAMPLER0_BORDER_RED = *((uint32_t*)&(color[2]));
	t->TD_PS_SAMPLER0_BORDER_GREEN = *((uint32_t*)&(color[1]));
	t->TD_PS_SAMPLER0_BORDER_BLUE = *((uint32_t*)&(color[0]));

    SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_REGISTER,
		     EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_shift, 
             EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_mask);
}

static void evergreenSetDepthTexMode(struct gl_texture_object *tObj)
{
	radeonTexObjPtr t;

	if (!tObj)
		return;

	t = radeon_tex_obj(tObj);

	if(!evergreenGetTexFormat(tObj, tObj->Image[0][tObj->BaseLevel]->TexFormat))
	  t->validated = GL_FALSE;
}

static INLINE uint32_t
EG_S_FIXED(float value, uint32_t frac_bits)
{
   return value * (1 << frac_bits);
}

static GLboolean evergreen_setup_hardware_state(struct gl_context * ctx, struct gl_texture_object *texObj, int unit)
{
	context_t *context = EVERGREEN_CONTEXT(ctx);
	radeonTexObj *t = radeon_tex_obj(texObj);
	const struct gl_texture_image *firstImage;
	GLuint uTexelPitch, row_align;

	if (context->radeon.radeonScreen->driScreen->dri2.enabled &&
	    t->image_override &&
	    t->bo)
		return GL_TRUE;

	firstImage = t->base.Image[0][t->minLod];

	if (!t->image_override) {        
		if (!evergreenGetTexFormat(texObj, firstImage->TexFormat)) {
			radeon_warning("unsupported texture format in %s\n",
				       __FUNCTION__);
			return GL_FALSE;
		}        
	}

    switch (texObj->Target) 
    {
    case GL_TEXTURE_1D:
        SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_1D, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
        SETfield(t->SQ_TEX_RESOURCE1, 0, 
                 EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift, 
                 EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
        break;
    case GL_TEXTURE_2D:
    case GL_TEXTURE_RECTANGLE_NV:
        SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_2D, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
        SETfield(t->SQ_TEX_RESOURCE1, 0, 
                 EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift, 
                 EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
        break;
    case GL_TEXTURE_3D:
        SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_3D, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
        SETfield(t->SQ_TEX_RESOURCE1, (firstImage->Depth - 1), // ???
	             EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift, 
                 EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
        break;
    case GL_TEXTURE_CUBE_MAP:
        SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_CUBEMAP, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift, 
                 EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
        SETfield(t->SQ_TEX_RESOURCE1, 0, 
                 EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift, 
                 EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
        break;
    default:
        radeon_error("unexpected texture target type in %s\n", __FUNCTION__);
        return GL_FALSE;
    }

    row_align = context->radeon.texture_row_align - 1;
    uTexelPitch = (_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align;
    uTexelPitch = uTexelPitch / _mesa_get_format_bytes(firstImage->TexFormat);
    uTexelPitch = (uTexelPitch + R700_TEXEL_PITCH_ALIGNMENT_MASK)
	             & ~R700_TEXEL_PITCH_ALIGNMENT_MASK;

	/* min pitch is 8 */
	if (uTexelPitch < 8)
		uTexelPitch = 8;

	SETfield(t->SQ_TEX_RESOURCE0, (uTexelPitch/8)-1, 
             EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_shift, 
             EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_mask);
	SETfield(t->SQ_TEX_RESOURCE0, firstImage->Width - 1,
		     EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_shift, 
             EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_mask);
	SETfield(t->SQ_TEX_RESOURCE1, firstImage->Height - 1,
		     EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_shift, 
             EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_mask);

	t->SQ_TEX_RESOURCE2 = get_base_teximage_offset(t) / 256;

	t->SQ_TEX_RESOURCE3 = radeon_miptree_image_offset(t->mt, 0, t->minLod + 1) / 256;

	SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask);
	SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask);
    
	SETfield(t->SQ_TEX_SAMPLER1,
		     EG_S_FIXED(CLAMP(t->base.MinLod - t->minLod, 0, 15), 8),
		     EG_SQ_TEX_SAMPLER_WORD1_0__MIN_LOD_shift, 
             EG_SQ_TEX_SAMPLER_WORD1_0__MIN_LOD_mask);
	SETfield(t->SQ_TEX_SAMPLER1,
		     EG_S_FIXED(CLAMP(t->base.MaxLod - t->minLod, 0, 15), 8),
		     EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_shift, 
             EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_mask);
	SETfield(t->SQ_TEX_SAMPLER2,
		     EG_S_FIXED(CLAMP(ctx->Texture.Unit[unit].LodBias + t->base.LodBias, -16, 16), 8),
		     EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_shift, 
             EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_mask);

	if(texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB)
	{
		SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_shadow_func(texObj->CompareFunc), 
                 EG_SQ_TEX_SAMPLER_WORD0_0__DCF_shift, 
                 EG_SQ_TEX_SAMPLER_WORD0_0__DCF_mask);
	}
	else
	{
		CLEARfield(t->SQ_TEX_SAMPLER0, EG_SQ_TEX_SAMPLER_WORD0_0__DCF_mask);
	}

	return GL_TRUE;
}

void evergreenSetTexOffset(__DRIcontext * pDRICtx, GLint texname,
		      unsigned long long offset, GLint depth, GLuint pitch)
{
	context_t *rmesa = pDRICtx->driverPrivate;
	struct gl_texture_object *tObj =
	    _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
	radeonTexObjPtr t = radeon_tex_obj(tObj);
	const struct gl_texture_image *firstImage;
	uint32_t pitch_val, size, row_align;

	if (!tObj)
		return;

	t->image_override = GL_TRUE;

	if (!offset)
		return;

	firstImage = t->base.Image[0][t->minLod];
	row_align = rmesa->radeon.texture_row_align - 1;
	size = ((_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align) * firstImage->Height;
	if (t->bo) {
		radeon_bo_unref(t->bo);
		t->bo = NULL;
	}
	t->bo = radeon_legacy_bo_alloc_fake(rmesa->radeon.radeonScreen->bom, size, offset);
	t->override_offset = offset;
	pitch_val = pitch;
	switch (depth) {
	case 32:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		pitch_val /= 4;
		break;
	case 24:
	default:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		pitch_val /= 4;
		break;
	case 16:
		SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		pitch_val /= 2;
		break;
	}

	pitch_val = (pitch_val + R700_TEXEL_PITCH_ALIGNMENT_MASK)
		& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;

	/* min pitch is 8 */
	if (pitch_val < 8)
		pitch_val = 8;

	SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1, 
             EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_shift, 
             EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_mask);
}

void evergreenSetTexBuffer(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv)
{
	struct gl_texture_unit *texUnit;
	struct gl_texture_object *texObj;
	struct gl_texture_image *texImage;
	struct radeon_renderbuffer *rb;
	radeon_texture_image *rImage;
	radeonContextPtr radeon;
	context_t *rmesa;
	struct radeon_framebuffer *rfb;
	radeonTexObjPtr t;
	uint32_t pitch_val;
	uint32_t internalFormat, type, format;
	gl_format texFormat;

	type = GL_BGRA;
	format = GL_UNSIGNED_BYTE;
	internalFormat = (glx_texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);

	radeon = pDRICtx->driverPrivate;
	rmesa = pDRICtx->driverPrivate;

	rfb = dPriv->driverPrivate;
        texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
	texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
        texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);

	rImage = get_radeon_texture_image(texImage);
	t = radeon_tex_obj(texObj);
        if (t == NULL) {
    	    return;
    	}

	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
	rb = rfb->color_rb[0];
	if (rb->bo == NULL) {
		/* Failed to BO for the buffer */
		return;
	}

	_mesa_lock_texture(radeon->glCtx, texObj);
	if (t->bo) {
		radeon_bo_unref(t->bo);
		t->bo = NULL;
	}
	if (rImage->bo) {
		radeon_bo_unref(rImage->bo);
		rImage->bo = NULL;
	}

	radeon_miptree_unreference(&t->mt);
	radeon_miptree_unreference(&rImage->mt);

	rImage->bo = rb->bo;
	radeon_bo_ref(rImage->bo);
	t->bo = rb->bo;
	radeon_bo_ref(t->bo);
	t->image_override = GL_TRUE;
	t->override_offset = 0;
	pitch_val = rb->pitch;
	switch (rb->cpp) {
	case 4:
		if (glx_texture_format == __DRI_TEXTURE_FORMAT_RGB) {
			texFormat = MESA_FORMAT_RGB888;
			SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
				     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		} else {
			texFormat = MESA_FORMAT_ARGB8888;
			SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
				     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
			SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
				 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		}
		pitch_val /= 4;
		break;
	case 3:
	default:
		// FMT_8_8_8 ???
		texFormat = MESA_FORMAT_RGB888;
		SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		pitch_val /= 4;
		break;
	case 2:
		texFormat = MESA_FORMAT_RGB565;
		SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
			     EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift, 
                 EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);

		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
		pitch_val /= 2;
		break;
	}

	_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
				   rb->base.Width, rb->base.Height, 1, 0,
				   rb->cpp, texFormat);
	texImage->RowStride = rb->pitch / rb->cpp;

	pitch_val = (pitch_val + R700_TEXEL_PITCH_ALIGNMENT_MASK)
		& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;

	/* min pitch is 8 */
	if (pitch_val < 8)
		pitch_val = 8;

	SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1, 
             EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_shift, 
             EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_mask);
	SETfield(t->SQ_TEX_RESOURCE0, rb->base.Width - 1,
		     EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_shift, 
             EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_mask);
	SETfield(t->SQ_TEX_RESOURCE1, rb->base.Height - 1,
		     EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_shift, 
             EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_mask);

	t->validated = GL_TRUE;
	_mesa_unlock_texture(radeon->glCtx, texObj);
	return;
}

void evergreenUpdateTextureState(struct gl_context * ctx)
{
	context_t *context = EVERGREEN_CONTEXT(ctx);
    EVERGREEN_CHIP_CONTEXT * evergreen = GET_EVERGREEN_CHIP(context);	
	struct gl_texture_unit *texUnit;
	struct radeon_tex_obj *t;
	GLuint    unit;

	EVERGREEN_STATECHANGE(context, tx);    

	for (unit = 0; unit < R700_MAX_TEXTURE_UNITS; unit++) {
		texUnit = &ctx->Texture.Unit[unit];
		t = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
		evergreen->textures[unit] = NULL;
		if (texUnit->_ReallyEnabled) {
			if (!t)
				continue;
			evergreen->textures[unit] = t;
		}
	}
}

static GLboolean evergreen_validate_texture(struct gl_context * ctx, struct gl_texture_object *texObj, int unit)
{
	radeonTexObj *t = radeon_tex_obj(texObj);

	if (!radeon_validate_texture_miptree(ctx, texObj))
		return GL_FALSE;

	/* Configure the hardware registers (more precisely, the cached version
	 * of the hardware registers). */
	if (!evergreen_setup_hardware_state(ctx, texObj, unit))
	        return GL_FALSE;

	t->validated = GL_TRUE;
	return GL_TRUE;
}

GLboolean evergreenValidateBuffers(struct gl_context * ctx)
{
	context_t *rmesa = EVERGREEN_CONTEXT(ctx);
	struct radeon_renderbuffer *rrb;
	struct radeon_bo *pbo;
	int i;
	int ret;

	radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);

	rrb = radeon_get_colorbuffer(&rmesa->radeon);
	/* color buffer */
	if (rrb && rrb->bo) {
		radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
						  rrb->bo, 0,
						  RADEON_GEM_DOMAIN_VRAM);
	}

	/* depth buffer */
	rrb = radeon_get_depthbuffer(&rmesa->radeon);
	if (rrb && rrb->bo) {
		radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
						  rrb->bo, 0,
						  RADEON_GEM_DOMAIN_VRAM);
	}
	
	for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
		radeonTexObj *t;

		if (!ctx->Texture.Unit[i]._ReallyEnabled)
			continue;

		if (!evergreen_validate_texture(ctx, ctx->Texture.Unit[i]._Current, i)) {
			radeon_warning("failed to validate texture for unit %d.\n", i);
		}
		t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
		if (t->image_override && t->bo)
			radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
							  t->bo,
							  RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
		else if (t->mt->bo)
			radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
							  t->mt->bo,
							  RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
	}

	pbo = (struct radeon_bo *)evergreenGetActiveFpShaderBo(ctx);
	if (pbo) {
		radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
						  RADEON_GEM_DOMAIN_GTT, 0);
	}

	pbo = (struct radeon_bo *)evergreenGetActiveVpShaderBo(ctx);
	if (pbo) {
		radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
						  RADEON_GEM_DOMAIN_GTT, 0);
	}

	pbo = (struct radeon_bo *)evergreenGetActiveFpShaderConstBo(ctx);
	if (pbo) {
		radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
						  RADEON_GEM_DOMAIN_GTT, 0);
	}

	pbo = (struct radeon_bo *)evergreenGetActiveVpShaderConstBo(ctx);
	if (pbo) {
		radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
						  RADEON_GEM_DOMAIN_GTT, 0);
	}
	
	ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
	if (ret)
		return GL_FALSE;
	return GL_TRUE;
}

static struct gl_texture_object *evergreenNewTextureObject(struct gl_context * ctx,
						      GLuint name,
						      GLenum target)
{
	context_t* rmesa = EVERGREEN_CONTEXT(ctx);
	radeonTexObj * t = CALLOC_STRUCT(radeon_tex_obj);


	radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
		"%s( %p (target = %s) )\n", __FUNCTION__,
			t, _mesa_lookup_enum_by_nr(target));

	_mesa_initialize_texture_object(&t->base, name, target);
	t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
    
	evergreenSetTexDefaultState(t);
	evergreenUpdateTexWrap(t);
	evergreenSetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy);
	evergreenSetTexBorderColor(t, t->base.BorderColor.f);

	return &t->base;
}

static void evergreenDeleteTexture(struct gl_context * ctx, struct gl_texture_object *texObj)
{
	context_t              * rmesa     = EVERGREEN_CONTEXT(ctx);
    EVERGREEN_CHIP_CONTEXT * evergreen = GET_EVERGREEN_CHIP(rmesa);
	radeonTexObj* t = radeon_tex_obj(texObj);

	radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
		"%s( %p (target = %s) )\n", __FUNCTION__,
			(void *)texObj,
			_mesa_lookup_enum_by_nr(texObj->Target));

	if (rmesa) {
		int i;
		radeon_firevertices(&rmesa->radeon);

		for(i = 0; i < R700_MAX_TEXTURE_UNITS; ++i)
			if (evergreen->textures[i] == t)
				evergreen->textures[i] = 0;
	}

	if (t->bo) {
		radeon_bo_unref(t->bo);
		t->bo = NULL;
	}

	radeon_miptree_unreference(&t->mt);

	_mesa_delete_texture_object(ctx, texObj);
}

static void evergreenTexParameter(struct gl_context * ctx, GLenum target,
			     struct gl_texture_object *texObj,
			     GLenum pname, const GLfloat * params)
{
    radeonTexObj* t = radeon_tex_obj(texObj);
	GLenum baseFormat;

	radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_VERBOSE,
			"%s( %s )\n", __FUNCTION__,
			_mesa_lookup_enum_by_nr(pname));

	switch (pname) {
	case GL_TEXTURE_MIN_FILTER:
	case GL_TEXTURE_MAG_FILTER:
	case GL_TEXTURE_MAX_ANISOTROPY_EXT:
		evergreenSetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
		break;

	case GL_TEXTURE_WRAP_S:
	case GL_TEXTURE_WRAP_T:
	case GL_TEXTURE_WRAP_R:
		evergreenUpdateTexWrap(t);
		break;

	case GL_TEXTURE_BORDER_COLOR:
		evergreenSetTexBorderColor(t, texObj->BorderColor.f);
		break;

	case GL_TEXTURE_BASE_LEVEL:
	case GL_TEXTURE_MAX_LEVEL:
	case GL_TEXTURE_MIN_LOD:
	case GL_TEXTURE_MAX_LOD:
		t->validated = GL_FALSE;
		break;

	case GL_DEPTH_TEXTURE_MODE:
		if (!texObj->Image[0][texObj->BaseLevel])
			return;
		baseFormat = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
		if (baseFormat == GL_DEPTH_COMPONENT ||
		    baseFormat == GL_DEPTH_STENCIL) {
			evergreenSetDepthTexMode(texObj);
			break;
		} else {
			/* If the texture isn't a depth texture, changing this
			 * state won't cause any changes to the hardware.
			 * Don't force a flush of texture state.
			 */
			return;
		}

	default:
		return;
	}
}

void evergreenInitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
{
	/* Note: we only plug in the functions we implement in the driver
	 * since _mesa_init_driver_functions() was already called.
	 */
	functions->NewTextureImage = radeonNewTextureImage;
	functions->FreeTexImageData = radeonFreeTexImageData;
	functions->MapTexture = radeonMapTexture;
	functions->UnmapTexture = radeonUnmapTexture;

	functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa;
	functions->TexImage1D = radeonTexImage1D;
	functions->TexImage2D = radeonTexImage2D;
	functions->TexImage3D = radeonTexImage3D;
	functions->TexSubImage1D = radeonTexSubImage1D;
	functions->TexSubImage2D = radeonTexSubImage2D;
	functions->TexSubImage3D = radeonTexSubImage3D;
	functions->GetTexImage = radeonGetTexImage;
	functions->GetCompressedTexImage = radeonGetCompressedTexImage;
	functions->NewTextureObject = evergreenNewTextureObject;
	functions->DeleteTexture = evergreenDeleteTexture;
	functions->IsTextureResident = driIsTextureResident;

	functions->TexParameter = evergreenTexParameter;

	functions->CompressedTexImage2D = radeonCompressedTexImage2D;
	functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;

	if (radeon->radeonScreen->kernel_mm) {
		functions->CopyTexImage2D = radeonCopyTexImage2D;
		functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
	}

	functions->GenerateMipmap = radeonGenerateMipmap;

	driInitTextureFormats();
}
