From ebc1478e501d43e0de54e7b6c3edfbc81d7d20c6 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 2 Apr 2009 23:38:34 +0200 Subject: [PATCH] mesa: fix TexParameter functions premature return in TexParameterf caused mesa to never call Driver.TexParameter breaking drivers relying on this (fix bug #20966). While here, also fix using ctx->ErrorValue when deciding to call Driver.TexParameter. Errors are sticky and uncleared errors thus would cause this to no longer get called. Since we thus need return value of set_tex_parameter[if] can also optimize this to only call when value changed. --- src/mesa/main/texparam.c | 148 +++++++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 62 deletions(-) diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 15c4aa31216..515a35cdfcf 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -179,8 +179,11 @@ flush(GLcontext *ctx, struct gl_texture_object *texObj) } -/** Set an integer-valued texture parameter */ -static void +/** + * Set an integer-valued texture parameter + * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise + */ +static GLboolean set_tex_parameteri(GLcontext *ctx, struct gl_texture_object *texObj, GLenum pname, const GLint *params) @@ -188,13 +191,13 @@ set_tex_parameteri(GLcontext *ctx, switch (pname) { case GL_TEXTURE_MIN_FILTER: if (texObj->MinFilter == params[0]) - return; + return GL_FALSE; switch (params[0]) { case GL_NEAREST: case GL_LINEAR: flush(ctx, texObj); texObj->MinFilter = params[0]; - return; + return GL_TRUE; case GL_NEAREST_MIPMAP_NEAREST: case GL_LINEAR_MIPMAP_NEAREST: case GL_NEAREST_MIPMAP_LINEAR: @@ -202,90 +205,95 @@ set_tex_parameteri(GLcontext *ctx, if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) { flush(ctx, texObj); texObj->MinFilter = params[0]; - return; + return GL_TRUE; } /* fall-through */ default: _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); } - return; + return GL_FALSE; case GL_TEXTURE_MAG_FILTER: if (texObj->MagFilter == params[0]) - return; + return GL_FALSE; switch (params[0]) { case GL_NEAREST: case GL_LINEAR: flush(ctx, texObj); texObj->MagFilter = params[0]; - return; + return GL_TRUE; default: _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); } - return; + return GL_FALSE; case GL_TEXTURE_WRAP_S: if (texObj->WrapS == params[0]) - return; + return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { flush(ctx, texObj); texObj->WrapS = params[0]; + return GL_TRUE; } - return; + return GL_FALSE; case GL_TEXTURE_WRAP_T: if (texObj->WrapT == params[0]) - return; + return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { flush(ctx, texObj); texObj->WrapT = params[0]; + return GL_TRUE; } - return; + return GL_FALSE; case GL_TEXTURE_WRAP_R: if (texObj->WrapR == params[0]) - return; + return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { flush(ctx, texObj); texObj->WrapR = params[0]; + return GL_TRUE; } - return; + return GL_FALSE; case GL_TEXTURE_BASE_LEVEL: if (texObj->BaseLevel == params[0]) - return; + return GL_FALSE; if (params[0] < 0 || (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)"); - return; + return GL_FALSE; } flush(ctx, texObj); texObj->BaseLevel = params[0]; - return; + return GL_TRUE; case GL_TEXTURE_MAX_LEVEL: if (texObj->MaxLevel == params[0]) - return; + return GL_FALSE; if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)"); - return; + return GL_FALSE; } flush(ctx, texObj); texObj->MaxLevel = params[0]; - return; + return GL_TRUE; case GL_GENERATE_MIPMAP_SGIS: if (ctx->Extensions.SGIS_generate_mipmap) { if (texObj->GenerateMipmap != params[0]) { flush(ctx, texObj); texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; + return GL_TRUE; } + return GL_FALSE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)"); } - return; + return GL_FALSE; case GL_TEXTURE_COMPARE_MODE_ARB: if (ctx->Extensions.ARB_shadow && @@ -294,24 +302,26 @@ set_tex_parameteri(GLcontext *ctx, if (texObj->CompareMode != params[0]) { flush(ctx, texObj); texObj->CompareMode = params[0]; + return GL_TRUE; } + return GL_FALSE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)"); } - return; + return GL_FALSE; case GL_TEXTURE_COMPARE_FUNC_ARB: if (ctx->Extensions.ARB_shadow) { if (texObj->CompareFunc == params[0]) - return; + return GL_FALSE; switch (params[0]) { case GL_LEQUAL: case GL_GEQUAL: flush(ctx, texObj); texObj->CompareFunc = params[0]; - return; + return GL_TRUE; case GL_EQUAL: case GL_NOTEQUAL: case GL_LESS: @@ -321,7 +331,7 @@ set_tex_parameteri(GLcontext *ctx, if (ctx->Extensions.EXT_shadow_funcs) { flush(ctx, texObj); texObj->CompareFunc = params[0]; - return; + return GL_TRUE; } /* fall-through */ default: @@ -332,7 +342,7 @@ set_tex_parameteri(GLcontext *ctx, else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)"); } - return; + return GL_FALSE; case GL_DEPTH_TEXTURE_MODE_ARB: if (ctx->Extensions.ARB_depth_texture && @@ -342,13 +352,14 @@ set_tex_parameteri(GLcontext *ctx, if (texObj->DepthMode != params[0]) { flush(ctx, texObj); texObj->DepthMode = params[0]; + return GL_TRUE; } } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)"); } - return; + return GL_FALSE; #ifdef FEATURE_OES_draw_texture case GL_TEXTURE_CROP_RECT_OES: @@ -356,7 +367,7 @@ set_tex_parameteri(GLcontext *ctx, texObj->CropRect[1] = params[1]; texObj->CropRect[2] = params[2]; texObj->CropRect[3] = params[3]; - return; + return GL_TRUE; #endif case GL_TEXTURE_SWIZZLE_R_EXT: @@ -369,18 +380,18 @@ set_tex_parameteri(GLcontext *ctx, if (swz < 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(swizzle 0x%x)", params[0]); - return; + return GL_FALSE; } ASSERT(comp < 4); if (swz >= 0) { flush(ctx, texObj); texObj->Swizzle[comp] = params[0]; set_swizzle_component(&texObj->_Swizzle, comp, swz); - return; + return GL_TRUE; } } _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); - return; + return GL_FALSE; case GL_TEXTURE_SWIZZLE_RGBA_EXT: if (ctx->Extensions.EXT_texture_swizzle) { @@ -395,22 +406,26 @@ set_tex_parameteri(GLcontext *ctx, else { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(swizzle 0x%x)", params[comp]); - return; + return GL_FALSE; } } - return; + return GL_TRUE; } _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); - return; + return GL_FALSE; default: _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); } + return GL_FALSE; } -/** Set a float-valued texture parameter */ -static void +/** + * Set a float-valued texture parameter + * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise + */ +static GLboolean set_tex_parameterf(GLcontext *ctx, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params) @@ -418,54 +433,56 @@ set_tex_parameterf(GLcontext *ctx, switch (pname) { case GL_TEXTURE_MIN_LOD: if (texObj->MinLod == params[0]) - return; + return GL_FALSE; flush(ctx, texObj); texObj->MinLod = params[0]; - return; + return GL_TRUE; case GL_TEXTURE_MAX_LOD: if (texObj->MaxLod == params[0]) - return; + return GL_FALSE; flush(ctx, texObj); texObj->MaxLod = params[0]; - return; + return GL_TRUE; case GL_TEXTURE_PRIORITY: flush(ctx, texObj); texObj->Priority = CLAMP(params[0], 0.0F, 1.0F); - return; + return GL_TRUE; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { if (texObj->MaxAnisotropy == params[0]) - return; + return GL_FALSE; if (params[0] < 1.0) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); - return; + return GL_FALSE; } flush(ctx, texObj); /* clamp to max, that's what NVIDIA does */ texObj->MaxAnisotropy = MIN2(params[0], ctx->Const.MaxTextureMaxAnisotropy); + return GL_TRUE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); } - return; + return GL_FALSE; case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: if (ctx->Extensions.ARB_shadow_ambient) { if (texObj->CompareFailValue != params[0]) { flush(ctx, texObj); texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F); + return GL_TRUE; } } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)"); } - return; + return GL_FALSE; case GL_TEXTURE_LOD_BIAS: /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */ @@ -473,7 +490,9 @@ set_tex_parameterf(GLcontext *ctx, if (texObj->LodBias != params[0]) { flush(ctx, texObj); texObj->LodBias = params[0]; + return GL_TRUE; } + return GL_FALSE; } break; @@ -483,17 +502,19 @@ set_tex_parameterf(GLcontext *ctx, texObj->BorderColor[GCOMP] = params[1]; texObj->BorderColor[BCOMP] = params[2]; texObj->BorderColor[ACOMP] = params[3]; - return; + return GL_TRUE; default: _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); } + return GL_FALSE; } void GLAPIENTRY _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) { + GLboolean need_update; struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -517,15 +538,15 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) { /* convert float param to int */ GLint p = (GLint) param; - set_tex_parameteri(ctx, texObj, pname, &p); + need_update = set_tex_parameteri(ctx, texObj, pname, &p); } - return; + break; default: /* this will generate an error if pname is illegal */ - set_tex_parameterf(ctx, texObj, pname, ¶m); + need_update = set_tex_parameterf(ctx, texObj, pname, ¶m); } - if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) { + if (ctx->Driver.TexParameter && need_update) { ctx->Driver.TexParameter(ctx, target, texObj, pname, ¶m); } } @@ -534,6 +555,7 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) void GLAPIENTRY _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { + GLboolean need_update; struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -557,7 +579,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { /* convert float param to int */ GLint p = (GLint) params[0]; - set_tex_parameteri(ctx, texObj, pname, &p); + need_update = set_tex_parameteri(ctx, texObj, pname, &p); } break; @@ -570,17 +592,17 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) iparams[1] = (GLint) params[1]; iparams[2] = (GLint) params[2]; iparams[3] = (GLint) params[3]; - set_tex_parameteri(ctx, target, iparams); + need_update = set_tex_parameteri(ctx, target, iparams); } break; #endif default: /* this will generate an error if pname is illegal */ - set_tex_parameterf(ctx, texObj, pname, params); + need_update = set_tex_parameterf(ctx, texObj, pname, params); } - if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) { + if (ctx->Driver.TexParameter && need_update) { ctx->Driver.TexParameter(ctx, target, texObj, pname, params); } } @@ -589,6 +611,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) void GLAPIENTRY _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) { + GLboolean need_update; struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -607,15 +630,15 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) { GLfloat fparam = (GLfloat) param; /* convert int param to float */ - set_tex_parameterf(ctx, texObj, pname, &fparam); + need_update = set_tex_parameterf(ctx, texObj, pname, &fparam); } break; default: /* this will generate an error if pname is illegal */ - set_tex_parameteri(ctx, texObj, pname, ¶m); + need_update = set_tex_parameteri(ctx, texObj, pname, ¶m); } - if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) { + if (ctx->Driver.TexParameter && need_update) { GLfloat fparam = (GLfloat) param; ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam); } @@ -625,6 +648,7 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) void GLAPIENTRY _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) { + GLboolean need_update; struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -642,7 +666,7 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) fparams[1] = INT_TO_FLOAT(params[1]); fparams[2] = INT_TO_FLOAT(params[2]); fparams[3] = INT_TO_FLOAT(params[3]); - set_tex_parameterf(ctx, texObj, pname, fparams); + need_update = set_tex_parameterf(ctx, texObj, pname, fparams); } break; case GL_TEXTURE_MIN_LOD: @@ -654,15 +678,15 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) { /* convert int param to float */ GLfloat fparam = (GLfloat) params[0]; - set_tex_parameterf(ctx, texObj, pname, &fparam); + need_update = set_tex_parameterf(ctx, texObj, pname, &fparam); } break; default: /* this will generate an error if pname is illegal */ - set_tex_parameteri(ctx, texObj, pname, params); + need_update = set_tex_parameteri(ctx, texObj, pname, params); } - if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) { + if (ctx->Driver.TexParameter && need_update) { GLfloat fparams[4]; fparams[0] = INT_TO_FLOAT(params[0]); if (pname == GL_TEXTURE_BORDER_COLOR || -- 2.30.2