[Mesa-dev] [PATCH 1/3] mesa: Fold gallium's texture border stripping into a core Mesa option.
Eric Anholt
eric at anholt.net
Mon Oct 24 16:15:57 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..3309119 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1457,6 +1457,20 @@ struct gl_texture_attrib
/** GL_ARB_seamless_cubemap */
GLboolean CubeMapSeamless;
+ /**
+ * 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;
+
/** Texture units/samplers used by vertex or fragment texturing */
GLbitfield _EnabledUnits;
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 798201a..f1d1a7c 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->Texture.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..a143f8a 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;
}
+
+ st->ctx->Texture.StripTextureBorder = GL_TRUE;
}
--
1.7.7
More information about the mesa-dev
mailing list