Commit 9c4b0252 authored by Eric Anholt's avatar Eric Anholt

mesa: Fold gallium's texture border stripping into a core Mesa option.

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's avatarBrian Paul <brianp@vmware.com>
parent b31104e3
......@@ -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;
};
......
......@@ -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:
......
......@@ -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;
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment