Add GL_ARB_texture_cube_map support for i830. Most of the code was
authorIan Romanick <idr@us.ibm.com>
Sun, 19 Sep 2004 08:03:46 +0000 (08:03 +0000)
committerIan Romanick <idr@us.ibm.com>
Sun, 19 Sep 2004 08:03:46 +0000 (08:03 +0000)
lifted from the i915 side.  i830 will now report version 1.3!  Hurrah!
With the exception of GL_EXT_texture_compression_s3tc, the i830 driver
now supports all the extensions that its Windows counterpart supports.

src/mesa/drivers/dri/i915/i830_context.c
src/mesa/drivers/dri/i915/i830_context.h
src/mesa/drivers/dri/i915/i830_reg.h
src/mesa/drivers/dri/i915/i830_texstate.c
src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_context.c
src/mesa/drivers/dri/i915/intel_context.c

index 2c81e3d..fc63386 100644 (file)
@@ -99,7 +99,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis,
                                 4,
                                 11, /* max 2D texture size is 2048x2048 */
                                 8,  /* max 3D texture size is 256^3 */
-                                0,  /* max CUBE. not supported */
+                                10, /* max CUBE texture size is 1024x1024 */
                                 11, /* max RECT. supported */
                                 12,
                                 GL_FALSE );
index 48eb704..62e20d0 100644 (file)
@@ -89,8 +89,9 @@
 #define I830_TEXREG_TM0S2      3
 #define I830_TEXREG_TM0S3      4
 #define I830_TEXREG_TM0S4      5
-#define I830_TEXREG_MCS              6 /* _3DSTATE_MAP_COORD_SETS */
-#define I830_TEX_SETUP_SIZE    7
+#define I830_TEXREG_MCS               6        /* _3DSTATE_MAP_COORD_SETS */
+#define I830_TEXREG_CUBE       7       /* _3DSTATE_MAP_SUBE */
+#define I830_TEX_SETUP_SIZE    8
 
 #define I830_TEXBLEND_SIZE     12      /* (4 args + op) * 2 + COLOR_FACTOR */
 
index 69dc333..b931a6b 100644 (file)
 
 #define TM0S2_PITCH_SHIFT               21
 #define TM0S2_CUBE_FACE_ENA_SHIFT       15
+#define TM0S2_CUBE_FACE_ENA_MASK        (1<<15)
 #define TM0S2_MAP_FORMAT                (1<<14)
 #define TM0S2_VERTICAL_LINE_STRIDE      (1<<13)
 #define TM0S2_VERITCAL_LINE_STRIDE_OFF  (1<<12)
index 39ba0b8..a393fd1 100644 (file)
 #include "i830_context.h"
 #include "i830_reg.h"
 
+static const GLint initial_offsets[6][2] = { {0,0},
+                                      {0,2},
+                                      {1,0},
+                                      {1,2},
+                                      {1,1},
+                                      {1,3} };
+
+static const GLint step_offsets[6][2] = { {0,2},
+                                   {0,2},
+                                   {-1,2},
+                                   {-1,2},
+                                   {-1,1},
+                                   {-1,1} };
 
 #define I830_TEX_UNIT_ENABLED(unit)            (1<<unit)
 
@@ -133,39 +146,72 @@ static GLboolean i830SetTexImages( i830ContextPtr i830,
    lastLevel = t->intel.base.lastLevel;
    numLevels = lastLevel - firstLevel + 1;
 
-   /* Pitch would be subject to additional rules if texture memory were
-    * tiled.  Currently it isn't. 
-    */
-   if (0) {
-      pitch = 128;
-      while (pitch < tObj->Image[0][firstLevel]->Width * t->intel.texelBytes)
-        pitch *= 2;
-   }
-   else {
-      pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
-      pitch = (pitch + 3) & ~3;
-   }
-
 
    /* All images must be loaded at this pitch.  Count the number of
     * lines required:
     */
-   for ( total_height = i = 0 ; i < numLevels ; i++ ) {
-      t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
-      if (!t->intel.image[0][i].image) 
-        break;
+   switch (tObj->Target) {
+   case GL_TEXTURE_CUBE_MAP: {
+      const GLuint dim = tObj->Image[0][firstLevel]->Width;
+      GLuint face;
+
+      pitch = dim * t->intel.texelBytes;
+      pitch *= 2;              /* double pitch for cube layouts */
+      pitch = (pitch + 3) & ~3;
       
-      t->intel.image[0][i].offset = total_height * pitch;
-      t->intel.image[0][i].internalFormat = baseImage->Format;
-      if (t->intel.image[0][i].image->IsCompressed)
-       {
-         if (t->intel.image[0][i].image->Height > 4)
-           total_height += t->intel.image[0][i].image->Height/4;
-         else
-           total_height += 1;
-       }
-      else
-       total_height += MAX2(2, t->intel.image[0][i].image->Height);
+      total_height = dim * 4;
+
+      for ( face = 0 ; face < 6 ; face++) {
+        GLuint x = initial_offsets[face][0] * dim;
+        GLuint y = initial_offsets[face][1] * dim;
+        GLuint d = dim;
+        
+        t->intel.base.dirty_images[face] = ~0;
+
+        assert(tObj->Image[face][firstLevel]->Width == dim);
+        assert(tObj->Image[face][firstLevel]->Height == dim);
+
+        for (i = 0; i < numLevels; i++) {
+           t->intel.image[face][i].image = tObj->Image[face][firstLevel + i];
+           if (!t->intel.image[face][i].image) {
+              fprintf(stderr, "no image %d %d\n", face, i);
+              break;           /* can't happen */
+           }
+        
+           t->intel.image[face][i].offset = 
+              y * pitch + x * t->intel.texelBytes;
+           t->intel.image[face][i].internalFormat = baseImage->Format;
+
+           d >>= 1;
+           x += step_offsets[face][0] * d;
+           y += step_offsets[face][1] * d;
+        }
+      }
+      break;
+   }
+   default:
+      pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
+      pitch = (pitch + 3) & ~3;
+      t->intel.base.dirty_images[0] = ~0;
+
+      for ( total_height = i = 0 ; i < numLevels ; i++ ) {
+        t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
+        if (!t->intel.image[0][i].image) 
+           break;
+        
+        t->intel.image[0][i].offset = total_height * pitch;
+        t->intel.image[0][i].internalFormat = baseImage->Format;
+        if (t->intel.image[0][i].image->IsCompressed)
+        {
+          if (t->intel.image[0][i].image->Height > 4)
+            total_height += t->intel.image[0][i].image->Height/4;
+          else
+            total_height += 1;
+        }
+        else
+          total_height += MAX2(2, t->intel.image[0][i].image->Height);
+      }
+      break;
    }
 
    t->intel.Pitch = pitch;
@@ -176,7 +222,8 @@ static GLboolean i830SetTexImages( i830ContextPtr i830,
        ((tObj->Image[0][firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) |
        textureFormat);
    t->Setup[I830_TEXREG_TM0S2] = 
-      (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT);
+      (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) |
+      TM0S2_CUBE_FACE_ENA_MASK;
    t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK;
    t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK;
    t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT;
@@ -216,6 +263,7 @@ static void i830_import_tex_unit( i830ContextPtr i830,
    i830->state.Tex[unit][I830_TEXREG_TM0S4] = t->Setup[I830_TEXREG_TM0S4];
    i830->state.Tex[unit][I830_TEXREG_MCS] = (t->Setup[I830_TEXREG_MCS] & 
                                             ~MAP_UNIT_MASK);   
+   i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE];
    i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit);
 
    t->intel.dirty &= ~I830_UPLOAD_TEX(unit);
@@ -267,9 +315,11 @@ static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
    mcs &= ~TEXCOORDS_ARE_NORMAL;
    mcs |= TEXCOORDS_ARE_IN_TEXELUNITS;
 
-   if (mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) {
+   if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS])
+       || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) {
       I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
       i830->state.Tex[unit][I830_TEXREG_MCS] = mcs;
+      i830->state.Tex[unit][I830_TEXREG_CUBE] = 0;
    }
 
    return GL_TRUE;
@@ -284,15 +334,61 @@ static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
    mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS;
    mcs |= TEXCOORDS_ARE_NORMAL;
 
-   if (mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) {
+   if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS])
+       || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) {
       I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
       i830->state.Tex[unit][I830_TEXREG_MCS] = mcs;
+      i830->state.Tex[unit][I830_TEXREG_CUBE] = 0;
    }
 
    return GL_TRUE;
 }
 
  
+static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit )
+{
+   i830ContextPtr i830 = I830_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   struct gl_texture_object *tObj = texUnit->_Current;
+   i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData;
+   GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS];
+   const GLuint cube = CUBE_NEGX_ENABLE | CUBE_POSX_ENABLE
+     | CUBE_NEGY_ENABLE | CUBE_POSY_ENABLE
+     | CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE;
+   GLuint face;
+
+   mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS;
+   mcs |= TEXCOORDS_ARE_NORMAL;
+
+   if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS])
+       || (cube != i830->state.Tex[unit][I830_TEXREG_CUBE])) {
+      I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
+      i830->state.Tex[unit][I830_TEXREG_MCS] = mcs;
+      i830->state.Tex[unit][I830_TEXREG_CUBE] = cube;
+   }
+
+   /* Upload teximages (not pipelined)
+    */
+   if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] ||
+        t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] ||
+        t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) {
+      i830SetTexImages( i830, tObj );
+   }
+
+   /* upload (per face) */
+   for (face = 0; face < 6; face++) {
+      if (t->intel.base.dirty_images[face]) {
+        if (!intelUploadTexImages( &i830->intel, &t->intel, face )) {
+           return GL_FALSE;
+        }
+      }
+   }
+
+
+   return GL_TRUE;
+}
+
+
 static GLboolean disable_tex( GLcontext *ctx, GLuint unit )
 {
    i830ContextPtr i830 = I830_CONTEXT(ctx);
@@ -324,20 +420,21 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit )
        INTEL_CONTEXT(ctx)->intelScreen->textureSize < 2048 * 1024)
       return GL_FALSE;
 
-   if (texUnit->_ReallyEnabled == TEXTURE_1D_BIT ||
-       texUnit->_ReallyEnabled == TEXTURE_2D_BIT) {
+   switch(texUnit->_ReallyEnabled) {
+   case TEXTURE_1D_BIT:
+   case TEXTURE_2D_BIT:
       return (enable_tex_common( ctx, unit ) &&
              enable_tex_2d( ctx, unit ));
-   }
-   else if (texUnit->_ReallyEnabled == TEXTURE_RECT_BIT) {      
+   case TEXTURE_RECT_BIT:
       return (enable_tex_common( ctx, unit ) &&
              enable_tex_rect( ctx, unit ));
-   }
-   else if (texUnit->_ReallyEnabled) {
-      return GL_FALSE;
-   }
-   else {
+   case TEXTURE_CUBE_BIT:
+      return (enable_tex_common( ctx, unit ) &&
+             enable_tex_cube( ctx, unit ));
+   case 0:
       return disable_tex( ctx, unit );
+   default:
+      return GL_FALSE;
    }
 }
 
index b0a7287..22939e8 100644 (file)
@@ -121,11 +121,15 @@ static void i830_render_start( intelContextPtr intel )
            switch (sz) {
            case 1: 
            case 2: 
-           case 3:             /* XXX: fix for CUBE/VOLUME textures */
               emit = EMIT_2F; 
               sz = 2; 
               mcs |= TEXCOORDTYPE_CARTESIAN; 
               break;
+           case 3:
+              emit = EMIT_3F; 
+              sz = 3;
+              mcs |= TEXCOORDTYPE_VECTOR;
+              break;
            case 4: 
               emit = EMIT_3F_XYW; 
               sz = 3;     
index 4cfc502..ff2ac28 100644 (file)
@@ -48,7 +48,6 @@
 static const char * const card_extensions[] =
 {
    "GL_ARB_fragment_program",
-   "GL_ARB_texture_cube_map",
    NULL
 };
 
index 610e0f5..e637d38 100644 (file)
@@ -72,7 +72,7 @@ int prevLockLine;
  * Mesa's Driver Functions
  ***************************************/
 
-#define DRIVER_DATE                     "20040914"
+#define DRIVER_DATE                     "20040919"
 
 const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
 {
@@ -144,6 +144,7 @@ static const char * const card_extensions[] =
    "GL_ARB_multitexture",
    "GL_ARB_point_parameters",
    "GL_ARB_texture_border_clamp",
+   "GL_ARB_texture_cube_map",
    "GL_ARB_texture_compression",
    "GL_ARB_texture_env_add",
    "GL_ARB_texture_env_combine",