Merge branch 'mesa_7_6_branch'
authorBrian Paul <brianp@vmware.com>
Mon, 28 Sep 2009 16:02:20 +0000 (10:02 -0600)
committerBrian Paul <brianp@vmware.com>
Mon, 28 Sep 2009 16:02:20 +0000 (10:02 -0600)
docs/relnotes-7.5.2.html
src/gallium/auxiliary/util/u_gen_mipmap.c
src/glx/x11/glxhash.c
src/mesa/drivers/dri/intel/intel_buffer_objects.c
src/mesa/drivers/dri/intel/intel_tex_copy.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_gen_mipmap.c

index b638c0517ddc730be39194edfda815c89f9def08..0832e11bb4981ee3a45b13fd1d738c899a1cb63e 100644 (file)
@@ -49,6 +49,10 @@ tbd
     (such as bug 23946)
 <li>glUseProgram() is now compiled into display lists (bug 23746).
 <li>glUniform functions are now compiled into display lists
+<li>Auto mipmap generation didn't work reliably with Gallium.
+<li>Fixed random number usage in GLX code.
+<li>Fixed invalid GL_OUT_OF_MEMORY error sometimes raised by glTexSubImage2D
+    when using Gallium.
 </ul>
 
 
index f06c0e463d0db8a1861662d0114d64d8d375bcf6..4e3d35f40e7c8543d83a4188b4f0ced9e97e7224 100644 (file)
@@ -1515,6 +1515,17 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    uint zslice = 0;
    uint offset;
 
+   /* The texture object should have room for the levels which we're
+    * about to generate.
+    */
+   assert(lastLevel <= pt->last_level);
+
+   /* If this fails, why are we here? */
+   assert(lastLevel > baseLevel);
+
+   assert(filter == PIPE_TEX_FILTER_LINEAR ||
+          filter == PIPE_TEX_FILTER_NEAREST);
+
    /* check if we can render in the texture's format */
    if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
                                     PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
index 6f2c51d39dd984e634af8782c93692372bd43aad..b76ec32345940c3020e0f5045d223f171e17e048 100644 (file)
 
 #define HASH_ALLOC malloc
 #define HASH_FREE  free
+#ifndef __GLIBC__
+#define HASH_RANDOM_DECL       char *ps, rs[256]
+#define HASH_RANDOM_INIT(seed) ps = initstate(seed, rs, sizeof(rs))
+#define HASH_RANDOM            random()
+#define HASH_RANDOM_DESTROY    setstate(ps)
+#else
 #define HASH_RANDOM_DECL       struct random_data rd; int32_t rv; char rs[256]
 #define HASH_RANDOM_INIT(seed)                                 \
    do {                                                                \
    } while(0)
 #define HASH_RANDOM             ((void) random_r(&rd, &rv), rv)
 #define HASH_RANDOM_DESTROY
+#endif
 
 typedef struct __glxHashBucket
 {
index 7f6fb66d52f601b0d5625e089a44275bcb7c8791..a0225936c81648a133c1eec15b2ab95f2185b527 100644 (file)
@@ -229,7 +229,10 @@ intel_bufferobj_get_subdata(GLcontext * ctx,
    struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
 
    assert(intel_obj);
-   dri_bo_get_subdata(intel_obj->buffer, offset, size, data);
+   if (intel_obj->sys_buffer)
+      memcpy(data, (char *)intel_obj->sys_buffer + offset, size);
+   else
+      dri_bo_get_subdata(intel_obj->buffer, offset, size, data);
 }
 
 
index ac557a920052b4ae3ebe8a449118e3f30f437029..8f467e651440f56e802ca7fd43a0742e138c6614 100644 (file)
@@ -75,6 +75,7 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat)
    case GL_RGBA:
    case GL_RGBA8:
    case GL_RGB:
+   case GL_RGB8:
       return intel_readbuf_region(intel);
    default:
       return NULL;
index 3520c986b4761d6a28aa57674e912d2939a6bda7..c0fba8641b32283316c334b0a524ba77f5633535 100644 (file)
@@ -1693,53 +1693,6 @@ st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
 }
 
 
-/**
- * Compute which mipmap levels that really need to be sent to the hardware.
- * This depends on the base image size, GL_TEXTURE_MIN_LOD,
- * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
- */
-static void
-calculate_first_last_level(struct st_texture_object *stObj)
-{
-   struct gl_texture_object *tObj = &stObj->base;
-
-   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
-    * and having firstLevel and lastLevel as signed prevents the need for
-    * extra sign checks.
-    */
-   GLint firstLevel;
-   GLint lastLevel;
-
-   /* Yes, this looks overly complicated, but it's all needed.
-    */
-   switch (tObj->Target) {
-   case GL_TEXTURE_1D:
-   case GL_TEXTURE_2D:
-   case GL_TEXTURE_3D:
-   case GL_TEXTURE_CUBE_MAP:
-      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
-         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
-          */
-         firstLevel = lastLevel = tObj->BaseLevel;
-      }
-      else {
-         firstLevel = 0;
-         lastLevel = MIN2(tObj->MaxLevel,
-                          (int) tObj->Image[0][tObj->BaseLevel]->WidthLog2);
-      }
-      break;
-   case GL_TEXTURE_RECTANGLE_NV:
-   case GL_TEXTURE_4D_SGIS:
-      firstLevel = lastLevel = 0;
-      break;
-   default:
-      return;
-   }
-
-   stObj->lastLevel = lastLevel;
-}
-
-
 static void
 copy_image_data_to_texture(struct st_context *st,
                           struct st_texture_object *stObj,
@@ -1803,13 +1756,16 @@ st_finalize_texture(GLcontext *ctx,
 
    *needFlush = GL_FALSE;
 
-   /* We know/require this is true by now: 
-    */
-   assert(stObj->base._Complete);
+   if (stObj->base._Complete) {
+      /* The texture is complete and we know exactly how many mipmap levels
+       * are present/needed.  This is conditional because we may be called
+       * from the st_generate_mipmap() function when the texture object is
+       * incomplete.  In that case, we'll have set stObj->lastLevel before
+       * we get here.
+       */
+      stObj->lastLevel = stObj->base._MaxLevel - stObj->base.BaseLevel;
+   }
 
-   /* What levels must the texture include at a minimum?
-    */
-   calculate_first_last_level(stObj);
    firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
 
    /* If both firstImage and stObj point to a texture which can contain
index 58f693365232eb57603a61ab92450a33b36c620f..f75b2348b82cbdb43a8737e0b2270d4b9a2aaea8 100644 (file)
@@ -27,6 +27,7 @@
 
 
 #include "main/imports.h"
+#include "main/macros.h"
 #include "main/mipmap.h"
 #include "main/teximage.h"
 #include "main/texformat.h"
@@ -161,6 +162,43 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
 }
 
 
+/**
+ * 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
+ * level should be generated.
+ */
+static GLuint
+compute_num_levels(GLcontext *ctx,
+                   struct gl_texture_object *texObj,
+                   GLenum target)
+{
+   if (target == GL_TEXTURE_RECTANGLE_ARB) {
+      return 1;
+   }
+   else {
+      const GLuint maxLevels = texObj->MaxLevel - texObj->BaseLevel + 1;
+      const struct gl_texture_image *baseImage = 
+         _mesa_get_tex_image(ctx, texObj, target, texObj->BaseLevel);
+      GLuint size, numLevels;
+
+      size = MAX2(baseImage->Width2, baseImage->Height2);
+      size = MAX2(size, baseImage->Depth2);
+
+      numLevels = 0;
+
+      while (size > 0) {
+         numLevels++;
+         size >>= 1;
+      }
+
+      numLevels = MIN2(numLevels, maxLevels);
+
+      return numLevels;
+   }
+}
+
+
 void
 st_generate_mipmap(GLcontext *ctx, GLenum target,
                    struct gl_texture_object *texObj)
@@ -174,9 +212,49 @@ st_generate_mipmap(GLcontext *ctx, GLenum target,
    if (!pt)
       return;
 
-   lastLevel = pt->last_level;
+   /* find expected last mipmap level */
+   lastLevel = compute_num_levels(ctx, texObj, target) - 1;
+
+   if (pt->last_level < lastLevel) {
+      /* The current gallium texture doesn't have space for all the
+       * mipmap levels we need to generate.  So allocate a new texture.
+       */
+      struct st_texture_object *stObj = st_texture_object(texObj);
+      struct pipe_texture *oldTex = stObj->pt;
+      GLboolean needFlush;
+
+      /* create new texture with space for more levels */
+      stObj->pt = st_texture_create(st,
+                                    oldTex->target,
+                                    oldTex->format,
+                                    lastLevel,
+                                    oldTex->width[0],
+                                    oldTex->height[0],
+                                    oldTex->depth[0],
+                                    oldTex->tex_usage);
+
+      /* The texture isn't in a "complete" state yet so set the expected
+       * lastLevel here, since it won't get done in st_finalize_texture().
+       */
+      stObj->lastLevel = lastLevel;
+
+      /* This will copy the old texture's base image into the new texture
+       * which we just allocated.
+       */
+      st_finalize_texture(ctx, st->pipe, texObj, &needFlush);
+
+      /* release the old tex (will likely be freed too) */
+      pipe_texture_reference(&oldTex, NULL);
+
+      pt = stObj->pt;
+   }
+
+   assert(lastLevel <= pt->last_level);
 
-   if (!st_render_mipmap(st, target, pt, baseLevel, lastLevel)) {
+   /* Recall that the Mesa BaseLevel image is stored in the gallium
+    * texture's level[0] position.  So pass baseLevel=0 here.
+    */
+   if (!st_render_mipmap(st, target, pt, 0, lastLevel)) {
       fallback_generate_mipmap(ctx, target, texObj);
    }