fix up radeon span functions using latest r200 code from Brian,
[mesa.git] / src / mesa / drivers / dri / r200 / r200_texmem.c
index 473520a9507870b4f213c0a93712bf1e4c634da5..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() */
 
@@ -73,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;
         }
       }
    }
@@ -256,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 );
@@ -286,8 +282,8 @@ 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 ) {
@@ -342,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;
@@ -361,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 );
 
@@ -455,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:
        */