X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexparam.c;h=e60ab6aa123a6f105cff51c7b1d3b1eb5bfe8690;hb=4147bb24d49a10498e00039fc1dc9aa5f1316777;hp=8df22fe9e2e0a5321549435c82b88602bfd1f9d8;hpb=ee4c921b65fb76998711f3c40330505cbc49a0e0;p=mesa.git diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 8df22fe9e2e..e60ab6aa123 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -3,7 +3,7 @@ * Version: 7.5 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 1999-2009 VMware, Inc. All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -69,7 +69,7 @@ validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap) return GL_TRUE; } - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", wrap ); return GL_FALSE; } @@ -92,29 +92,29 @@ get_texobj(GLcontext *ctx, GLenum target) switch (target) { case GL_TEXTURE_1D: - return texUnit->Current1D; + return texUnit->CurrentTex[TEXTURE_1D_INDEX]; case GL_TEXTURE_2D: - return texUnit->Current2D; + return texUnit->CurrentTex[TEXTURE_2D_INDEX]; case GL_TEXTURE_3D: - return texUnit->Current3D; + return texUnit->CurrentTex[TEXTURE_3D_INDEX]; case GL_TEXTURE_CUBE_MAP: if (ctx->Extensions.ARB_texture_cube_map) { - return texUnit->CurrentCubeMap; + return texUnit->CurrentTex[TEXTURE_CUBE_INDEX]; } break; case GL_TEXTURE_RECTANGLE_NV: if (ctx->Extensions.NV_texture_rectangle) { - return texUnit->CurrentRect; + return texUnit->CurrentTex[TEXTURE_RECT_INDEX]; } break; case GL_TEXTURE_1D_ARRAY_EXT: if (ctx->Extensions.MESA_texture_array) { - return texUnit->Current1DArray; + return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX]; } break; case GL_TEXTURE_2D_ARRAY_EXT: if (ctx->Extensions.MESA_texture_array) { - return texUnit->Current2DArray; + return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX]; } break; default: @@ -165,8 +165,25 @@ set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) } -/** Set an integer-valued texture parameter */ -static void +/** + * This is called just prior to changing any texture object state. + * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE + * state flag and then mark the texture object as 'incomplete' so that any + * per-texture derived state gets recomputed. + */ +static INLINE void +flush(GLcontext *ctx, struct gl_texture_object *texObj) +{ + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texObj->_Complete = GL_FALSE; +} + + +/** + * 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) @@ -174,124 +191,141 @@ 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_VERTICES(ctx, _NEW_TEXTURE); + 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: case GL_LINEAR_MIPMAP_LINEAR: if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); texObj->MinFilter = params[0]; - return; + return GL_TRUE; } /* fall-through */ default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + params[0] ); } - 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_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); texObj->MagFilter = params[0]; - return; + return GL_TRUE; default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + params[0]); } - 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_VERTICES(ctx, _NEW_TEXTURE); + 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_VERTICES(ctx, _NEW_TEXTURE); + 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_VERTICES(ctx, _NEW_TEXTURE); + 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; + _mesa_error(ctx, GL_INVALID_VALUE, + "glTexParameter(param=%d)", params[0]); + return GL_FALSE; } - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + 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; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexParameter(param=%d)", params[0]); + return GL_FALSE; } - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); texObj->MaxLevel = params[0]; - return; + return GL_TRUE; case GL_GENERATE_MIPMAP_SGIS: if (ctx->Extensions.SGIS_generate_mipmap) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; + 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 && (params[0] == GL_NONE || params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->CompareMode = params[0]; + 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 GL_FALSE; switch (params[0]) { case GL_LEQUAL: case GL_GEQUAL: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); texObj->CompareFunc = params[0]; - return; + return GL_TRUE; case GL_EQUAL: case GL_NOTEQUAL: case GL_LESS: @@ -299,9 +333,9 @@ set_tex_parameteri(GLcontext *ctx, case GL_ALWAYS: case GL_NEVER: if (ctx->Extensions.EXT_shadow_funcs) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); texObj->CompareFunc = params[0]; - return; + return GL_TRUE; } /* fall-through */ default: @@ -310,23 +344,26 @@ set_tex_parameteri(GLcontext *ctx, } } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); } - return; + return GL_FALSE; case GL_DEPTH_TEXTURE_MODE_ARB: if (ctx->Extensions.ARB_depth_texture && (params[0] == GL_LUMINANCE || params[0] == GL_INTENSITY || params[0] == GL_ALPHA)) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->DepthMode = params[0]; + 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: @@ -334,7 +371,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: @@ -347,23 +384,23 @@ 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_VERTICES(ctx, _NEW_TEXTURE); + 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) { GLuint comp; - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); for (comp = 0; comp < 4; comp++) { const GLint swz = comp_to_swizzle(params[comp]); if (swz >= 0) { @@ -373,22 +410,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) @@ -396,82 +437,88 @@ set_tex_parameterf(GLcontext *ctx, switch (pname) { case GL_TEXTURE_MIN_LOD: if (texObj->MinLod == params[0]) - return; - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + 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; - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + return GL_FALSE; + flush(ctx, texObj); texObj->MaxLod = params[0]; - return; + return GL_TRUE; case GL_TEXTURE_PRIORITY: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + 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 GL_FALSE; if (params[0] < 1.0) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); - return; + return GL_FALSE; } - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + 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) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F); + 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 */ if (ctx->Extensions.EXT_texture_lod_bias) { if (texObj->LodBias != params[0]) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); texObj->LodBias = params[0]; + return GL_TRUE; } + return GL_FALSE; } break; case GL_TEXTURE_BORDER_COLOR: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + flush(ctx, texObj); texObj->BorderColor[RCOMP] = params[0]; texObj->BorderColor[GCOMP] = params[1]; texObj->BorderColor[BCOMP] = params[2]; texObj->BorderColor[ACOMP] = params[3]; - UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]); - UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]); - UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]); - UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[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); @@ -495,17 +542,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); } - texObj->_Complete = GL_FALSE; - - if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) { + if (ctx->Driver.TexParameter && need_update) { ctx->Driver.TexParameter(ctx, target, texObj, pname, ¶m); } } @@ -514,6 +559,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); @@ -537,7 +583,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; @@ -550,19 +596,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); } - texObj->_Complete = GL_FALSE; - - if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) { + if (ctx->Driver.TexParameter && need_update) { ctx->Driver.TexParameter(ctx, target, texObj, pname, params); } } @@ -571,6 +615,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); @@ -589,17 +634,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); } - texObj->_Complete = GL_FALSE; - - 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); } @@ -609,6 +652,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); @@ -626,7 +670,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: @@ -638,17 +682,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); } - texObj->_Complete = GL_FALSE; - - 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 ||