mesa: add new GLvertexformat entries for integer-valued attributes
[mesa.git] / src / mesa / main / mipmap.c
index 3dca09d9f289ae39612f90b7cc999d1d2f1ec230..11d5a0519e03913008e68e42c9e8834e23981476 100644 (file)
  */
 
 #include "imports.h"
+#include "formats.h"
 #include "mipmap.h"
-#include "texcompress.h"
-#include "texformat.h"
 #include "teximage.h"
+#include "texstore.h"
 #include "image.h"
 
 
@@ -415,7 +415,7 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
       GLuint i, j, k;
       const GLuint *rowA = (const GLuint *) srcRowA;
       const GLuint *rowB = (const GLuint *) srcRowB;
-      GLfloat *dst = (GLfloat *) dstRow;
+      GLuint *dst = (GLuint *) dstRow;
       for (i = j = 0, k = k0; i < (GLuint) dstWidth;
            i++, j += colStride, k += colStride) {
          dst[i] = (GLfloat)(rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4);
@@ -606,7 +606,7 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
          FILTER_3D(0);
       }
    }
-   if ((datatype == GL_BYTE) && (comps == 4)) {
+   else if ((datatype == GL_BYTE) && (comps == 4)) {
       DECLARE_ROW_POINTERS(GLbyte, 4);
 
       for (i = j = 0, k = k0; i < (GLuint) dstWidth;
@@ -979,9 +979,11 @@ make_1d_mipmap(GLenum datatype, GLuint comps, GLint border,
 
    if (border) {
       /* copy left-most pixel from source */
-      MEMCPY(dstPtr, srcPtr, bpt);
+      assert(dstPtr);
+      assert(srcPtr);
+      memcpy(dstPtr, srcPtr, bpt);
       /* copy right-most pixel from source */
-      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+      memcpy(dstPtr + (dstWidth - 1) * bpt,
              srcPtr + (srcWidth - 1) * bpt,
              bpt);
    }
@@ -1003,21 +1005,28 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
    const GLint dstRowBytes = bpt * dstRowStride;
    const GLubyte *srcA, *srcB;
    GLubyte *dst;
-   GLint row;
+   GLint row, srcRowStep;
 
    /* Compute src and dst pointers, skipping any border */
    srcA = srcPtr + border * ((srcWidth + 1) * bpt);
-   if (srcHeight > 1) 
+   if (srcHeight > 1 && srcHeight > dstHeight) {
+      /* sample from two source rows */
       srcB = srcA + srcRowBytes;
-   else
+      srcRowStep = 2;
+   }
+   else {
+      /* sample from one source row */
       srcB = srcA;
+      srcRowStep = 1;
+   }
+
    dst = dstPtr + border * ((dstWidth + 1) * bpt);
 
    for (row = 0; row < dstHeightNB; row++) {
       do_row(datatype, comps, srcWidthNB, srcA, srcB,
              dstWidthNB, dst);
-      srcA += 2 * srcRowBytes;
-      srcB += 2 * srcRowBytes;
+      srcA += srcRowStep * srcRowBytes;
+      srcB += srcRowStep * srcRowBytes;
       dst += dstRowBytes;
    }
 
@@ -1025,15 +1034,17 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
    if (border > 0) {
       /* fill in dest border */
       /* lower-left border pixel */
-      MEMCPY(dstPtr, srcPtr, bpt);
+      assert(dstPtr);
+      assert(srcPtr);
+      memcpy(dstPtr, srcPtr, bpt);
       /* lower-right border pixel */
-      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+      memcpy(dstPtr + (dstWidth - 1) * bpt,
              srcPtr + (srcWidth - 1) * bpt, bpt);
       /* upper-left border pixel */
-      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
+      memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt,
              srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
       /* upper-right border pixel */
-      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
+      memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt,
              srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
       /* lower border */
       do_row(datatype, comps, srcWidthNB,
@@ -1050,9 +1061,9 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
       if (srcHeight == dstHeight) {
          /* copy border pixel from src to dst */
          for (row = 1; row < srcHeight; row++) {
-            MEMCPY(dstPtr + dstWidth * row * bpt,
+            memcpy(dstPtr + dstWidth * row * bpt,
                    srcPtr + srcWidth * row * bpt, bpt);
-            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
+            memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
                    srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
          }
       }
@@ -1115,7 +1126,7 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
     */
 
    /*
-   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
+   printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
           srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
    */
 
@@ -1174,28 +1185,28 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
             /* do border along [img][row=0][col=0] */
             src = srcPtr + (img + 1) * bytesPerSrcImage;
             dst = dstPtr + (img + 1) * bytesPerDstImage;
-            MEMCPY(dst, src, bpt);
+            memcpy(dst, src, bpt);
 
             /* do border along [img][row=dstHeight-1][col=0] */
             src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
                          + (srcHeight - 1) * bytesPerSrcRow;
             dst = dstPtr + (img + 1) * bytesPerDstImage
                          + (dstHeight - 1) * bytesPerDstRow;
-            MEMCPY(dst, src, bpt);
+            memcpy(dst, src, bpt);
 
             /* do border along [img][row=0][col=dstWidth-1] */
             src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
                          + (srcWidth - 1) * bpt;
             dst = dstPtr + (img + 1) * bytesPerDstImage
                          + (dstWidth - 1) * bpt;
-            MEMCPY(dst, src, bpt);
+            memcpy(dst, src, bpt);
 
             /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
             src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
                          + (bytesPerSrcImage - bpt);
             dst = dstPtr + (img + 1) * bytesPerDstImage
                          + (bytesPerDstImage - bpt);
-            MEMCPY(dst, src, bpt);
+            memcpy(dst, src, bpt);
          }
       }
       else {
@@ -1265,9 +1276,11 @@ make_1d_stack_mipmap(GLenum datatype, GLuint comps, GLint border,
 
    if (border) {
       /* copy left-most pixel from source */
-      MEMCPY(dstPtr, srcPtr, bpt);
+      assert(dstPtr);
+      assert(srcPtr);
+      memcpy(dstPtr, srcPtr, bpt);
       /* copy right-most pixel from source */
-      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+      memcpy(dstPtr + (dstWidth - 1) * bpt,
              srcPtr + (srcWidth - 1) * bpt,
              bpt);
    }
@@ -1319,15 +1332,17 @@ make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border,
       if (border > 0) {
          /* fill in dest border */
          /* lower-left border pixel */
-         MEMCPY(dstPtr, srcPtr, bpt);
+         assert(dstPtr);
+         assert(srcPtr);
+         memcpy(dstPtr, srcPtr, bpt);
          /* lower-right border pixel */
-         MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+         memcpy(dstPtr + (dstWidth - 1) * bpt,
                 srcPtr + (srcWidth - 1) * bpt, bpt);
          /* upper-left border pixel */
-         MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
+         memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt,
                 srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
          /* upper-right border pixel */
-         MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
+         memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt,
                 srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
          /* lower border */
          do_row(datatype, comps, srcWidthNB,
@@ -1344,9 +1359,9 @@ make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border,
          if (srcHeight == dstHeight) {
             /* copy border pixel from src to dst */
             for (row = 1; row < srcHeight; row++) {
-               MEMCPY(dstPtr + dstWidth * row * bpt,
+               memcpy(dstPtr + dstWidth * row * bpt,
                       srcPtr + srcWidth * row * bpt, bpt);
-               MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
+               memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
                       srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
             }
          }
@@ -1489,11 +1504,11 @@ next_mipmap_level_size(GLenum target, GLint border,
  * GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP.
  */
 void
-_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
+_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
                       struct gl_texture_object *texObj)
 {
    const struct gl_texture_image *srcImage;
-   const struct gl_texture_format *convertFormat;
+   gl_format convertFormat;
    const GLubyte *srcData = NULL;
    GLubyte *dstData = NULL;
    GLint level, maxLevels;
@@ -1501,16 +1516,18 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
    GLuint comps;
 
    ASSERT(texObj);
-   /* XXX choose cube map face here??? */
-   srcImage = texObj->Image[0][texObj->BaseLevel];
+   srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel);
    ASSERT(srcImage);
 
    maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
    ASSERT(maxLevels > 0);  /* bad target */
 
    /* Find convertFormat - the format that do_row() will process */
-   if (srcImage->IsCompressed) {
-      /* setup for compressed textures */
+
+   if (_mesa_is_format_compressed(srcImage->TexFormat)) {
+      /* setup for compressed textures - need to allocate temporary
+       * image buffers to hold uncompressed images.
+       */
       GLuint row;
       GLint  components, size;
       GLchan *dst;
@@ -1519,11 +1536,11 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
              texObj->Target == GL_TEXTURE_CUBE_MAP_ARB);
 
       if (srcImage->_BaseFormat == GL_RGB) {
-         convertFormat = &_mesa_texformat_rgb;
+         convertFormat = MESA_FORMAT_RGB888;
          components = 3;
       }
       else if (srcImage->_BaseFormat == GL_RGBA) {
-         convertFormat = &_mesa_texformat_rgba;
+         convertFormat = MESA_FORMAT_RGBA8888;
          components = 4;
       }
       else {
@@ -1535,15 +1552,15 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
       size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)
          * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
       /* 20 extra bytes, just be safe when calling last FetchTexel */
-      srcData = (GLubyte *) _mesa_malloc(size);
+      srcData = (GLubyte *) malloc(size);
       if (!srcData) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
          return;
       }
-      dstData = (GLubyte *) _mesa_malloc(size / 2);  /* 1/4 would probably be OK */
+      dstData = (GLubyte *) malloc(size / 2);  /* 1/4 would probably be OK */
       if (!dstData) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
-         _mesa_free((void *) srcData);
+         free((void *) srcData);
          return;
       }
 
@@ -1571,7 +1588,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
       struct gl_texture_image *dstImage;
       GLint srcWidth, srcHeight, srcDepth;
       GLint dstWidth, dstHeight, dstDepth;
-      GLint border, bytesPerTexel;
+      GLint border;
       GLboolean nextLevel;
 
       /* get src image parameters */
@@ -1587,9 +1604,9 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
                                          &dstWidth, &dstHeight, &dstDepth);
       if (!nextLevel) {
          /* all done */
-         if (srcImage->IsCompressed) {
-            _mesa_free((void *) srcData);
-            _mesa_free(dstData);
+         if (_mesa_is_format_compressed(srcImage->TexFormat)) {
+            free((void *) srcData);
+            free(dstData);
          }
          return;
       }
@@ -1612,46 +1629,33 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
       dstImage->TexFormat = srcImage->TexFormat;
       dstImage->FetchTexelc = srcImage->FetchTexelc;
       dstImage->FetchTexelf = srcImage->FetchTexelf;
-      dstImage->IsCompressed = srcImage->IsCompressed;
-      if (dstImage->IsCompressed) {
-         dstImage->CompressedSize
-            = ctx->Driver.CompressedTextureSize(ctx, dstImage->Width,
-                                              dstImage->Height,
-                                              dstImage->Depth,
-                                              dstImage->TexFormat->MesaFormat);
-         ASSERT(dstImage->CompressedSize > 0);
-      }
-
-      ASSERT(dstImage->TexFormat);
-      ASSERT(dstImage->FetchTexelc);
-      ASSERT(dstImage->FetchTexelf);
 
-      /* Alloc new teximage data buffer.
-       * Setup src and dest data pointers.
-       */
-      if (dstImage->IsCompressed) {
-         dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize);
+      /* Alloc new teximage data buffer */
+      {
+         GLuint size = _mesa_format_image_size(dstImage->TexFormat,
+                                               dstWidth, dstHeight, dstDepth);
+         dstImage->Data = _mesa_alloc_texmemory(size);
          if (!dstImage->Data) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
             return;
          }
+      }
+
+      /* Setup src and dest data pointers */
+      if (_mesa_is_format_compressed(dstImage->TexFormat)) {
          /* srcData and dstData are already set */
          ASSERT(srcData);
          ASSERT(dstData);
       }
       else {
-         bytesPerTexel = dstImage->TexFormat->TexelBytes;
-         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
-         dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight
-                                                * dstDepth * bytesPerTexel);
-         if (!dstImage->Data) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
-            return;
-         }
          srcData = (const GLubyte *) srcImage->Data;
          dstData = (GLubyte *) dstImage->Data;
       }
 
+      ASSERT(dstImage->TexFormat);
+      ASSERT(dstImage->FetchTexelc);
+      ASSERT(dstImage->FetchTexelf);
+
       _mesa_generate_mipmap_level(target, datatype, comps, border,
                                   srcWidth, srcHeight, srcDepth, 
                                   srcData, srcImage->RowStride,
@@ -1659,22 +1663,24 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
                                   dstData, dstImage->RowStride);
 
 
-      if (dstImage->IsCompressed) {
+      if (_mesa_is_format_compressed(dstImage->TexFormat)) {
          GLubyte *temp;
          /* compress image from dstData into dstImage->Data */
-         const GLenum srcFormat = convertFormat->BaseFormat;
+         const GLenum srcFormat = _mesa_get_format_base_format(convertFormat);
          GLint dstRowStride
-            = _mesa_compressed_row_stride(dstImage->TexFormat->MesaFormat, dstWidth);
+            = _mesa_format_row_stride(dstImage->TexFormat, dstWidth);
          ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
-         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat,
-                                         dstImage->TexFormat,
-                                         dstImage->Data,
-                                         0, 0, 0, /* dstX/Y/Zoffset */
-                                         dstRowStride, 0, /* strides */
-                                         dstWidth, dstHeight, 1, /* size */
-                                         srcFormat, CHAN_TYPE,
-                                         dstData, /* src data, actually */
-                                         &ctx->DefaultPacking);
+
+         _mesa_texstore(ctx, 2, dstImage->_BaseFormat,
+                        dstImage->TexFormat,
+                        dstImage->Data,
+                        0, 0, 0, /* dstX/Y/Zoffset */
+                        dstRowStride, 0, /* strides */
+                        dstWidth, dstHeight, 1, /* size */
+                        srcFormat, CHAN_TYPE,
+                        dstData, /* src data, actually */
+                        &ctx->DefaultPacking);
+
          /* swap src and dest pointers */
          temp = (GLubyte *) srcData;
          srcData = dstData;