From 9c4b02528752eb6392009e41025202fc9f9ca5b3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 17 Oct 2011 14:30:26 -0700 Subject: [PATCH] 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 (v1) Reviewed-by: Brian Paul --- 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 719dff3af2e..4117686414e 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 798201a60b0..a93ae946ea5 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 169e235ac47..f82346bc672 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 37f36de9381..6b9ff6b7200 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; } -- 2.30.2