diff options
Diffstat (limited to 'src/mesa/main/texcompress.c')
| -rw-r--r-- | src/mesa/main/texcompress.c | 275 | 
1 files changed, 48 insertions, 227 deletions
| diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index 2cda4dd859..a4f1926ab3 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -34,10 +34,10 @@  #include "imports.h"  #include "colormac.h"  #include "context.h" +#include "formats.h"  #include "image.h"  #include "mipmap.h"  #include "texcompress.h" -#include "texformat.h"  #include "texstore.h" @@ -113,252 +113,43 @@ _mesa_get_compressed_formats(GLcontext *ctx, GLint *formats, GLboolean all)  } -  /** - * Return number of bytes needed to store a texture of the given size - * using the specified compressed format. - * This is called via the ctx->Driver.CompressedTextureSize function, - * unless a device driver overrides it. - * - * \param width texture width in texels. - * \param height texture height in texels. - * \param depth texture depth in texels. - * \param mesaFormat  one of the MESA_FORMAT_* compressed formats - * - * \return size in bytes, or zero if bad format + * Convert a compressed MESA_FORMAT_x to a GLenum.   */ -GLuint -_mesa_compressed_texture_size( GLcontext *ctx, -                               GLsizei width, GLsizei height, GLsizei depth, -                               GLuint mesaFormat ) +gl_format +_mesa_glenum_to_compressed_format(GLenum format)  { -   GLuint size; - -   ASSERT(depth == 1); -   (void) depth; -   (void) size; - -   switch (mesaFormat) { -#if FEATURE_texture_fxt1 -   case MESA_FORMAT_RGB_FXT1: -   case MESA_FORMAT_RGBA_FXT1: -      /* round up width to next multiple of 8, height to next multiple of 4 */ -      width = (width + 7) & ~7; -      height = (height + 3) & ~3; -      /* 16 bytes per 8x4 tile of RGB[A] texels */ -      size = width * height / 2; -      /* Textures smaller than 8x4 will effectively be made into 8x4 and -       * take 16 bytes. -       */ -      return size; -#endif -#if FEATURE_texture_s3tc -   case MESA_FORMAT_RGB_DXT1: -   case MESA_FORMAT_RGBA_DXT1: -#if FEATURE_EXT_texture_sRGB -   case MESA_FORMAT_SRGB_DXT1: -   case MESA_FORMAT_SRGBA_DXT1: -#endif -      /* round up width, height to next multiple of 4 */ -      width = (width + 3) & ~3; -      height = (height + 3) & ~3; -      /* 8 bytes per 4x4 tile of RGB[A] texels */ -      size = width * height / 2; -      /* Textures smaller than 4x4 will effectively be made into 4x4 and -       * take 8 bytes. -       */ -      return size; -   case MESA_FORMAT_RGBA_DXT3: -   case MESA_FORMAT_RGBA_DXT5: -#if FEATURE_EXT_texture_sRGB -   case MESA_FORMAT_SRGBA_DXT3: -   case MESA_FORMAT_SRGBA_DXT5: -#endif -      /* round up width, height to next multiple of 4 */ -      width = (width + 3) & ~3; -      height = (height + 3) & ~3; -      /* 16 bytes per 4x4 tile of RGBA texels */ -      size = width * height; /* simple! */ -      /* Textures smaller than 4x4 will effectively be made into 4x4 and -       * take 16 bytes. -       */ -      return size; -#endif -   default: -      _mesa_problem(ctx, "bad mesaFormat in _mesa_compressed_texture_size"); -      return 0; -   } -} - - -/** - * As above, but format is specified by a GLenum (GL_COMPRESSED_*) token. - * - * Note: This function CAN NOT return a padded hardware texture size. - * That's why we don't call the ctx->Driver.CompressedTextureSize() function. - * - * We use this function to validate the <imageSize> parameter - * of glCompressedTex[Sub]Image1/2/3D(), which must be an exact match. - */ -GLuint -_mesa_compressed_texture_size_glenum(GLcontext *ctx, -                                     GLsizei width, GLsizei height, -                                     GLsizei depth, GLenum glformat) -{ -   GLuint mesaFormat; - -   switch (glformat) { -#if FEATURE_texture_fxt1 +   switch (format) {     case GL_COMPRESSED_RGB_FXT1_3DFX: -      mesaFormat = MESA_FORMAT_RGB_FXT1; -      break; +      return MESA_FORMAT_RGB_FXT1;     case GL_COMPRESSED_RGBA_FXT1_3DFX: -      mesaFormat = MESA_FORMAT_RGBA_FXT1; -      break; -#endif -#if FEATURE_texture_s3tc +      return MESA_FORMAT_RGBA_FXT1; +     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:     case GL_RGB_S3TC: -      mesaFormat = MESA_FORMAT_RGB_DXT1; -      break; +      return MESA_FORMAT_RGB_DXT1;     case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:     case GL_RGB4_S3TC: -      mesaFormat = MESA_FORMAT_RGBA_DXT1; -      break; +      return MESA_FORMAT_RGBA_DXT1;     case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:     case GL_RGBA_S3TC: -      mesaFormat = MESA_FORMAT_RGBA_DXT3; -      break; +      return MESA_FORMAT_RGBA_DXT3;     case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:     case GL_RGBA4_S3TC: -      mesaFormat = MESA_FORMAT_RGBA_DXT5; -      break; -#if FEATURE_EXT_texture_sRGB +      return MESA_FORMAT_RGBA_DXT5; +     case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: -      mesaFormat = MESA_FORMAT_SRGB_DXT1; -      break; +      return MESA_FORMAT_SRGB_DXT1;     case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: -      mesaFormat = MESA_FORMAT_SRGBA_DXT1; -      break; +      return MESA_FORMAT_SRGBA_DXT1;     case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: -      mesaFormat = MESA_FORMAT_SRGBA_DXT3; -      break; +      return MESA_FORMAT_SRGBA_DXT3;     case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: -      mesaFormat = MESA_FORMAT_SRGBA_DXT5; -      break; -#endif -#endif -   default: -      return 0; -   } - -   return _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat); -} - - -/* - * Compute the bytes per row in a compressed texture image. - * We use this for computing the destination address for sub-texture updates. - * \param mesaFormat  one of the MESA_FORMAT_* compressed formats - * \param width  image width in pixels - * \return stride, in bytes, between rows for compressed image - */ -GLint -_mesa_compressed_row_stride(GLuint mesaFormat, GLsizei width) -{ -   GLint stride; - -   switch (mesaFormat) { -#if FEATURE_texture_fxt1 -   case MESA_FORMAT_RGB_FXT1: -   case MESA_FORMAT_RGBA_FXT1: -      stride = ((width + 7) / 8) * 16; /* 16 bytes per 8x4 tile */ -      break; -#endif -#if FEATURE_texture_s3tc -   case MESA_FORMAT_RGB_DXT1: -   case MESA_FORMAT_RGBA_DXT1: -#if FEATURE_EXT_texture_sRGB -   case MESA_FORMAT_SRGB_DXT1: -   case MESA_FORMAT_SRGBA_DXT1: -#endif -      stride = ((width + 3) / 4) * 8; /* 8 bytes per 4x4 tile */ -      break; -   case MESA_FORMAT_RGBA_DXT3: -   case MESA_FORMAT_RGBA_DXT5: -#if FEATURE_EXT_texture_sRGB -   case MESA_FORMAT_SRGBA_DXT3: -   case MESA_FORMAT_SRGBA_DXT5: -#endif -      stride = ((width + 3) / 4) * 16; /* 16 bytes per 4x4 tile */ -      break; -#endif -   default: -      _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_row_stride"); -      return 0; -   } - -   return stride; -} - +      return MESA_FORMAT_SRGBA_DXT5; -/* - * Return the address of the pixel at (col, row, img) in a - * compressed texture image. - * \param col, row, img - image position (3D) - * \param format - compressed image format - * \param width - image width - * \param image - the image address - * \return address of pixel at (row, col) - */ -GLubyte * -_mesa_compressed_image_address(GLint col, GLint row, GLint img, -                               GLuint mesaFormat, -                               GLsizei width, const GLubyte *image) -{ -   GLubyte *addr; - -   (void) img; - -   /* We try to spot a "complete" subtexture "above" ROW, COL; -    * this texture is given by appropriate rounding of WIDTH x ROW. -    * Then we just add the amount left (usually on the left). -    * -    * Example for X*Y microtiles (Z bytes each) -    * offset = Z * (((width + X - 1) / X) * (row / Y) + col / X); -    */ - -   switch (mesaFormat) { -#if FEATURE_texture_fxt1 -   case MESA_FORMAT_RGB_FXT1: -   case MESA_FORMAT_RGBA_FXT1: -      addr = (GLubyte *) image + 16 * (((width + 7) / 8) * (row / 4) + col / 8); -      break; -#endif -#if FEATURE_texture_s3tc -   case MESA_FORMAT_RGB_DXT1: -   case MESA_FORMAT_RGBA_DXT1: -#if FEATURE_EXT_texture_sRGB -   case MESA_FORMAT_SRGB_DXT1: -   case MESA_FORMAT_SRGBA_DXT1: -#endif -      addr = (GLubyte *) image + 8 * (((width + 3) / 4) * (row / 4) + col / 4); -      break; -   case MESA_FORMAT_RGBA_DXT3: -   case MESA_FORMAT_RGBA_DXT5: -#if FEATURE_EXT_texture_sRGB -   case MESA_FORMAT_SRGBA_DXT3: -   case MESA_FORMAT_SRGBA_DXT5: -#endif -      addr = (GLubyte *) image + 16 * (((width + 3) / 4) * (row / 4) + col / 4); -      break; -#endif     default: -      _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_image_address"); -      addr = NULL; +      return MESA_FORMAT_NONE;     } - -   return addr;  } @@ -410,3 +201,33 @@ _mesa_compressed_format_to_glenum(GLcontext *ctx, GLuint mesaFormat)  } +/* + * Return the address of the pixel at (col, row, img) in a + * compressed texture image. + * \param col, row, img - image position (3D), should be a multiple of the + *                        format's block size. + * \param format - compressed image format + * \param width - image width (stride) in pixels + * \param image - the image address + * \return address of pixel at (row, col, img) + */ +GLubyte * +_mesa_compressed_image_address(GLint col, GLint row, GLint img, +                               gl_format mesaFormat, +                               GLsizei width, const GLubyte *image) +{ +   /* XXX only 2D images implemented, not 3D */ +   const GLuint blockSize = _mesa_get_format_bytes(mesaFormat); +   GLuint bw, bh; +   GLint offset; + +   _mesa_get_format_block_size(mesaFormat, &bw, &bh); + +   ASSERT(col % bw == 0); +   ASSERT(row % bh == 0); + +   offset = ((width + bw - 1) / bw) * (row / bh) + col / bw; +   offset *= blockSize; + +   return (GLubyte *) image + offset; +} | 
