[Mesa-dev] [PATCH 2/5] mesa: Fold gallium's texture border stripping into a core Mesa option.

Eric Anholt eric at anholt.net
Tue Oct 25 14:58:53 PDT 2011


We wanted to reuse this in the Intel driver.
---
 src/mesa/main/mtypes.h                 |   14 ++++++++
 src/mesa/main/teximage.c               |   57 +++++++++++++++++++++++++++++--
 src/mesa/state_tracker/st_cb_texture.c |   58 ++------------------------------
 src/mesa/state_tracker/st_extensions.c |    2 +
 4 files changed, 73 insertions(+), 58 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 719dff3..4117686 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -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;
 };
 
 
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 798201a..a93ae94 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -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:
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 169e235..f82346b 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -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;
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 37f36de..6b9ff6b 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -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;
 }
 
 
-- 
1.7.7



More information about the mesa-dev mailing list