コード例 #1
0
static void i915LayoutTextureImages( i915ContextPtr i915,
				     struct gl_texture_object *tObj )
{
   const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
   i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
   GLint firstLevel, lastLevel, numLevels;
   GLint i, total_height, pitch;

   /* Compute which mipmap levels we really want to send to the hardware.
    */
   driCalculateTextureFirstLastLevel( (driTextureObject *) t );

   /* Figure out the amount of memory required to hold all the mipmap
    * levels.  Choose the smallest pitch to accomodate the largest
    * mipmap:
    */
   firstLevel = t->intel.base.firstLevel;
   lastLevel = t->intel.base.lastLevel;
   numLevels = lastLevel - firstLevel + 1;



   /* All images must be loaded at this pitch.  Count the number of
    * lines required:
    */
   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;
      
      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->_BaseFormat;

	    d >>= 1;
	    x += step_offsets[face][0] * d;
	    y += step_offsets[face][1] * d;
	 }
      }
      break;
   }
   case GL_TEXTURE_3D: {
      GLuint virtual_height;
      GLuint tmp_numLevels = numLevels;
      pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
      pitch = (pitch + 3) & ~3;
      t->intel.base.dirty_images[0] = ~0;

      /* Calculate the size of a single slice.  Hardware demands a
       * minimum of 8 mipmaps, some of which might ultimately not be
       * used:
       */
      if (tmp_numLevels < 9)
	 tmp_numLevels = 9;

      virtual_height = tObj->Image[0][firstLevel]->Height;

      for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) {
	 t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
	 if (t->intel.image[0][i].image) {
	    t->intel.image[0][i].offset = total_height * pitch;
	    t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
	 }

	 total_height += MAX2(2, virtual_height);
	 virtual_height >>= 1;
      }

      t->intel.depth_pitch = total_height * pitch;

      /* Multiply slice size by texture depth for total size.  It's
       * remarkable how wasteful of memory all the i8x0 texture
       * layouts are.
       */
      total_height *= t->intel.image[0][0].image->Depth;
      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->_BaseFormat;
	 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;
   t->intel.base.totalSize = total_height*pitch;
   t->intel.max_level = numLevels-1;
}
コード例 #2
0
static void i810SetTexImages( i810ContextPtr imesa, 
			      struct gl_texture_object *tObj )
{
   GLuint height, width, pitch, i, textureFormat, log_pitch;
   i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData;
   const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
   GLint numLevels;
   GLint log2Width, log2Height;

/*     fprintf(stderr, "%s\n", __FUNCTION__); */

   t->texelBytes = 2;
   switch (baseImage->TexFormat) {
   case MESA_FORMAT_ARGB1555:
      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB1555;
      break;
   case MESA_FORMAT_ARGB4444:
      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444;
      break;
   case MESA_FORMAT_RGB565:
      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565;
      break;
   case MESA_FORMAT_AL88:
      textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_AY88;
      break;
   case MESA_FORMAT_YCBCR:
      textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB_SWAP_Y
	  | MI1_COLOR_CONV_ENABLE;
      break;
   case MESA_FORMAT_YCBCR_REV:
      textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB
	  | MI1_COLOR_CONV_ENABLE;
      break;
   case MESA_FORMAT_CI8:
      textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444;
      t->texelBytes = 1;
      break;

   default:
      fprintf(stderr, "i810SetTexImages: bad image->Format\n" );
      return;
   }

   driCalculateTextureFirstLastLevel( (driTextureObject *) t );

   numLevels = t->base.lastLevel - t->base.firstLevel + 1;

   log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
   log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;

   /* Figure out the amount of memory required to hold all the mipmap
    * levels.  Choose the smallest pitch to accomodate the largest
    * mipmap:
    */
   width = tObj->Image[0][t->base.firstLevel]->Width * t->texelBytes;
   for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
      log_pitch++;
   
   /* All images must be loaded at this pitch.  Count the number of
    * lines required:
    */
   for ( height = i = 0 ; i < numLevels ; i++ ) {
      t->image[i].image = tObj->Image[0][t->base.firstLevel + i];
      t->image[i].offset = height * pitch;
      t->image[i].internalFormat = baseImage->_BaseFormat;
      height += t->image[i].image->Height;
   }

   t->Pitch = pitch;
   t->base.totalSize = height*pitch;
   t->max_level = i-1;
   t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1;   
   t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch); 
   t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS |
				MLL_MAP_0  |
				MLL_UPDATE_MAX_MIP | 
				MLL_UPDATE_MIN_MIP |
				((numLevels - 1) << MLL_MIN_MIP_SHIFT));

   LOCK_HARDWARE( imesa );
   i810UploadTexImagesLocked( imesa, t );
   UNLOCK_HARDWARE( imesa );
}
コード例 #3
0
static void i945LayoutTextureImages( i915ContextPtr i915,
				    struct gl_texture_object *tObj )
{
   const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
   i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
   GLint firstLevel, lastLevel, numLevels;
   GLint i, total_height, pitch, sz, max_offset = 0, offset;


   /* Compute which mipmap levels we really want to send to the hardware.
    */
   driCalculateTextureFirstLastLevel( (driTextureObject *) t );

   /* Figure out the amount of memory required to hold all the mipmap
    * levels.  Choose the smallest pitch to accomodate the largest
    * mipmap:
    */
   firstLevel = t->intel.base.firstLevel;
   lastLevel = t->intel.base.lastLevel;
   numLevels = lastLevel - firstLevel + 1;



   /* All images must be loaded at this pitch.  Count the number of
    * lines required:
    */
   switch (tObj->Target) {
   case GL_TEXTURE_CUBE_MAP: {
      const GLuint dim = tObj->Image[0][firstLevel]->Width;
      GLuint face;

      /* Depending on the size of the largest images, pitch can be
       * determined either by the old-style packing of cubemap faces,
       * or the final row of 4x4, 2x2 and 1x1 faces below this. 
       */
      if (dim > 32) {
	 pitch = dim * t->intel.texelBytes;
	 pitch *= 2;		/* double pitch for cube layouts */
	 pitch = (pitch + 3) & ~3;
      }
      else {
	 pitch = 14 * 8 * t->intel.texelBytes; /* determined by row of
						* little maps at
						* bottom */
      }
      
      total_height = dim * 4 + 4;

      for ( face = 0 ; face < 6 ; face++) {
	 GLuint x = initial_offsets[face][0] * dim;
	 GLuint y = initial_offsets[face][1] * dim;
	 GLuint d = dim;
	 
	 if (dim == 4 && face >= 4) {
	    y = total_height - 4;
	    x = (face - 4) * 8;
	 }
	 else if (dim < 4) {
	    y = total_height - 4;
	    x = face * 8;
	 }

	 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];
	    assert(t->intel.image[face][i].image);
	 
	    t->intel.image[face][i].offset = 
	       y * pitch + x * t->intel.texelBytes;
	    t->intel.image[face][i].internalFormat = baseImage->_BaseFormat;

	    d >>= 1;
	    
	    switch (d) {
	    case 4:
	       switch (face) {
	       case FACE_POS_X:
	       case FACE_NEG_X:
		  x += step_offsets[face][0] * d;
		  y += step_offsets[face][1] * d;
		  break;
	       case FACE_POS_Y:
	       case FACE_NEG_Y:
		  y += 12;
		  x -= 8;
		  break;
	       case FACE_POS_Z:
	       case FACE_NEG_Z:
		  y = total_height - 4;
		  x = (face - 4) * 8;
		  break;
	       }

	    case 2:
	       y = total_height - 4;
	       x = 16 + face * 8;
	       break;

	    case 1:
	       x += 48;
	       break;
	       
	    default:
	       x += step_offsets[face][0] * d;
	       y += step_offsets[face][1] * d;
	       break;
	    }
	 }
      }
      max_offset = total_height * pitch;
      break;
   }
   case GL_TEXTURE_3D: {
      GLuint depth_packing = 0, depth_pack_pitch;
      GLuint tmp_numLevels = numLevels;
      pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
      pitch = (pitch + 3) & ~3;
      depth_pack_pitch = pitch;
      
      t->intel.base.dirty_images[0] = ~0;


      for ( total_height = i = 0 ; i < tmp_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->_BaseFormat;
	 


	 total_height += MAX2(2, t->intel.image[0][i].image->Height) * 
	    MAX2((t->intel.image[0][i].image->Depth >> depth_packing), 1);

	 /* When alignment dominates, can't increase depth packing?
	  * Or does pitch grow???  What are the alignment constraints,
	  * anyway?
	  */
	 if (depth_pack_pitch > 4) {
	    depth_packing++;
	    depth_pack_pitch <<= 2;
	 }
      }

      max_offset = total_height * pitch;
      break;
   }
   default:
      pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
      pitch = (pitch + 3) & ~3;
      t->intel.base.dirty_images[0] = ~0;
      max_offset = 0;

      for ( offset = 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 = offset;
	 t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;

	 if (t->intel.image[0][i].image->IsCompressed)
	    sz = MAX2(1, t->intel.image[0][i].image->Height/4) * pitch;
	 else
	    sz = MAX2(2, t->intel.image[0][i].image->Height) * pitch;
	 
	 /* Because the images are packed better, the final offset
	  * might not be the maximal one:
	  */
	 max_offset = MAX2(max_offset, offset + sz);

	 /* LPT change: step right after second mipmap.
	  */
	 if (i == 1) 
	    offset += pitch / 2;
	 else 
	    offset += sz;

      }
      break;
   }

   t->intel.Pitch = pitch;
   t->intel.base.totalSize = max_offset;
   t->intel.max_level = numLevels-1;
}
コード例 #4
0
ファイル: r128_texstate.c プロジェクト: toastpp/toastpp
static void r128SetTexImages( r128ContextPtr rmesa,
                              const struct gl_texture_object *tObj )
{
   r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;
   struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
   int log2Pitch, log2Height, log2Size, log2MinSize;
   int totalSize;
   int i;
   GLint firstLevel, lastLevel;

   assert(t);
   assert(baseImage);

   if ( R128_DEBUG & DEBUG_VERBOSE_API )
      fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *) tObj );

   switch (baseImage->TexFormat->MesaFormat) {
   case MESA_FORMAT_ARGB8888:
   case MESA_FORMAT_ARGB8888_REV:
      t->textureFormat = R128_DATATYPE_ARGB8888;
      break;
   case MESA_FORMAT_ARGB4444:
   case MESA_FORMAT_ARGB4444_REV:
      t->textureFormat = R128_DATATYPE_ARGB4444;
      break;
   case MESA_FORMAT_RGB565:
   case MESA_FORMAT_RGB565_REV:
      t->textureFormat = R128_DATATYPE_RGB565;
      break;
   case MESA_FORMAT_RGB332:
      t->textureFormat = R128_DATATYPE_RGB8;
      break;
   case MESA_FORMAT_CI8:
      t->textureFormat = R128_DATATYPE_CI8;
      break;
   case MESA_FORMAT_YCBCR:
      t->textureFormat = R128_DATATYPE_YVYU422;
      break;
   case MESA_FORMAT_YCBCR_REV:
      t->textureFormat = R128_DATATYPE_VYUY422;
      break;
   default:
      _mesa_problem(rmesa->glCtx, "Bad texture format in %s", __FUNCTION__);
   };

   /* Compute which mipmap levels we really want to send to the hardware.
    */

   driCalculateTextureFirstLastLevel( (driTextureObject *) t );
   firstLevel = t->base.firstLevel;
   lastLevel  = t->base.lastLevel;

   log2Pitch = tObj->Image[0][firstLevel]->WidthLog2;
   log2Height = tObj->Image[0][firstLevel]->HeightLog2;
   log2Size = MAX2(log2Pitch, log2Height);
   log2MinSize = log2Size;

   t->base.dirty_images[0] = 0;
   totalSize = 0;
   for ( i = firstLevel; i <= lastLevel; i++ ) {
      const struct gl_texture_image *texImage;

      texImage = tObj->Image[0][i];
      if ( !texImage || !texImage->Data ) {
         lastLevel = i - 1;
	 break;
      }

      log2MinSize = texImage->MaxLog2;

      t->image[i - firstLevel].offset = totalSize;
      t->image[i - firstLevel].width  = tObj->Image[0][i]->Width;
      t->image[i - firstLevel].height = tObj->Image[0][i]->Height;

      t->base.dirty_images[0] |= (1 << i);

      totalSize += (tObj->Image[0][i]->Height *
		    tObj->Image[0][i]->Width *
		    tObj->Image[0][i]->TexFormat->TexelBytes);

      /* Offsets must be 32-byte aligned for host data blits and tiling */
      totalSize = (totalSize + 31) & ~31;
   }

   t->base.totalSize = totalSize;
   t->base.firstLevel = firstLevel;
   t->base.lastLevel = lastLevel;

   /* Set the texture format */
   t->setup.tex_cntl &= ~(0xf << 16);
   t->setup.tex_cntl |= t->textureFormat;

   t->setup.tex_combine_cntl = 0x00000000;  /* XXX is this right? */

   t->setup.tex_size_pitch = ((log2Pitch   << R128_TEX_PITCH_SHIFT) |
			      (log2Size    << R128_TEX_SIZE_SHIFT) |
			      (log2Height  << R128_TEX_HEIGHT_SHIFT) |
			      (log2MinSize << R128_TEX_MIN_SIZE_SHIFT));

   for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
      t->setup.tex_offset[i]  = 0x00000000;
   }

   if (firstLevel == lastLevel)
      t->setup.tex_cntl |= R128_MIP_MAP_DISABLE;
   else
      t->setup.tex_cntl &= ~R128_MIP_MAP_DISABLE;

   /* FYI: r128UploadTexImages( rmesa, t ); used to be called here */
}