Remove CVS keywords.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texmem.c
index 235df8dcd1a4ab60d7b64017812831c3d393c0b3..f7520f1dea32e05d844fe360fa5a3578a1c5638b 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c,v 1.7 2002/12/16 16:18:59 dawes Exp $ */
 /**************************************************************************
 
 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
@@ -41,12 +40,13 @@ SOFTWARE.
 #include "imports.h"
 #include "context.h"
 #include "macros.h"
-#include "simple_list.h"
 
 #include "radeon_context.h"
 #include "radeon_ioctl.h"
 #include "radeon_tex.h"
 
+#include <unistd.h>  /* for usleep() */
+
 
 /**
  * Destroy any device-dependent state associated with the texture.  This may
@@ -66,8 +66,6 @@ radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
       for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) {
         if ( t == rmesa->state.texture.unit[i].texobj ) {
            rmesa->state.texture.unit[i].texobj = NULL;
-           remove_from_list( &rmesa->hw.tex[i] );
-           make_empty_list( &rmesa->hw.tex[i] );
         }
       }
    }
@@ -153,12 +151,12 @@ static void radeonUploadRectSubImage( radeonContextPtr rmesa,
 
         /* Blit to framebuffer
          */
-        radeonEmitBlit( rmesa, 
-                      blit_format, 
-                      dstPitch, GET_START( &region ),    
-                      dstPitch, t->bufAddr, 
-                      0, 0, 
-                      0, done, 
+        radeonEmitBlit( rmesa,
+                      blit_format,
+                      dstPitch, GET_START( &region ),
+                      dstPitch, t->bufAddr,
+                      0, 0,
+                      0, done,
                       width, lines );
         
         radeonEmitWait( rmesa, RADEON_WAIT_2D );
@@ -226,7 +224,7 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t,
    imageWidth = texImage->Width;
    imageHeight = texImage->Height;
 
-   offset = t->bufAddr;
+   offset = t->bufAddr + t->base.totalSize * face / 6;
 
    if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
       GLint imageX = 0;
@@ -250,30 +248,61 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t,
     * We used to use 1, 2 and 4-byte texels and used to use the texture
     * width to dictate the blit width - but that won't work for compressed
     * textures. (Brian)
+    * NOTE: can't do that with texture tiling. (sroland)
     */
    tex.offset = offset;
-   tex.pitch = BLIT_WIDTH_BYTES / 64;
-   tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
+   tex.image = &tmp;
+   /* copy (x,y,width,height,data) */
+   memcpy( &tmp, &t->image[face][hwlevel], sizeof(drm_radeon_tex_image_t) );
+
    if (texImage->TexFormat->TexelBytes) {
-      tex.width = imageWidth * texImage->TexFormat->TexelBytes; /* in bytes */
+      /* use multi-byte upload scheme */
       tex.height = imageHeight;
+      tex.width = imageWidth;
+      tex.format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK;
+      tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
+      tex.offset += tmp.x & ~1023;
+      tmp.x = tmp.x % 1024;
+      if (t->tile_bits & RADEON_TXO_MICRO_TILE_X2) {
+        /* need something like "tiled coordinates" ? */
+        tmp.y = tmp.x / (tex.pitch * 128) * 2;
+        tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
+        tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
+      }
+      else {
+        tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
+      }
+      if ((t->tile_bits & RADEON_TXO_MACRO_TILE) &&
+        (texImage->Width * texImage->TexFormat->TexelBytes >= 256)) {
+        /* radeon switches off macro tiling for small textures/mipmaps it seems */
+        tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
+      }
    }
    else {
-      tex.width = imageWidth; /* compressed */
-      tex.height = imageHeight;
-      if (tex.height < 4)
-         tex.height = 4;
+      /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is
+         needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
+      /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed
+         so the kernel module reads the right amount of data. */
+      tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
+      tex.pitch = (BLIT_WIDTH_BYTES / 64);
+      tex.height = (imageHeight + 3) / 4;
+      tex.width = (imageWidth + 3) / 4;
+      switch (t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) {
+      case RADEON_TXFORMAT_DXT1:
+         tex.width *= 8;
+         break;
+      case RADEON_TXFORMAT_DXT23:
+      case RADEON_TXFORMAT_DXT45:
+         tex.width *= 16;
+         break;
+      }
    }
-   tex.image = &tmp;
-
-   /* copy (x,y,width,height,data) */
-   memcpy( &tmp, &t->image[face][hwlevel], sizeof(drm_radeon_tex_image_t) );
 
    LOCK_HARDWARE( rmesa );
    do {
       ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE,
                                  &tex, sizeof(drm_radeon_texture_t) );
-   } while ( ret && errno == EAGAIN );
+   } while ( ret == -EAGAIN );
 
    UNLOCK_HARDWARE( rmesa );
 
@@ -302,7 +331,10 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t,
 
 int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint face )
 {
-   const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
+   int numLevels;
+
+   if ( !t || t->base.totalSize == 0 )
+      return 0;
 
    if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
       fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
@@ -310,8 +342,12 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint fac
               t->base.firstLevel, t->base.lastLevel );
    }
 
-   if ( !t || t->base.totalSize == 0 )
-      return 0;
+   numLevels = t->base.lastLevel - t->base.firstLevel + 1;
+
+   if (RADEON_DEBUG & DEBUG_SYNC) {
+      fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );
+      radeonFinish( rmesa->glCtx );
+   }
 
    LOCK_HARDWARE( rmesa );
 
@@ -330,6 +366,10 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint fac
           + t->base.memBlock->ofs;
       t->pp_txoffset = t->bufAddr;
 
+      if (!(t->base.tObj->Image[0][0]->IsClientData)) {
+        /* hope it's safe to add that here... */
+        t->pp_txoffset |= t->tile_bits;
+      }
 
       /* Mark this texobj as dirty on all units:
        */
@@ -355,5 +395,10 @@ int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint fac
       t->base.dirty_images[face] = 0;
    }
 
+   if (RADEON_DEBUG & DEBUG_SYNC) {
+      fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );
+      radeonFinish( rmesa->glCtx );
+   }
+
    return 0;
 }