From 17c7852bf93c4d4edf0c2cf0bdc553d399e2f51a Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Fri, 27 Feb 2009 00:21:07 -0700 Subject: i965: texture fixes: bordered textures, fallback rendering i965 doesn't natively support GL_CLAMP; it treats it like GL_CLAMP_TO_EDGE, which fails conformance tests. This fix adds a clause to the check_fallbacks() test to check whether GL_CLAMP is in use on any enabled 2D texture. If so, and if strict conformance is required (via INTEL_STRICT_CONFORMANCE), a software fallback is mandated. In addition, validate textures *before* checking for fallbacks, rather than after; otherwise, the texture state is never validated and can't be trusted. (In particular, if texturing is enabled and the sampler would access any level beyond level 0 of a texture, the sampler will segfault, because texture validation sets the firstLevel and lastLevel fields of a texture object so that the valid levels will be mapped and accessed correctly. If texture validation doesn't occur, only level 0 is accessed correctly, and that only because firstLevel and lastLevel happen to be set to 0.) --- src/mesa/drivers/dri/i965/brw_draw.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri/i965') diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 3ca953da37..7ab1ece263 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -194,6 +194,9 @@ static GLboolean check_fallbacks( struct brw_context *brw, GLcontext *ctx = &brw->intel.ctx; GLuint i; + /* If we don't require strict OpenGL conformance, never + * use fallbacks. + */ if (!brw->intel.strict_conformance) return GL_FALSE; @@ -230,13 +233,31 @@ static GLboolean check_fallbacks( struct brw_context *brw, } } - if (ctx->Point.SmoothFlag) { for (i = 0; i < nr_prims; i++) if (prim[i].mode == GL_POINTS) return GL_TRUE; } + + /* BRW hardware doesn't handle GL_CLAMP texturing correctly; + * brw_wm_sampler_state:translate_wrap_mode() treats GL_CLAMP + * as GL_CLAMP_TO_EDGE instead. If we're using GL_CLAMP, and + * we want strict conformance, force the fallback. + * Right now, we only do this for 2D textures. + */ + { + int u; + for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { + if (ctx->Texture.Unit[u].Enabled) { + if (ctx->Texture.Unit[u].CurrentTex[TEXTURE_2D_INDEX]->WrapS == GL_CLAMP || + ctx->Texture.Unit[u].CurrentTex[TEXTURE_2D_INDEX]->WrapT == GL_CLAMP) { + return GL_TRUE; + } + } + } + } + /* Nothing stopping us from the fast path now */ return GL_FALSE; } @@ -261,11 +282,18 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, if (ctx->NewState) _mesa_update_state( ctx ); + /* We have to validate the textures *before* checking for fallbacks; + * otherwise, the software fallback won't be able to rely on the + * texture state, the firstLevel and lastLevel fields won't be + * set in the intel texture object (they'll both be 0), and the + * software fallback will segfault if it attempts to access any + * texture level other than level 0. + */ + brw_validate_textures( brw ); + if (check_fallbacks(brw, prim, nr_prims)) return GL_FALSE; - brw_validate_textures( brw ); - /* Bind all inputs, derive varying and size information: */ brw_merge_inputs( brw, arrays ); -- cgit v1.2.3