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 <brianp@vmware.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user