fix up radeon span functions using latest r200 code from Brian,
[mesa.git] / src / mesa / drivers / dri / r200 / r200_texmem.c
index 34db1f4421eb7a174260704a0648ecd15d092ab6..14ee8238ad86d487a9e06952b45caadd1ae5c845 100644 (file)
@@ -43,13 +43,10 @@ SOFTWARE.
 #include "context.h"
 #include "colormac.h"
 #include "macros.h"
-#include "simple_list.h"
-#include "radeon_reg.h" /* gets definition for usleep */
 #include "r200_context.h"
-#include "r200_state.h"
 #include "r200_ioctl.h"
-#include "r200_swtcl.h"
 #include "r200_tex.h"
+#include "radeon_reg.h"
 
 #include <unistd.h>  /* for usleep() */
 
@@ -62,7 +59,8 @@ void
 r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t )
 {
    if ( R200_DEBUG & DEBUG_TEXTURE ) {
-      fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->base.tObj );
+      fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, 
+              (void *)t, (void *)t->base.tObj );
    }
 
    if ( rmesa != NULL ) {
@@ -72,10 +70,8 @@ r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr 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] );
-           remove_from_list( &rmesa->hw.cube[i] );
-           make_empty_list( &rmesa->hw.cube[i] );
+           rmesa->hw.tex[i].dirty = GL_FALSE;
+           rmesa->hw.cube[i].dirty = GL_FALSE;
         }
       }
    }
@@ -230,7 +226,7 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa,
         tex = (char *)texImage->Data + done * src_pitch;
 
         memset(&region, 0, sizeof(region));
-        r200AllocDmaRegion( rmesa, &region, lines * dstPitch, 64 );
+        r200AllocDmaRegion( rmesa, &region, lines * dstPitch, 1024 );
 
         /* Copy texdata to dma:
          */
@@ -239,10 +235,10 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa,
                    __FUNCTION__, src_pitch, dstPitch);
 
         if (src_pitch == dstPitch) {
-           memcpy( region.address, tex, lines * src_pitch );
+           memcpy( region.address + region.start, tex, lines * src_pitch );
         } 
         else {
-           char *buf = region.address;
+           char *buf = region.address + region.start;
            int i;
            for (i = 0 ; i < lines ; i++) {
               memcpy( buf, tex, src_pitch );
@@ -255,12 +251,13 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa,
 
         /* Blit to framebuffer
          */
-        r200EmitBlit( rmesa, 
-                      blit_format, 
-                      dstPitch, GET_START( &region ),   
-                      dstPitch, t->bufAddr,
-                      0, 0, 
-                      0, done, 
+        r200EmitBlit( rmesa,
+                      blit_format,
+                      dstPitch, GET_START( &region ),
+                      dstPitch | (t->tile_bits >> 16),
+                      t->bufAddr,
+                      0, 0,
+                      0, done,
                       width, lines );
         
         r200EmitWait( rmesa, RADEON_WAIT_2D );
@@ -285,13 +282,14 @@ static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t,
    GLuint offset;
    GLint imageWidth, imageHeight;
    GLint ret;
-   drmRadeonTexture tex;
-   drmRadeonTexImage tmp;
+   drm_radeon_texture_t tex;
+   drm_radeon_tex_image_t tmp;
    const int level = hwlevel + t->base.firstLevel;
 
    if ( R200_DEBUG & DEBUG_TEXTURE ) {
       fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", 
-              __FUNCTION__, t, t->base.tObj, level, width, height, face );
+              __FUNCTION__, (void *)t, (void *)t->base.tObj,
+              level, width, height, face );
    }
 
    ASSERT(face < 6);
@@ -302,26 +300,7 @@ static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t,
       return;
    }
 
-   switch (face) {
-   case 0:
-      texImage = t->base.tObj->Image[level];
-      break;
-   case 1:
-      texImage = t->base.tObj->NegX[level];
-      break;
-   case 2:
-      texImage = t->base.tObj->PosY[level];
-      break;
-   case 3:
-      texImage = t->base.tObj->NegY[level];
-      break;
-   case 4:
-      texImage = t->base.tObj->PosZ[level];
-      break;
-   case 5:
-      texImage = t->base.tObj->NegZ[level];
-      break;
-   }
+   texImage = t->base.tObj->Image[face][level];
 
    if ( !texImage ) {
       if ( R200_DEBUG & DEBUG_TEXTURE )
@@ -359,7 +338,7 @@ static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t,
    imageWidth = texImage->Width;
    imageHeight = texImage->Height;
 
-   offset = t->bufAddr;
+   offset = t->bufAddr + t->base.totalSize / 6 * face;
 
    if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
       GLint imageX = 0;
@@ -378,40 +357,77 @@ static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t,
 
    t->image[face][hwlevel].data = texImage->Data;
 
-   /* Init the DRM_RADEON_TEXTURE command / drmRadeonTexture struct.
+   /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
     * NOTE: we're always use a 1KB-wide blit and I8 texture format.
     * 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 = R200_TXFORMAT_I8; /* any 1-byte texel format */
+   tex.image = &tmp;
+   /* copy (x,y,width,height,data) */
+   memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
+   
    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 & R200_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 & R200_TXO_MICRO_TILE) {
+        /* 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 & R200_TXO_MACRO_TILE) &&
+        (texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
+        ((!(t->tile_bits & R200_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
+           (texImage->Height >= 16))) {
+        /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
+           OR if height is smaller than 8 automatically, but if micro tiling is active
+           the limit is height 16 instead ? */
+        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 = R200_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 & R200_TXFORMAT_FORMAT_MASK) {
+      case R200_TXFORMAT_DXT1:
+           tex.width *= 8;
+           break;
+      case R200_TXFORMAT_DXT23:
+      case R200_TXFORMAT_DXT45:
+           tex.width *= 16;
+           break;
+      default:
+          fprintf(stderr, "unknown compressed tex format in uploadSubImage\n");
+      }
    }
-   tex.image = &tmp;
-
-   /* copy (x,y,width,height,data) */
-   memcpy( &tmp, &t->image[face][hwlevel], sizeof(drmRadeonTexImage) );
 
    LOCK_HARDWARE( rmesa );
    do {
       ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE,
-                                 &tex, sizeof(drmRadeonTexture) );
+                                 &tex, sizeof(drm_radeon_texture_t) );
       if (ret) {
         if (R200_DEBUG & DEBUG_IOCTL)
            fprintf(stderr, "DRM_RADEON_TEXTURE:  again!\n");
         usleep(1);
       }
-   } while ( ret && errno == EAGAIN );
+   } while ( ret == -EAGAIN );
 
    UNLOCK_HARDWARE( rmesa );
 
@@ -444,7 +460,7 @@ int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face )
 
    if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
       fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
-              rmesa->glCtx, t->base.tObj, t->base.totalSize,
+              (void *)rmesa->glCtx, (void *)t->base.tObj, t->base.totalSize,
               t->base.firstLevel, t->base.lastLevel );
    }
 
@@ -472,7 +488,11 @@ int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face )
       t->bufAddr = rmesa->r200Screen->texOffset[heap] 
           + 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:
        */