/*
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
 *
 * 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, sub license,
 * 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 (including the
 * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
 */


#include <stdlib.h>
#include <stdio.h>

#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "enums.h"
#include "colortab.h"
#include "convolve.h"
#include "context.h"
#include "mipmap.h"
#include "simple_list.h"
#include "texcompress.h"
#include "texformat.h"
#include "texobj.h"
#include "texstore.h"

#include "mm.h"
#include "via_context.h"
#include "via_fb.h"
#include "via_tex.h"
#include "via_state.h"
#include "via_ioctl.h"
#include "via_3d_reg.h"

static const struct gl_texture_format *
viaChooseTexFormat( GLcontext *ctx, GLint internalFormat,
		    GLenum format, GLenum type )
{
   struct via_context *vmesa = VIA_CONTEXT(ctx);
   const GLboolean do32bpt = ( vmesa->viaScreen->bitsPerPixel == 32
/* 			       && vmesa->viaScreen->textureSize > 4*1024*1024 */
      );


   switch ( internalFormat ) {
   case 4:
   case GL_RGBA:
   case GL_COMPRESSED_RGBA:
      if ( format == GL_BGRA ) {
	 if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ||
	      type == GL_UNSIGNED_BYTE ) {
	    return &_mesa_texformat_argb8888;
	 }
         else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
            return &_mesa_texformat_argb4444;
	 }
         else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
	    return &_mesa_texformat_argb1555;
	 }
      }
      else if ( type == GL_UNSIGNED_BYTE ||
		type == GL_UNSIGNED_INT_8_8_8_8_REV ||
		type == GL_UNSIGNED_INT_8_8_8_8 ) {
	 return &_mesa_texformat_argb8888;
      }
      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;

   case 3:
   case GL_RGB:
   case GL_COMPRESSED_RGB:
      if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
	 return &_mesa_texformat_rgb565;
      }
      else if ( type == GL_UNSIGNED_BYTE ) {
	 return &_mesa_texformat_argb8888;
      }
      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;

   case GL_RGBA8:
   case GL_RGB10_A2:
   case GL_RGBA12:
   case GL_RGBA16:
      return &_mesa_texformat_argb8888;

   case GL_RGBA4:
   case GL_RGBA2:
      return &_mesa_texformat_argb4444;

   case GL_RGB5_A1:
      return &_mesa_texformat_argb1555;

   case GL_RGB8:
   case GL_RGB10:
   case GL_RGB12:
   case GL_RGB16:
      return &_mesa_texformat_argb8888;

   case GL_RGB5:
   case GL_RGB4:
   case GL_R3_G3_B2:
      return &_mesa_texformat_rgb565;

   case GL_ALPHA:
   case GL_ALPHA4:
   case GL_ALPHA8:
   case GL_ALPHA12:
   case GL_ALPHA16:
   case GL_COMPRESSED_ALPHA:
      return &_mesa_texformat_a8;

   case 1:
   case GL_LUMINANCE:
   case GL_LUMINANCE4:
   case GL_LUMINANCE8:
   case GL_LUMINANCE12:
   case GL_LUMINANCE16:
   case GL_COMPRESSED_LUMINANCE:
      return &_mesa_texformat_l8;

   case 2:
   case GL_LUMINANCE_ALPHA:
   case GL_LUMINANCE4_ALPHA4:
   case GL_LUMINANCE6_ALPHA2:
   case GL_LUMINANCE8_ALPHA8:
   case GL_LUMINANCE12_ALPHA4:
   case GL_LUMINANCE12_ALPHA12:
   case GL_LUMINANCE16_ALPHA16:
   case GL_COMPRESSED_LUMINANCE_ALPHA:
      return &_mesa_texformat_al88;

   case GL_INTENSITY:
   case GL_INTENSITY4:
   case GL_INTENSITY8:
   case GL_INTENSITY12:
   case GL_INTENSITY16:
   case GL_COMPRESSED_INTENSITY:
      return &_mesa_texformat_i8;

   case GL_YCBCR_MESA:
      if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
	  type == GL_UNSIGNED_BYTE)
         return &_mesa_texformat_ycbcr;
      else
         return &_mesa_texformat_ycbcr_rev;

   case GL_COMPRESSED_RGB_FXT1_3DFX:
      return &_mesa_texformat_rgb_fxt1;
   case GL_COMPRESSED_RGBA_FXT1_3DFX:
      return &_mesa_texformat_rgba_fxt1;

   case GL_RGB_S3TC:
   case GL_RGB4_S3TC:
   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
      return &_mesa_texformat_rgb_dxt1;

   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      return &_mesa_texformat_rgba_dxt1;

   case GL_RGBA_S3TC:
   case GL_RGBA4_S3TC:
   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
      return &_mesa_texformat_rgba_dxt3;

   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      return &_mesa_texformat_rgba_dxt5;

   case GL_COLOR_INDEX:	
   case GL_COLOR_INDEX1_EXT:	
   case GL_COLOR_INDEX2_EXT:	
   case GL_COLOR_INDEX4_EXT:	
   case GL_COLOR_INDEX8_EXT:	
   case GL_COLOR_INDEX12_EXT:	    
   case GL_COLOR_INDEX16_EXT:
      return &_mesa_texformat_ci8;    

   default:
      fprintf(stderr, "unexpected texture format %s in %s\n", 
	      _mesa_lookup_enum_by_nr(internalFormat),
	      __FUNCTION__);
      return NULL;
   }

   return NULL; /* never get here */
}

static int logbase2(int n)
{
   GLint i = 1;
   GLint log2 = 0;

   while (n > i) {
      i *= 2;
      log2++;
   }

   return log2;
}

static const char *get_memtype_name( GLint memType )
{
   static const char *names[] = {
      "VIA_MEM_VIDEO",
      "VIA_MEM_AGP",
      "VIA_MEM_SYSTEM",
      "VIA_MEM_MIXED",
      "VIA_MEM_UNKNOWN"
   };

   return names[memType];
}


static GLboolean viaMoveTexBuffers( struct via_context *vmesa,
				    struct via_tex_buffer **buffers,
				    GLuint nr,
				    GLint newMemType )
{
   struct via_tex_buffer *newTexBuf[VIA_MAX_TEXLEVELS];
   GLint i;

   if (VIA_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "%s to %s\n",
	      __FUNCTION__,
	      get_memtype_name(newMemType));

   memset(newTexBuf, 0, sizeof(newTexBuf));

   /* First do all the allocations (or fail):
    */ 
   for (i = 0; i < nr; i++) {    
      if (buffers[i]->memType != newMemType) {	 

	 /* Don't allow uploads in a thrash state.  Should try and
	  * catch this earlier.
	  */
	 if (vmesa->thrashing && newMemType != VIA_MEM_SYSTEM)
	    goto cleanup;

	 newTexBuf[i] = via_alloc_texture(vmesa, 
					  buffers[i]->size,
					  newMemType);
	 if (!newTexBuf[i]) 
	    goto cleanup;
      }
   }


   /* Now copy all the image data and free the old texture memory.
    */
   for (i = 0; i < nr; i++) {    
      if (newTexBuf[i]) {
	 memcpy(newTexBuf[i]->bufAddr,
		buffers[i]->bufAddr, 
		buffers[i]->size);

	 newTexBuf[i]->image = buffers[i]->image;
	 newTexBuf[i]->image->texMem = newTexBuf[i];
	 newTexBuf[i]->image->image.Data = newTexBuf[i]->bufAddr;
	 via_free_texture(vmesa, buffers[i]);
      }
   }

   if (VIA_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "%s - success\n", __FUNCTION__);

   return GL_TRUE;

 cleanup:
   /* Release any allocations made prior to failure:
    */
   if (VIA_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "%s - failed\n", __FUNCTION__);

   for (i = 0; i < nr; i++) {    
      if (newTexBuf[i]) {
	 via_free_texture(vmesa, newTexBuf[i]);
      }
   }
   
   return GL_FALSE;   
}


static GLboolean viaMoveTexObject( struct via_context *vmesa,
				   struct via_texture_object *viaObj,
				   GLint newMemType )
{   
   struct via_texture_image **viaImage = 
      (struct via_texture_image **)&viaObj->obj.Image[0][0];
   struct via_tex_buffer *buffers[VIA_MAX_TEXLEVELS];
   GLuint i, nr = 0;

   for (i = viaObj->firstLevel; i <= viaObj->lastLevel; i++)
      buffers[nr++] = viaImage[i]->texMem;

   if (viaMoveTexBuffers( vmesa, &buffers[0], nr, newMemType )) {
      viaObj->memType = newMemType;
      return GL_TRUE;
   }

   return GL_FALSE;
}



static GLboolean viaSwapInTexObject( struct via_context *vmesa,
				     struct via_texture_object *viaObj )
{
   const struct via_texture_image *baseImage = 
      (struct via_texture_image *)viaObj->obj.Image[0][viaObj->obj.BaseLevel]; 

   if (VIA_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "%s\n", __FUNCTION__);

   if (baseImage->texMem->memType != VIA_MEM_SYSTEM) 
      return viaMoveTexObject( vmesa, viaObj, baseImage->texMem->memType );

   return (viaMoveTexObject( vmesa, viaObj, VIA_MEM_AGP ) ||
	   viaMoveTexObject( vmesa, viaObj, VIA_MEM_VIDEO ));
}


/* This seems crude, but it asks a fairly pertinent question and gives
 * an accurate answer:
 */
static GLboolean viaIsTexMemLow( struct via_context *vmesa,
				 GLuint heap )
{
   struct via_tex_buffer *buf =  via_alloc_texture(vmesa, 512 * 1024, heap );
   if (!buf)
      return GL_TRUE;
   
   via_free_texture(vmesa, buf);
   return GL_FALSE;
}


/* Speculatively move texture images which haven't been used in a
 * while back to system memory. 
 * 
 * TODO: only do this when texture memory is low.
 * 
 * TODO: use dma.
 *
 * TODO: keep the fb/agp version hanging around and use the local
 * version as backing store, so re-upload might be avoided.
 *
 * TODO: do this properly in the kernel...
 */
GLboolean viaSwapOutWork( struct via_context *vmesa )
{
   struct via_tex_buffer *s, *tmp;
   GLuint done = 0;
   GLuint heap, target;

   if (VIA_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "%s VID %d AGP %d SYS %d\n", __FUNCTION__,
	      vmesa->total_alloc[VIA_MEM_VIDEO],
	      vmesa->total_alloc[VIA_MEM_AGP],
	      vmesa->total_alloc[VIA_MEM_SYSTEM]);

   
   for (heap = VIA_MEM_VIDEO; heap <= VIA_MEM_AGP; heap++) {
      GLuint nr = 0, sz = 0;

      if (vmesa->thrashing) {
 	 if (VIA_DEBUG & DEBUG_TEXTURE)
	    fprintf(stderr, "Heap %d: trash flag\n", heap);
	 target = 1*1024*1024;
      }
      else if (viaIsTexMemLow(vmesa, heap)) {
 	 if (VIA_DEBUG & DEBUG_TEXTURE)
	    fprintf(stderr, "Heap %d: low memory\n", heap);
	 target = 64*1024;
      }
      else {
 	 if (VIA_DEBUG & DEBUG_TEXTURE)
	    fprintf(stderr, "Heap %d: nothing to do\n", heap);
	 continue;
      }

      foreach_s( s, tmp, &vmesa->tex_image_list[heap] ) {
	 if (s->lastUsed < vmesa->lastSwap[1]) {
	    struct via_texture_object *viaObj = 
	       (struct via_texture_object *) s->image->image.TexObject;

	    if (VIA_DEBUG & DEBUG_TEXTURE)
	       fprintf(stderr, 
		       "back copy tex sz %d, lastUsed %d lastSwap %d\n", 
		       s->size, s->lastUsed, vmesa->lastSwap[1]);

	    if (viaMoveTexBuffers( vmesa, &s, 1, VIA_MEM_SYSTEM )) {
	       viaObj->memType = VIA_MEM_MIXED;
	       done += s->size;
	    }
	    else {
	       if (VIA_DEBUG & DEBUG_TEXTURE)
		  fprintf(stderr, "Failed to back copy texture!\n");
	       sz += s->size;
	    }
	 }
	 else {
	    nr ++;
	    sz += s->size;
	 }

	 if (done > target) {
	    vmesa->thrashing = GL_FALSE; /* might not get set otherwise? */
	    return GL_TRUE;
	 }
      }

      assert(sz == vmesa->total_alloc[heap]);
	 
      if (VIA_DEBUG & DEBUG_TEXTURE)
	 fprintf(stderr, "Heap %d: nr %d tot sz %d\n", heap, nr, sz);
   }

   
   return done != 0;
}



/* Basically, just collect the image dimensions and addresses for each
 * image and update the texture object state accordingly.
 */
static GLboolean viaSetTexImages(GLcontext *ctx,
				 struct gl_texture_object *texObj)
{
   struct via_context *vmesa = VIA_CONTEXT(ctx);
   struct via_texture_object *viaObj = (struct via_texture_object *)texObj;
   const struct via_texture_image *baseImage = 
      (struct via_texture_image *)texObj->Image[0][texObj->BaseLevel];
   GLint firstLevel, lastLevel, numLevels;
   GLuint texFormat;
   GLint w, h, p;
   GLint i, j = 0, k = 0, l = 0, m = 0;
   GLuint texBase;
   GLuint basH = 0;
   GLuint widthExp = 0;
   GLuint heightExp = 0;    

   switch (baseImage->image.TexFormat->MesaFormat) {
   case MESA_FORMAT_ARGB8888:
      texFormat = HC_HTXnFM_ARGB8888;
      break;
   case MESA_FORMAT_ARGB4444:
      texFormat = HC_HTXnFM_ARGB4444; 
      break;
   case MESA_FORMAT_RGB565:
      texFormat = HC_HTXnFM_RGB565;   
      break;
   case MESA_FORMAT_ARGB1555:
      texFormat = HC_HTXnFM_ARGB1555;   
      break;
   case MESA_FORMAT_RGB888:
      texFormat = HC_HTXnFM_ARGB0888;
      break;
   case MESA_FORMAT_L8:
      texFormat = HC_HTXnFM_L8;       
      break;
   case MESA_FORMAT_I8:
      texFormat = HC_HTXnFM_T8;       
      break;
   case MESA_FORMAT_CI8:
      texFormat = HC_HTXnFM_Index8;   
      break;
   case MESA_FORMAT_AL88:
      texFormat = HC_HTXnFM_AL88;     
      break;
   case MESA_FORMAT_A8:
      texFormat = HC_HTXnFM_A8;     
      break;
   default:
      _mesa_problem(vmesa->glCtx, "Bad texture format in viaSetTexImages");
      return GL_FALSE;
   }

   /* Compute which mipmap levels we really want to send to the hardware.
    * This depends on the base image size, GL_TEXTURE_MIN_LOD,
    * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
    * Yes, this looks overly complicated, but it's all needed.
    */
   if (texObj->MinFilter == GL_LINEAR || texObj->MinFilter == GL_NEAREST) {
      firstLevel = lastLevel = texObj->BaseLevel;
   }
   else {
      firstLevel = texObj->BaseLevel + (GLint)(texObj->MinLod + 0.5);
      firstLevel = MAX2(firstLevel, texObj->BaseLevel);
      lastLevel = texObj->BaseLevel + (GLint)(texObj->MaxLod + 0.5);
      lastLevel = MAX2(lastLevel, texObj->BaseLevel);
      lastLevel = MIN2(lastLevel, texObj->BaseLevel + baseImage->image.MaxLog2);
      lastLevel = MIN2(lastLevel, texObj->MaxLevel);
      lastLevel = MAX2(firstLevel, lastLevel);     /* need at least one level */
   }

   numLevels = lastLevel - firstLevel + 1;

   /* The hardware supports only 10 mipmap levels; ignore higher levels.
    */
   if ((numLevels > 10) && (ctx->Const.MaxTextureLevels > 10)) {
       lastLevel -= numLevels - 10;
       numLevels = 10;
   }

   /* save these values, check if they effect the residency of the
    * texture:
    */
   if (viaObj->firstLevel != firstLevel ||
       viaObj->lastLevel != lastLevel) {
      viaObj->firstLevel = firstLevel;
      viaObj->lastLevel = lastLevel;
      viaObj->memType = VIA_MEM_MIXED;
   }

   if (VIA_DEBUG & DEBUG_TEXTURE & 0)
      fprintf(stderr, "%s, current memType: %s\n",
	      __FUNCTION__,
	      get_memtype_name(viaObj->memType));

   
   if (viaObj->memType == VIA_MEM_MIXED ||
       viaObj->memType == VIA_MEM_SYSTEM) {
      if (!viaSwapInTexObject(vmesa, viaObj)) {
 	 if (VIA_DEBUG & DEBUG_TEXTURE) 
	    if (!vmesa->thrashing)
	       fprintf(stderr, "Thrashing flag set for frame %d\n", 
		       vmesa->swap_count);
	 vmesa->thrashing = GL_TRUE;
	 return GL_FALSE;
      }
   }

   if (viaObj->memType == VIA_MEM_AGP)
      viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_AGP | texFormat;
   else
      viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_Local | texFormat;


   for (i = 0; i < numLevels; i++) {    
      struct via_texture_image *viaImage = 
	 (struct via_texture_image *)texObj->Image[0][firstLevel + i];

      w = viaImage->image.WidthLog2;
      h = viaImage->image.HeightLog2;
      p = viaImage->pitchLog2;

      assert(viaImage->texMem->memType == viaObj->memType);

      texBase = viaImage->texMem->texBase;
      if (!texBase) {
	 if (VIA_DEBUG & DEBUG_TEXTURE)
	    fprintf(stderr, "%s: no texBase[%d]\n", __FUNCTION__, i); 
	 return GL_FALSE;
      }

      /* Image has to remain resident until the coming fence is retired.
       */
      move_to_head( &vmesa->tex_image_list[viaImage->texMem->memType],
		    viaImage->texMem );
      viaImage->texMem->lastUsed = vmesa->lastBreadcrumbWrite;


      viaObj->regTexBaseAndPitch[i].baseL = 
	 ((HC_SubA_HTXnL0BasL + i) << 24) | (texBase & 0xFFFFFF);

      viaObj->regTexBaseAndPitch[i].pitchLog2 = 
	 ((HC_SubA_HTXnL0Pit + i) << 24) | (p << 20);
					      
					      
      /* The base high bytes for each 3 levels are packed
       * together into one register:
       */
      j = i / 3;
      k = 3 - (i % 3);
      basH |= ((texBase & 0xFF000000) >> (k << 3));
      if (k == 1) {
	 viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
	 basH = 0;
      }
            
      /* Likewise, sets of 6 log2width and log2height values are
       * packed into individual registers:
       */
      l = i / 6;
      m = i % 6;
      widthExp |= (((GLuint)w & 0xF) << (m << 2));
      heightExp |= (((GLuint)h & 0xF) << (m << 2));
      if (m == 5) {
	 viaObj->regTexWidthLog2[l] = 
	    (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;
	 viaObj->regTexHeightLog2[l] = 
	    (l + HC_SubA_HTXnL0_5HE) << 24 | heightExp;
	 widthExp = 0;
	 heightExp = 0;
      }
      if (w) w--;
      if (h) h--;
      if (p) p--;                                           
   }
        
   if (k != 1) {
      viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;      
   }
   if (m != 5) {
      viaObj->regTexWidthLog2[l] = (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;
      viaObj->regTexHeightLog2[l] = (l + HC_SubA_HTXnL0_5HE) << 24 | heightExp;
   }

   return GL_TRUE;
}


GLboolean viaUpdateTextureState( GLcontext *ctx )
{
   struct gl_texture_unit *texUnit = ctx->Texture.Unit;
   GLuint i;

   for (i = 0; i < 2; i++) {   
      if (texUnit[i]._ReallyEnabled == TEXTURE_2D_BIT || 
	  texUnit[i]._ReallyEnabled == TEXTURE_1D_BIT) {

	 if (!viaSetTexImages(ctx, texUnit[i]._Current)) 
	    return GL_FALSE;
      }
      else if (texUnit[i]._ReallyEnabled) {
	 return GL_FALSE;
      } 
   }
   
   return GL_TRUE;
}





				 


static void viaTexImage(GLcontext *ctx, 
			GLint dims,
			GLenum target, GLint level,
			GLint internalFormat,
			GLint width, GLint height, GLint border,
			GLenum format, GLenum type, const void *pixels,
			const struct gl_pixelstore_attrib *packing,
			struct gl_texture_object *texObj,
			struct gl_texture_image *texImage)
{
   struct via_context *vmesa = VIA_CONTEXT(ctx);
   GLint postConvWidth = width;
   GLint postConvHeight = height;
   GLint texelBytes, sizeInBytes;
   struct via_texture_object *viaObj = (struct via_texture_object *)texObj;
   struct via_texture_image *viaImage = (struct via_texture_image *)texImage;
   int heaps[3], nheaps, i;

   if (!is_empty_list(&vmesa->freed_tex_buffers)) {
      viaCheckBreadcrumb(vmesa, 0);
      via_release_pending_textures(vmesa);
   }

   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
                                         &postConvHeight);
   }

   /* choose the texture format */
   texImage->TexFormat = viaChooseTexFormat(ctx, internalFormat, 
					    format, type);

   assert(texImage->TexFormat);

   if (dims == 1) {
      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
   }
   else {
      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
   }
   texelBytes = texImage->TexFormat->TexelBytes;

   if (texelBytes == 0) {
      /* compressed format */
      texImage->IsCompressed = GL_TRUE;
      texImage->CompressedSize =
         ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
                                           texImage->Height, texImage->Depth,
                                           texImage->TexFormat->MesaFormat);
   }

   /* Minimum pitch of 32 bytes */
   if (postConvWidth * texelBytes < 32) {
      postConvWidth = 32 / texelBytes;
      texImage->RowStride = postConvWidth;
   }

   assert(texImage->RowStride == postConvWidth);
   viaImage->pitchLog2 = logbase2(postConvWidth * texelBytes);

   /* allocate memory */
   if (texImage->IsCompressed)
      sizeInBytes = texImage->CompressedSize;
   else
      sizeInBytes = postConvWidth * postConvHeight * texelBytes;


   /* Attempt to allocate texture memory directly, otherwise use main
    * memory and this texture will always be a fallback.   FIXME!
    *
    * TODO: make room in agp if this fails.
    * TODO: use fb ram for textures as well.
    */
   
      
   switch (viaObj->memType) {
   case VIA_MEM_UNKNOWN:
      heaps[0] = VIA_MEM_AGP;
      heaps[1] = VIA_MEM_VIDEO;
      heaps[2] = VIA_MEM_SYSTEM;
      nheaps = 3;
      break;
   case VIA_MEM_AGP:
   case VIA_MEM_VIDEO:
      heaps[0] = viaObj->memType;
      heaps[1] = VIA_MEM_SYSTEM;
      nheaps = 2;
      break;
   case VIA_MEM_MIXED:
   case VIA_MEM_SYSTEM:
   default:
      heaps[0] = VIA_MEM_SYSTEM;
      nheaps = 1;
      break;
   }
	
   for (i = 0; i < nheaps && !viaImage->texMem; i++) {
      if (VIA_DEBUG & DEBUG_TEXTURE) 
	 fprintf(stderr, "try %s (obj %s)\n", get_memtype_name(heaps[i]),
		 get_memtype_name(viaObj->memType));
      viaImage->texMem = via_alloc_texture(vmesa, sizeInBytes, heaps[i]);
   }

   if (!viaImage->texMem) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
      return;
   }

   if (VIA_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "upload %d bytes to %s\n", sizeInBytes, 
	      get_memtype_name(viaImage->texMem->memType));

   viaImage->texMem->image = viaImage;
   texImage->Data = viaImage->texMem->bufAddr;

   if (viaObj->memType == VIA_MEM_UNKNOWN)
      viaObj->memType = viaImage->texMem->memType;
   else if (viaObj->memType != viaImage->texMem->memType)
      viaObj->memType = VIA_MEM_MIXED;

   if (VIA_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "%s, obj %s, image : %s\n",
	      __FUNCTION__,	      
	      get_memtype_name(viaObj->memType),
	      get_memtype_name(viaImage->texMem->memType));

   vmesa->clearTexCache = 1;

   pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 
					format, type,
					pixels, packing, "glTexImage");
   if (!pixels) {
      /* Note: we check for a NULL image pointer here, _after_ we allocated
       * memory for the texture.  That's what the GL spec calls for.
       */
      return;
   }
   else {
      GLint dstRowStride;
      GLboolean success;
      if (texImage->IsCompressed) {
         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
      }
      else {
         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
      }
      ASSERT(texImage->TexFormat->StoreImage);
      success = texImage->TexFormat->StoreImage(ctx, dims,
                                                texImage->_BaseFormat,
                                                texImage->TexFormat,
                                                texImage->Data,
                                                0, 0, 0,  /* dstX/Y/Zoffset */
                                                dstRowStride,
                                                texImage->ImageOffsets,
                                                width, height, 1,
                                                format, type, pixels, packing);
      if (!success) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
      }
   }

   /* GL_SGIS_generate_mipmap */
   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
      _mesa_generate_mipmap(ctx, target, texObj);
   }

   _mesa_unmap_teximage_pbo(ctx, packing);
}

static void viaTexImage2D(GLcontext *ctx, 
			  GLenum target, GLint level,
			  GLint internalFormat,
			  GLint width, GLint height, GLint border,
			  GLenum format, GLenum type, const void *pixels,
			  const struct gl_pixelstore_attrib *packing,
			  struct gl_texture_object *texObj,
			  struct gl_texture_image *texImage)
{
   viaTexImage( ctx, 2, target, level, 
		internalFormat, width, height, border,
		format, type, pixels,
		packing, texObj, texImage );
}

static void viaTexSubImage2D(GLcontext *ctx,
                             GLenum target,
                             GLint level,
                             GLint xoffset, GLint yoffset,
                             GLsizei width, GLsizei height,
                             GLenum format, GLenum type,
                             const GLvoid *pixels,
                             const struct gl_pixelstore_attrib *packing,
                             struct gl_texture_object *texObj,
                             struct gl_texture_image *texImage)
{
   struct via_context *vmesa = VIA_CONTEXT(ctx);
  
   viaWaitIdle(vmesa, GL_TRUE);
   vmesa->clearTexCache = 1;

   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
			     height, format, type, pixels, packing, texObj,
			     texImage);
}

static void viaTexImage1D(GLcontext *ctx, 
			  GLenum target, GLint level,
			  GLint internalFormat,
			  GLint width, GLint border,
			  GLenum format, GLenum type, const void *pixels,
			  const struct gl_pixelstore_attrib *packing,
			  struct gl_texture_object *texObj,
			  struct gl_texture_image *texImage)
{
   viaTexImage( ctx, 1, target, level, 
		internalFormat, width, 1, border,
		format, type, pixels,
		packing, texObj, texImage );
}

static void viaTexSubImage1D(GLcontext *ctx,
                             GLenum target,
                             GLint level,
                             GLint xoffset,
                             GLsizei width,
                             GLenum format, GLenum type,
                             const GLvoid *pixels,
                             const struct gl_pixelstore_attrib *packing,
                             struct gl_texture_object *texObj,
                             struct gl_texture_image *texImage)
{
   struct via_context *vmesa = VIA_CONTEXT(ctx);

   viaWaitIdle(vmesa, GL_TRUE); 
   vmesa->clearTexCache = 1;

   _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
			     format, type, pixels, packing, texObj,
			     texImage);
}



static GLboolean viaIsTextureResident(GLcontext *ctx,
                                      struct gl_texture_object *texObj)
{
   struct via_texture_object *viaObj = 
      (struct via_texture_object *)texObj;

   return (viaObj->memType == VIA_MEM_AGP ||
	   viaObj->memType == VIA_MEM_VIDEO);
}



static struct gl_texture_image *viaNewTextureImage( GLcontext *ctx )
{
   (void) ctx;
   return (struct gl_texture_image *)CALLOC_STRUCT(via_texture_image);
}


static struct gl_texture_object *viaNewTextureObject( GLcontext *ctx, 
						      GLuint name, 
						      GLenum target )
{
   struct via_texture_object *obj = CALLOC_STRUCT(via_texture_object);

   _mesa_initialize_texture_object(&obj->obj, name, target);
   (void) ctx;

   obj->memType = VIA_MEM_UNKNOWN;

   return &obj->obj;
}


static void viaFreeTextureImageData( GLcontext *ctx, 
				     struct gl_texture_image *texImage )
{
   struct via_context *vmesa = VIA_CONTEXT(ctx);
   struct via_texture_image *image = (struct via_texture_image *)texImage;

   if (image->texMem) {
      via_free_texture(vmesa, image->texMem);
      image->texMem = NULL;
   }
   
   texImage->Data = NULL;
}




void viaInitTextureFuncs(struct dd_function_table * functions)
{
   functions->ChooseTextureFormat = viaChooseTexFormat;
   functions->TexImage1D = viaTexImage1D;
   functions->TexImage2D = viaTexImage2D;
   functions->TexSubImage1D = viaTexSubImage1D;
   functions->TexSubImage2D = viaTexSubImage2D;

   functions->NewTextureObject = viaNewTextureObject;
   functions->NewTextureImage = viaNewTextureImage;
   functions->DeleteTexture = _mesa_delete_texture_object;
   functions->FreeTexImageData = viaFreeTextureImageData;

#if 0 && defined( USE_SSE_ASM )
   /*
    * XXX this code is disabled for now because the via_sse_memcpy()
    * routine causes segfaults with flightgear.
    * See Mesa3d-dev mail list messages from 7/15/2005 for details.
    * Note that this function is currently disabled in via_tris.c too.
    */
   if (getenv("VIA_NO_SSE"))
      functions->TextureMemCpy = _mesa_memcpy;
   else
      functions->TextureMemCpy = via_sse_memcpy;
#else
   functions->TextureMemCpy = _mesa_memcpy;
#endif

   functions->UpdateTexturePalette = 0;
   functions->IsTextureResident = viaIsTextureResident;
}


