glthread: Fix use of alloca() without #include "c99_alloca.h"
[mesa.git] / src / mesa / main / mipmap.c
index cb9afdef2af929963b8f4ce6bd59875a772cd321..f882bae89ce9200c290567fb6421eb750ad80178 100644 (file)
@@ -27,7 +27,8 @@
  * \file mipmap.c  mipmap generation and teximage resizing functions.
  */
 
-#include "imports.h"
+#include "errors.h"
+
 #include "formats.h"
 #include "glformats.h"
 #include "mipmap.h"
 #include "image.h"
 #include "macros.h"
 #include "util/half_float.h"
-#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
-#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
+#include "util/format_rgb9e5.h"
+#include "util/format_r11g11b10f.h"
+
+
+/**
+ * Compute the expected number of mipmap levels in the texture given
+ * the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/
+ * GL_TEXTURE_MAX_LEVEL settings.  This will tell us how many mipmap
+ * levels should be generated.
+ */
+unsigned
+_mesa_compute_num_levels(struct gl_context *ctx,
+                         struct gl_texture_object *texObj,
+                         GLenum target)
+{
+   const struct gl_texture_image *baseImage;
+   GLuint numLevels;
+
+   baseImage = _mesa_get_tex_image(ctx, texObj, target, texObj->BaseLevel);
 
+   numLevels = texObj->BaseLevel + baseImage->MaxNumLevels;
+   numLevels = MIN2(numLevels, (GLuint) texObj->MaxLevel + 1);
+   if (texObj->Immutable)
+      numLevels = MIN2(numLevels, texObj->NumLevels);
+   assert(numLevels >= 1);
 
+   return numLevels;
+}
 
 static GLint
 bytes_per_pixel(GLenum datatype, GLuint comps)
@@ -757,7 +782,7 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
    }
 
    else {
-      _mesa_problem(NULL, "bad format in do_row()");
+      unreachable("bad format in do_row()");
    }
 }
 
@@ -1401,7 +1426,7 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth,
    }
 
    else {
-      _mesa_problem(NULL, "bad format in do_row()");
+      unreachable("bad format in do_row()");
    }
 }
 
@@ -1445,9 +1470,9 @@ make_1d_mipmap(GLenum datatype, GLuint comps, GLint border,
 static void
 make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
                GLint srcWidth, GLint srcHeight,
-              const GLubyte *srcPtr, GLint srcRowStride,
+               const GLubyte *srcPtr, GLint srcRowStride,
                GLint dstWidth, GLint dstHeight,
-              GLubyte *dstPtr, GLint dstRowStride)
+               GLubyte *dstPtr, GLint dstRowStride)
 {
    const GLint bpt = bytes_per_pixel(datatype, comps);
    const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
@@ -1595,7 +1620,7 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
       GLubyte *dstImgRow = imgDst;
 
       for (row = 0; row < dstHeightNB; row++) {
-         do_row_3D(datatype, comps, srcWidthNB, 
+         do_row_3D(datatype, comps, srcWidthNB,
                    srcImgARowA, srcImgARowB,
                    srcImgBRowA, srcImgBRowB,
                    dstWidthNB, dstImgRow);
@@ -1736,17 +1761,17 @@ _mesa_generate_mipmap_level(GLenum target,
       assert(srcHeight == 1);
       assert(dstHeight == 1);
       for (i = 0; i < dstDepth; i++) {
-        make_1d_mipmap(datatype, comps, border,
-                       srcWidth, srcData[i],
-                       dstWidth, dstData[i]);
+         make_1d_mipmap(datatype, comps, border,
+                        srcWidth, srcData[i],
+                        dstWidth, dstData[i]);
       }
       break;
    case GL_TEXTURE_2D_ARRAY_EXT:
    case GL_TEXTURE_CUBE_MAP_ARRAY:
       for (i = 0; i < dstDepth; i++) {
-        make_2d_mipmap(datatype, comps, border,
-                       srcWidth, srcHeight, srcData[i], srcRowStride,
-                       dstWidth, dstHeight, dstData[i], dstRowStride);
+         make_2d_mipmap(datatype, comps, border,
+                        srcWidth, srcHeight, srcData[i], srcRowStride,
+                        dstWidth, dstHeight, dstData[i], dstRowStride);
       }
       break;
    case GL_TEXTURE_RECTANGLE_NV:
@@ -1754,8 +1779,7 @@ _mesa_generate_mipmap_level(GLenum target,
       /* no mipmaps, do nothing */
       break;
    default:
-      _mesa_problem(NULL, "bad tex target in _mesa_generate_mipmaps");
-      return;
+      unreachable("bad tex target in _mesa_generate_mipmaps");
    }
 }
 
@@ -1776,8 +1800,9 @@ _mesa_next_mipmap_level_size(GLenum target, GLint border,
       *dstWidth = srcWidth; /* can't go smaller */
    }
 
-   if ((srcHeight - 2 * border > 1) && 
-       (target != GL_TEXTURE_1D_ARRAY_EXT)) {
+   if ((srcHeight - 2 * border > 1) &&
+       target != GL_TEXTURE_1D_ARRAY_EXT &&
+       target != GL_PROXY_TEXTURE_1D_ARRAY_EXT) {
       *dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
    }
    else {
@@ -1785,8 +1810,10 @@ _mesa_next_mipmap_level_size(GLenum target, GLint border,
    }
 
    if ((srcDepth - 2 * border > 1) &&
-       (target != GL_TEXTURE_2D_ARRAY_EXT &&
-        target != GL_TEXTURE_CUBE_MAP_ARRAY)) {
+       target != GL_TEXTURE_2D_ARRAY_EXT &&
+       target != GL_PROXY_TEXTURE_2D_ARRAY_EXT &&
+       target != GL_TEXTURE_CUBE_MAP_ARRAY &&
+       target != GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) {
       *dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
    }
    else {
@@ -1810,11 +1837,11 @@ _mesa_next_mipmap_level_size(GLenum target, GLint border,
  * for mipmap generation.  If not, (re) allocate it.
  * \return GL_TRUE if successful, GL_FALSE if mipmap generation should stop
  */
-GLboolean
-_mesa_prepare_mipmap_level(struct gl_context *ctx,
-                           struct gl_texture_object *texObj, GLuint level,
-                           GLsizei width, GLsizei height, GLsizei depth,
-                           GLsizei border, GLenum intFormat, mesa_format format)
+static GLboolean
+prepare_mipmap_level(struct gl_context *ctx,
+                     struct gl_texture_object *texObj, GLuint level,
+                     GLsizei width, GLsizei height, GLsizei depth,
+                     GLsizei border, GLenum intFormat, mesa_format format)
 {
    const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
    GLuint face;
@@ -1864,7 +1891,7 @@ _mesa_prepare_mipmap_level(struct gl_context *ctx,
          /* in case the mipmap level is part of an FBO: */
          _mesa_update_fbo_texture(ctx, texObj, face, level);
 
-         ctx->NewState |= _NEW_TEXTURE;
+         ctx->NewState |= _NEW_TEXTURE_OBJECT;
       }
    }
 
@@ -1902,9 +1929,9 @@ _mesa_prepare_mipmap_levels(struct gl_context *ctx,
          break;
       }
 
-      if (!_mesa_prepare_mipmap_level(ctx, texObj, level,
-                                      newWidth, newHeight, newDepth,
-                                      border, intFormat, texFormat)) {
+      if (!prepare_mipmap_level(ctx, texObj, level,
+                                newWidth, newHeight, newDepth,
+                                border, intFormat, texFormat)) {
          break;
       }
 
@@ -1917,9 +1944,9 @@ _mesa_prepare_mipmap_levels(struct gl_context *ctx,
 
 static void
 generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
-                            struct gl_texture_object *texObj,
-                            const struct gl_texture_image *srcImage,
-                            GLuint maxLevel)
+                             struct gl_texture_object *texObj,
+                             const struct gl_texture_image *srcImage,
+                             GLuint maxLevel)
 {
    GLuint level;
    GLenum datatype;
@@ -1956,10 +1983,10 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
       dstDepth = dstImage->Depth;
 
       if (target == GL_TEXTURE_1D_ARRAY) {
-        srcDepth = srcHeight;
-        dstDepth = dstHeight;
-        srcHeight = 1;
-        dstHeight = 1;
+         srcDepth = srcHeight;
+         dstDepth = dstHeight;
+         srcHeight = 1;
+         dstHeight = 1;
       }
 
       /* Map src texture image slices */
@@ -2037,9 +2064,9 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
 
 static void
 generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
-                          struct gl_texture_object *texObj,
-                          struct gl_texture_image *srcImage,
-                          GLuint maxLevel)
+                           struct gl_texture_object *texObj,
+                           struct gl_texture_image *srcImage,
+                           GLuint maxLevel)
 {
    GLuint level;
    mesa_format temp_format;
@@ -2052,8 +2079,8 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
 
    /* only two types of compressed textures at this time */
    assert(texObj->Target == GL_TEXTURE_2D ||
-         texObj->Target == GL_TEXTURE_2D_ARRAY ||
-         texObj->Target == GL_TEXTURE_CUBE_MAP ||
+          texObj->Target == GL_TEXTURE_2D_ARRAY ||
+          texObj->Target == GL_TEXTURE_CUBE_MAP ||
           texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY);
 
    /*
@@ -2146,11 +2173,11 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
       temp_dst_img_stride = _mesa_format_image_size(temp_format, dstWidth,
                                                     dstHeight, 1);
       if (!temp_dst) {
-        temp_dst = malloc(temp_dst_img_stride * dstDepth);
-        if (!temp_dst) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
+         temp_dst = malloc(temp_dst_img_stride * dstDepth);
+         if (!temp_dst) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
             goto end;
-        }
+         }
       }
 
       /* for 2D arrays, setup array[depth] of slice pointers */
@@ -2179,9 +2206,9 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
 
       /* swap src and dest pointers */
       {
-        GLubyte *temp = temp_src;
-        temp_src = temp_dst;
-        temp_dst = temp;
+         GLubyte *temp = temp_src;
+         temp_src = temp_dst;
+         temp_dst = temp;
          temp_src_row_stride = temp_dst_row_stride;
          temp_src_img_stride = temp_dst_img_stride;
       }