mesa: Fold gallium's texture border stripping into a core Mesa option.
authorEric Anholt <eric@anholt.net>
Mon, 17 Oct 2011 21:30:26 +0000 (14:30 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 26 Oct 2011 19:42:17 +0000 (12:42 -0700)
We wanted to reuse this in the Intel driver.

v2: Move the flag to ctx->Const

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> (v1)
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/mtypes.h
src/mesa/main/teximage.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_extensions.c

index 719dff3af2e81bde670b183493b4bf1d4941797f..4117686414ea201e6e83d0b9f5d18d2e5aa7f2ac 100644 (file)
@@ -2732,6 +2732,20 @@ struct gl_constants
 
    /* GL_ARB_robustness */
    GLenum ResetStrategy;
+
+   /**
+    * Whether the implementation strips out and ignores texture borders.
+    *
+    * Many GPU hardware implementations don't support rendering with texture
+    * borders and mipmapped textures.  (Note: not static border color, but the
+    * old 1-pixel border around each edge).  Implementations then have to do
+    * slow fallbacks to be correct, or just ignore the border and be fast but
+    * wrong.  Setting the flag stripts the border off of TexImage calls,
+    * providing "fast but wrong" at significantly reduced driver complexity.
+    *
+    * Texture borders are deprecated in GL 3.0.
+    **/
+   GLboolean StripTextureBorder;
 };
 
 
index 798201a60b0703376ddf46e4c4cdea19628b0fd1..a93ae946ea5c3c3db0ae87b9eee904444b3f7729 100644 (file)
@@ -2246,6 +2246,45 @@ _mesa_choose_texture_format(struct gl_context *ctx,
    return f;
 }
 
+/**
+ * Adjust pixel unpack params and image dimensions to strip off the
+ * texture border.
+ *
+ * Gallium and intel don't support texture borders.  They've seldem been used
+ * and seldom been implemented correctly anyway.
+ *
+ * \param unpackNew returns the new pixel unpack parameters
+ */
+static void
+strip_texture_border(GLint *border,
+                     GLint *width, GLint *height, GLint *depth,
+                     const struct gl_pixelstore_attrib *unpack,
+                     struct gl_pixelstore_attrib *unpackNew)
+{
+   assert(*border > 0);  /* sanity check */
+
+   *unpackNew = *unpack;
+
+   if (unpackNew->RowLength == 0)
+      unpackNew->RowLength = *width;
+
+   if (depth && unpackNew->ImageHeight == 0)
+      unpackNew->ImageHeight = *height;
+
+   unpackNew->SkipPixels += *border;
+   if (height)
+      unpackNew->SkipRows += *border;
+   if (depth)
+      unpackNew->SkipImages += *border;
+
+   assert(*width >= 3);
+   *width = *width - 2 * *border;
+   if (height && *height >= 3)
+      *height = *height - 2 * *border;
+   if (depth && *depth >= 3)
+      *depth = *depth - 2 * *border;
+   *border = 0;
+}
 
 /**
  * Common code to implement all the glTexImage1D/2D/3D functions.
@@ -2258,6 +2297,8 @@ teximage(struct gl_context *ctx, GLuint dims,
          const GLvoid *pixels)
 {
    GLboolean error;
+   struct gl_pixelstore_attrib unpack_no_border;
+   const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
@@ -2322,6 +2363,16 @@ teximage(struct gl_context *ctx, GLuint dims,
          return;   /* error was recorded */
       }
 
+      /* Allow a hardware driver to just strip out the border, to provide
+       * reliable but slightly incorrect hardware rendering instead of
+       * rarely-tested software fallback rendering.
+       */
+      if (border && ctx->Const.StripTextureBorder) {
+        strip_texture_border(&border, &width, &height, &depth, unpack,
+                             &unpack_no_border);
+        unpack = &unpack_no_border;
+      }
+
       if (ctx->NewState & _NEW_PIXEL)
         _mesa_update_state(ctx);
 
@@ -2354,19 +2405,19 @@ teximage(struct gl_context *ctx, GLuint dims,
                case 1:
                   ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
                                          width, border, format,
-                                         type, pixels, &ctx->Unpack, texObj,
+                                         type, pixels, unpack, texObj,
                                          texImage);
                   break;
                case 2:
                   ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
                                          width, height, border, format,
-                                         type, pixels, &ctx->Unpack, texObj,
+                                         type, pixels, unpack, texObj,
                                          texImage);
                   break;
                case 3:
                   ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
                                          width, height, depth, border, format,
-                                         type, pixels, &ctx->Unpack, texObj,
+                                         type, pixels, unpack, texObj,
                                          texImage);
                   break;
                default:
index 169e235ac4776f2ae677c76d0371b3ef4d8c0a22..f82346bc67203fe3a46c1fddcf49838e693e582e 100644 (file)
@@ -543,45 +543,6 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
    }
 }
 
-
-/**
- * Adjust pixel unpack params and image dimensions to strip off the
- * texture border.
- * Gallium doesn't support texture borders.  They've seldem been used
- * and seldom been implemented correctly anyway.
- * \param unpackNew  returns the new pixel unpack parameters
- */
-static void
-strip_texture_border(GLint border,
-                     GLint *width, GLint *height, GLint *depth,
-                     const struct gl_pixelstore_attrib *unpack,
-                     struct gl_pixelstore_attrib *unpackNew)
-{
-   assert(border > 0);  /* sanity check */
-
-   *unpackNew = *unpack;
-
-   if (unpackNew->RowLength == 0)
-      unpackNew->RowLength = *width;
-
-   if (depth && unpackNew->ImageHeight == 0)
-      unpackNew->ImageHeight = *height;
-
-   unpackNew->SkipPixels += border;
-   if (height)
-      unpackNew->SkipRows += border;
-   if (depth)
-      unpackNew->SkipImages += border;
-
-   assert(*width >= 3);
-   *width = *width - 2 * border;
-   if (height && *height >= 3)
-      *height = *height - 2 * border;
-   if (depth && *depth >= 3)
-      *depth = *depth - 2 * border;
-}
-
-
 /**
  * Do glTexImage1/2/3D().
  */
@@ -602,7 +563,6 @@ st_TexImage(struct gl_context * ctx,
    struct st_texture_object *stObj = st_texture_object(texObj);
    struct st_texture_image *stImage = st_texture_image(texImage);
    GLuint dstRowStride = 0;
-   struct gl_pixelstore_attrib unpackNB;
    enum pipe_transfer_usage transfer_usage = 0;
    GLubyte *dstMap;
 
@@ -627,21 +587,9 @@ st_TexImage(struct gl_context * ctx,
       stObj->surface_based = GL_FALSE;
    }
 
-   /* gallium does not support texture borders, strip it off */
-   if (border) {
-      strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
-      unpack = &unpackNB;
-      texImage->Width = width;
-      texImage->Height = height;
-      texImage->Depth = depth;
-      texImage->Border = 0;
-      border = 0;
-   }
-   else {
-      assert(texImage->Width == width);
-      assert(texImage->Height == height);
-      assert(texImage->Depth == depth);
-   }
+   assert(texImage->Width == width);
+   assert(texImage->Height == height);
+   assert(texImage->Depth == depth);
 
    stImage->base.Face = _mesa_tex_target_to_face(target);
    stImage->base.Level = level;
index 37f36de93816c9d12c621767a6f58cc739d2f00a..6b9ff6b720021e1b42b5925211cf5974194129e9 100644 (file)
@@ -222,6 +222,8 @@ void st_init_limits(struct st_context *st)
       _mesa_override_glsl_version(st->ctx);
       c->UniformBooleanTrue = ~0;
    }
+
+   c->StripTextureBorder = GL_TRUE;
 }