diff --git a/src/kits/opengl/mesa/main/attrib.c b/src/kits/opengl/mesa/main/attrib.c index ef1273d82d..a54951205f 100644 --- a/src/kits/opengl/mesa/main/attrib.c +++ b/src/kits/opengl/mesa/main/attrib.c @@ -1176,7 +1176,7 @@ _mesa_PopAttrib(void) /* restore clip planes */ for (i = 0; i < MAX_CLIP_PLANES; i++) { - const GLuint mask = 1 << 1; + const GLuint mask = 1 << i; const GLfloat *eyePlane = xform->EyeUserPlane[i]; COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane); if (xform->ClipPlanesEnabled & mask) { diff --git a/src/kits/opengl/mesa/main/drawpix.c b/src/kits/opengl/mesa/main/drawpix.c index ac97bc1ff9..cb837de4dd 100644 --- a/src/kits/opengl/mesa/main/drawpix.c +++ b/src/kits/opengl/mesa/main/drawpix.c @@ -77,28 +77,30 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, } if (ctx->RenderMode == GL_RENDER) { - /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ - GLint x = IROUND(ctx->Current.RasterPos[0]); - GLint y = IROUND(ctx->Current.RasterPos[1]); + if (width > 0 && height > 0) { + /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ + GLint x = IROUND(ctx->Current.RasterPos[0]); + GLint y = IROUND(ctx->Current.RasterPos[1]); - if (ctx->Unpack.BufferObj->Name) { - /* unpack from PBO */ - if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glDrawPixels(invalid PBO access)"); - return; - } - if (ctx->Unpack.BufferObj->Pointer) { - /* buffer is mapped - that's an error */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glDrawPixels(PBO is mapped)"); - return; + if (ctx->Unpack.BufferObj->Name) { + /* unpack from PBO */ + if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(invalid PBO access)"); + return; + } + if (ctx->Unpack.BufferObj->Pointer) { + /* buffer is mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawPixels(PBO is mapped)"); + return; + } } + + ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type, + &ctx->Unpack, pixels); } - - ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type, - &ctx->Unpack, pixels); } else if (ctx->RenderMode == GL_FEEDBACK) { /* Feedback the current raster pos info */ @@ -159,10 +161,12 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, if (ctx->RenderMode == GL_RENDER) { /* Round to satisfy conformance tests (matches SGI's OpenGL) */ - GLint destx = IROUND(ctx->Current.RasterPos[0]); - GLint desty = IROUND(ctx->Current.RasterPos[1]); - ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, - type ); + if (width > 0 && height > 0) { + GLint destx = IROUND(ctx->Current.RasterPos[0]); + GLint desty = IROUND(ctx->Current.RasterPos[1]); + ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, + type ); + } } else if (ctx->RenderMode == GL_FEEDBACK) { FLUSH_CURRENT( ctx, 0 ); diff --git a/src/kits/opengl/mesa/main/ffvertex_prog.c b/src/kits/opengl/mesa/main/ffvertex_prog.c index cc1b44de64..4321b4c2eb 100644 --- a/src/kits/opengl/mesa/main/ffvertex_prog.c +++ b/src/kits/opengl/mesa/main/ffvertex_prog.c @@ -1104,6 +1104,9 @@ static void build_lighting( struct tnl_program *p ) if (twoside) { if (!p->state->material_shininess_is_zero) { + /* Note that we negate the back-face specular exponent here. + * The negation will be un-done later in the back-face code below. + */ struct ureg shininess = get_material(p, 1, STATE_SHININESS); emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, negate(swizzle1(shininess,X))); @@ -1309,6 +1312,11 @@ static void build_lighting( struct tnl_program *p ) mask1 = 0; } + /* For the back face we need to negate the X and Y component + * dot products. dots.Z has the negated back-face specular + * exponent. We swizzle that into the W position. This + * negation makes the back-face specular term positive again. + */ dots = negate(swizzle(dots,X,Y,W,Z)); if (!is_undef(att)) { @@ -1327,8 +1335,10 @@ static void build_lighting( struct tnl_program *p ) emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); - /* restore negate flag for next lighting */ - dots = negate(dots); + /* restore dots to its original state for subsequent lights + * by negating and swizzling again. + */ + dots = negate(swizzle(dots,X,Y,W,Z)); release_temp(p, ambient); release_temp(p, diffuse); diff --git a/src/kits/opengl/mesa/main/glheader.h b/src/kits/opengl/mesa/main/glheader.h index 6ec940c6d4..3aad113bf6 100644 --- a/src/kits/opengl/mesa/main/glheader.h +++ b/src/kits/opengl/mesa/main/glheader.h @@ -142,17 +142,20 @@ * For now, only used by some DRI hardware drivers for color/texel packing. */ #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN - #if defined(__linux__) - #include - #define CPU_TO_LE32( x ) bswap_32( x ) - #elif defined(__BEOS__) || defined(__HAIKU__) - #include - #define CPU_TO_LE32( x ) B_HOST_TO_LENDIAN_INT32( x ) - #else - #include - #define CPU_TO_LE32( x ) bswap32( x ) - #endif - #define MESA_BIG_ENDIAN 1 +#if defined(__linux__) +#include +#define CPU_TO_LE32( x ) bswap_32( x ) +#elif defined(__APPLE__) +#include +#define CPU_TO_LE32( x ) CFSwapInt32HostToLittle( x ) +#elif defined(__BEOS__) || defined(__HAIKU__) +#include +#define CPU_TO_LE32( x ) B_HOST_TO_LENDIAN_INT32( x ) +#else /*__linux__ __APPLE__ __BEOS__ __HAIKU__ */ +#include +#define CPU_TO_LE32( x ) bswap32( x ) +#endif /*__linux__*/ +#define MESA_BIG_ENDIAN 1 #else #define CPU_TO_LE32( x ) ( x ) #define MESA_LITTLE_ENDIAN 1 diff --git a/src/kits/opengl/mesa/main/hash.c b/src/kits/opengl/mesa/main/hash.c index 976f9d999b..08c64568c8 100644 --- a/src/kits/opengl/mesa/main/hash.c +++ b/src/kits/opengl/mesa/main/hash.c @@ -63,6 +63,7 @@ struct _mesa_HashTable { struct HashEntry *Table[TABLE_SIZE]; /**< the lookup table */ GLuint MaxKey; /**< highest key inserted so far */ _glthread_Mutex Mutex; /**< mutual exclusion lock */ + _glthread_Mutex WalkMutex; /**< for _mesa_HashWalk() */ GLboolean InDeleteAll; /**< Debug check */ }; @@ -79,6 +80,7 @@ _mesa_NewHashTable(void) struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable); if (table) { _glthread_INIT_MUTEX(table->Mutex); + _glthread_INIT_MUTEX(table->WalkMutex); } return table; } @@ -111,6 +113,7 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table) } } _glthread_DESTROY_MUTEX(table->Mutex); + _glthread_DESTROY_MUTEX(table->WalkMutex); _mesa_free(table); } @@ -285,6 +288,11 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table, /** * Walk over all entries in a hash table, calling callback function for each. + * Note: we use a separate mutex in this function to avoid a recursive + * locking deadlock (in case the callback calls _mesa_HashRemove()) and to + * prevent multiple threads/contexts from getting tangled up. + * A lock-less version of this function could be used when the table will + * not be modified. * \param table the hash table to walk * \param callback the callback function * \param userData arbitrary pointer to pass along to the callback @@ -300,14 +308,16 @@ _mesa_HashWalk(const struct _mesa_HashTable *table, GLuint pos; ASSERT(table); ASSERT(callback); - _glthread_LOCK_MUTEX(table2->Mutex); + _glthread_LOCK_MUTEX(table2->WalkMutex); for (pos = 0; pos < TABLE_SIZE; pos++) { - struct HashEntry *entry; - for (entry = table->Table[pos]; entry; entry = entry->Next) { + struct HashEntry *entry, *next; + for (entry = table->Table[pos]; entry; entry = next) { + /* save 'next' pointer now in case the callback deletes the entry */ + next = entry->Next; callback(entry->Key, entry->Data, userData); } } - _glthread_UNLOCK_MUTEX(table2->Mutex); + _glthread_UNLOCK_MUTEX(table2->WalkMutex); } diff --git a/src/kits/opengl/mesa/main/light.c b/src/kits/opengl/mesa/main/light.c index ce50224d30..4372f7bb53 100644 --- a/src/kits/opengl/mesa/main/light.c +++ b/src/kits/opengl/mesa/main/light.c @@ -209,7 +209,6 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); } TRANSFORM_DIRECTION(temp, params, ctx->ModelviewMatrixStack.Top->m); - NORMALIZE_3FV(temp); params = temp; break; case GL_SPOT_EXPONENT: @@ -1137,12 +1136,18 @@ compute_light_positions( GLcontext *ctx ) } if (light->_Flags & LIGHT_SPOT) { + /* Note: we normalize the spot direction now */ + if (ctx->_NeedEyeCoords) { COPY_3V( light->_NormDirection, light->EyeDirection ); + NORMALIZE_3FV( light->_NormDirection ); } else { + GLfloat spotDir[3]; + COPY_3V(spotDir, light->EyeDirection); + NORMALIZE_3FV(spotDir); TRANSFORM_NORMAL( light->_NormDirection, - light->EyeDirection, + spotDir, ctx->ModelviewMatrixStack.Top->m); } diff --git a/src/kits/opengl/mesa/main/readpix.c b/src/kits/opengl/mesa/main/readpix.c index dfdd297b6e..2326776ecb 100644 --- a/src/kits/opengl/mesa/main/readpix.c +++ b/src/kits/opengl/mesa/main/readpix.c @@ -170,6 +170,9 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, return; } + if (width == 0 || height == 0) + return; /* nothing to do */ + if (ctx->Pack.BufferObj->Name) { if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1, format, type, pixels)) { diff --git a/src/kits/opengl/mesa/main/teximage.c b/src/kits/opengl/mesa/main/teximage.c index d5f9d2feec..cd3edb2e07 100644 --- a/src/kits/opengl/mesa/main/teximage.c +++ b/src/kits/opengl/mesa/main/teximage.c @@ -49,6 +49,17 @@ #include "mtypes.h" +/** + * State changes which we care about for glCopyTex[Sub]Image() calls. + * In particular, we care about pixel transfer state and buffer state + * (such as glReadBuffer to make sure we read from the right renderbuffer). + */ +#define NEW_COPY_TEX_STATE (_IMAGE_NEW_TRANSFER_STATE | \ + _NEW_BUFFERS | \ + _NEW_PIXEL) + + + /** * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE * elsewhere. @@ -2918,7 +2929,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); #if FEATURE_convolve @@ -2983,7 +2994,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); #if FEATURE_convolve @@ -3051,7 +3062,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 1, target, level)) @@ -3106,7 +3117,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 2, target, level)) @@ -3161,7 +3172,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 3, target, level)) diff --git a/src/kits/opengl/mesa/main/texparam.c b/src/kits/opengl/mesa/main/texparam.c index be4fc1dc4a..e89bc5fb9d 100644 --- a/src/kits/opengl/mesa/main/texparam.c +++ b/src/kits/opengl/mesa/main/texparam.c @@ -139,8 +139,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) @@ -148,13 +151,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: @@ -162,77 +165,80 @@ 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_TEXTURE_COMPARE_SGIX: if (ctx->Extensions.SGIX_shadow) { @@ -243,7 +249,7 @@ set_tex_parameteri(GLcontext *ctx, _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)"); } - return; + return GL_TRUE; case GL_TEXTURE_COMPARE_OPERATOR_SGIX: if (ctx->Extensions.SGIX_shadow && @@ -256,20 +262,22 @@ set_tex_parameteri(GLcontext *ctx, _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(GL_TEXTURE_COMPARE_OPERATOR_SGIX)"); } - 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 && @@ -278,24 +286,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: @@ -305,7 +315,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: @@ -316,7 +326,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 && @@ -326,13 +336,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: @@ -340,17 +351,21 @@ set_tex_parameteri(GLcontext *ctx, texObj->CropRect[1] = params[1]; texObj->CropRect[2] = params[2]; texObj->CropRect[3] = params[3]; - break; + return GL_TRUE; #endif 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) @@ -358,54 +373,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.SGIX_shadow_ambient) { if (texObj->ShadowAmbient != params[0]) { flush(ctx, texObj); texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F); + return GL_TRUE; } } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)"); } - return; + return GL_FALSE; case GL_TEXTURE_LOD_BIAS: /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */ @@ -413,7 +430,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; @@ -427,17 +446,19 @@ set_tex_parameterf(GLcontext *ctx, 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); @@ -463,15 +484,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); } } @@ -480,6 +501,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); @@ -505,7 +527,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; @@ -518,17 +540,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); } } @@ -537,6 +559,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); @@ -555,15 +578,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); } @@ -573,6 +596,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); @@ -590,7 +614,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: @@ -602,15 +626,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 || diff --git a/src/kits/opengl/mesa/main/texstate.c b/src/kits/opengl/mesa/main/texstate.c index d172c5b546..348a2d9e63 100644 --- a/src/kits/opengl/mesa/main/texstate.c +++ b/src/kits/opengl/mesa/main/texstate.c @@ -802,6 +802,9 @@ _mesa_free_texture_data(GLcontext *ctx) /* unreference current textures */ for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { struct gl_texture_unit *unit = ctx->Texture.Unit + u; + /* The _Current texture could account for another reference */ + _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { _mesa_reference_texobj(&unit->CurrentTex[tgt], NULL); } diff --git a/src/kits/opengl/mesa/main/version.h b/src/kits/opengl/mesa/main/version.h index 84dcb263c6..9da81ee20e 100644 --- a/src/kits/opengl/mesa/main/version.h +++ b/src/kits/opengl/mesa/main/version.h @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 7.4 + * Version: 7.4.2 * * Copyright (C) 1999-2008 Brian Paul 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"), @@ -30,8 +31,8 @@ /* Mesa version */ #define MESA_MAJOR 7 #define MESA_MINOR 4 -#define MESA_PATCH 0 -#define MESA_VERSION_STRING "7.4" +#define MESA_PATCH 2 +#define MESA_VERSION_STRING "7.4.2" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) diff --git a/src/kits/opengl/mesa/math/m_matrix.c b/src/kits/opengl/mesa/math/m_matrix.c index 84b4cae4ad..5f300f4173 100644 --- a/src/kits/opengl/mesa/math/m_matrix.c +++ b/src/kits/opengl/mesa/math/m_matrix.c @@ -1379,11 +1379,10 @@ _math_matrix_analyse( GLmatrix *mat ) if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) { matrix_invert( mat ); + mat->flags &= ~MAT_DIRTY_INVERSE; } - mat->flags &= ~(MAT_DIRTY_FLAGS| - MAT_DIRTY_TYPE| - MAT_DIRTY_INVERSE); + mat->flags &= ~(MAT_DIRTY_FLAGS | MAT_DIRTY_TYPE); } /*@}*/ diff --git a/src/kits/opengl/mesa/shader/arbprogparse.c b/src/kits/opengl/mesa/shader/arbprogparse.c index a3a75c3b0a..0984d88172 100644 --- a/src/kits/opengl/mesa/shader/arbprogparse.c +++ b/src/kits/opengl/mesa/shader/arbprogparse.c @@ -1496,10 +1496,16 @@ generic_attrib_check(struct var_cache *vc_head) curr = vc_head; while (curr) { if (curr->type == vt_attrib) { - if (curr->attrib_is_generic) - genericAttrib[ curr->attrib_binding ] = GL_TRUE; - else + if (curr->attrib_is_generic) { + GLuint attr = (curr->attrib_binding == 0) + ? 0 : (curr->attrib_binding - VERT_ATTRIB_GENERIC0); + assert(attr < MAX_VERTEX_PROGRAM_ATTRIBS); + genericAttrib[attr] = GL_TRUE; + } + else { + assert(curr->attrib_binding < MAX_VERTEX_PROGRAM_ATTRIBS); explicitAttrib[ curr->attrib_binding ] = GL_TRUE; + } } curr = curr->next; @@ -1823,7 +1829,6 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, if (param_var->param_binding_begin == ~0U) param_var->param_binding_begin = idx; param_var->param_binding_length++; - Program->Base.NumParameters++; } } else { @@ -1832,7 +1837,6 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, if (param_var->param_binding_begin == ~0U) param_var->param_binding_begin = idx; param_var->param_binding_length++; - Program->Base.NumParameters++; } break; @@ -1843,7 +1847,6 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, if (param_var->param_binding_begin == ~0U) param_var->param_binding_begin = idx; param_var->param_binding_length++; - Program->Base.NumParameters++; /* Check if there is more: 0 -> we're done, else its an integer */ if (**inst) { @@ -1879,7 +1882,6 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, idx = _mesa_add_state_reference(Program->Base.Parameters, state_tokens); param_var->param_binding_length++; - Program->Base.NumParameters++; } } else { @@ -1897,7 +1899,6 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, param_var->param_binding_begin = idx; param_var->param_binding_type = PROGRAM_CONSTANT; param_var->param_binding_length++; - Program->Base.NumParameters++; break; default: @@ -1906,12 +1907,14 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, return 1; } + Program->Base.NumParameters = Program->Base.Parameters->NumParameters; + /* Make sure we haven't blown past our parameter limits */ if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && - (Program->Base.NumParameters >= + (Program->Base.NumParameters > ctx->Const.VertexProgram.MaxLocalParams)) || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) - && (Program->Base.NumParameters >= + && (Program->Base.NumParameters > ctx->Const.FragmentProgram.MaxLocalParams))) { program_error(ctx, Program->Position, "Too many parameter variables"); return 1; diff --git a/src/kits/opengl/mesa/shader/prog_execute.c b/src/kits/opengl/mesa/shader/prog_execute.c index a93733c085..9c25a9eb43 100644 --- a/src/kits/opengl/mesa/shader/prog_execute.c +++ b/src/kits/opengl/mesa/shader/prog_execute.c @@ -873,7 +873,7 @@ _mesa_execute_program(GLcontext * ctx, * result.z = result.x * APPX(result.y) * We do what the ARB extension says. */ - q[2] = (GLfloat) pow(2.0, t[0]); + q[2] = (GLfloat) _mesa_pow(2.0, t[0]); } q[1] = t[0] - floor_t0; q[3] = 1.0F; @@ -986,7 +986,7 @@ _mesa_execute_program(GLcontext * ctx, if (a[1] == 0.0 && a[3] == 0.0) result[2] = 1.0; else - result[2] = EXPF(a[3] * LOGF(a[1])); + result[2] = (GLfloat) _mesa_pow(a[1], a[3]); } else { result[2] = 0.0; @@ -1577,8 +1577,8 @@ _mesa_execute_program(GLcontext * ctx, case OPCODE_TXB: /* GL_ARB_fragment_program only */ /* Texel lookup with LOD bias */ { - const struct gl_texture_unit *texUnit - = &ctx->Texture.Unit[inst->TexSrcUnit]; + const GLuint unit = machine->Samplers[inst->TexSrcUnit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; GLfloat texcoord[4], color[4], lodBias; fetch_vector4(&inst->SrcReg[0], machine, texcoord); diff --git a/src/kits/opengl/mesa/shader/prog_parameter.c b/src/kits/opengl/mesa/shader/prog_parameter.c index dc48e84ab2..b8202b56e7 100644 --- a/src/kits/opengl/mesa/shader/prog_parameter.c +++ b/src/kits/opengl/mesa/shader/prog_parameter.c @@ -178,15 +178,20 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList, const char *name, const GLfloat values[4], GLuint size) { -#if 0 /* disable this for now -- we need to save the name! */ + /* first check if this is a duplicate constant */ GLint pos; - GLuint swizzle; - ASSERT(size == 4); /* XXX future feature */ - /* check if we already have this constant */ - if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { - return pos; + for (pos = 0; pos < paramList->NumParameters; pos++) { + const GLfloat *pvals = paramList->ParameterValues[pos]; + if (pvals[0] == values[0] && + pvals[1] == values[1] && + pvals[2] == values[2] && + pvals[3] == values[3] && + _mesa_strcmp(paramList->Parameters[pos].Name, name) == 0) { + /* Same name and value is already in the param list - reuse it */ + return pos; + } } -#endif + /* not found, add new parameter */ return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name, size, GL_NONE, values, NULL, 0x0); } diff --git a/src/kits/opengl/mesa/shader/program.c b/src/kits/opengl/mesa/shader/program.c index 828db38a49..aa6c6c4951 100644 --- a/src/kits/opengl/mesa/shader/program.c +++ b/src/kits/opengl/mesa/shader/program.c @@ -296,6 +296,7 @@ _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id) struct gl_program *prog; switch (target) { case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + case GL_VERTEX_STATE_PROGRAM_NV: prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), target, id ); break; diff --git a/src/kits/opengl/mesa/shader/slang/slang_builtin.c b/src/kits/opengl/mesa/shader/slang/slang_builtin.c index c0f4c79e13..5a673941fa 100644 --- a/src/kits/opengl/mesa/shader/slang/slang_builtin.c +++ b/src/kits/opengl/mesa/shader/slang/slang_builtin.c @@ -457,28 +457,36 @@ emit_statevars(const char *name, int array_len, tokens[0] = STATE_TEXENV_COLOR; } else if (strcmp(name, "gl_EyePlaneS") == 0) { - tokens[0] = STATE_TEXGEN_EYE_S; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_EYE_S; } else if (strcmp(name, "gl_EyePlaneT") == 0) { - tokens[0] = STATE_TEXGEN_EYE_T; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_EYE_T; } else if (strcmp(name, "gl_EyePlaneR") == 0) { - tokens[0] = STATE_TEXGEN_EYE_R; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_EYE_R; } else if (strcmp(name, "gl_EyePlaneQ") == 0) { - tokens[0] = STATE_TEXGEN_EYE_Q; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_EYE_Q; } else if (strcmp(name, "gl_ObjectPlaneS") == 0) { - tokens[0] = STATE_TEXGEN_OBJECT_S; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_OBJECT_S; } else if (strcmp(name, "gl_ObjectPlaneT") == 0) { - tokens[0] = STATE_TEXGEN_OBJECT_T; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_OBJECT_T; } else if (strcmp(name, "gl_ObjectPlaneR") == 0) { - tokens[0] = STATE_TEXGEN_OBJECT_R; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_OBJECT_R; } else if (strcmp(name, "gl_ObjectPlaneQ") == 0) { - tokens[0] = STATE_TEXGEN_OBJECT_Q; + tokens[0] = STATE_TEXGEN; + tokens[2] = STATE_TEXGEN_OBJECT_Q; } else { return -1; /* invalid array name */ diff --git a/src/kits/opengl/mesa/shader/slang/slang_link.c b/src/kits/opengl/mesa/shader/slang/slang_link.c index b8427cae58..2aa3851911 100644 --- a/src/kits/opengl/mesa/shader/slang/slang_link.c +++ b/src/kits/opengl/mesa/shader/slang/slang_link.c @@ -249,6 +249,11 @@ link_uniform_vars(GLcontext *ctx, _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i); if (uniform) uniform->Initialized = p->Initialized; + + /* Add the flag indicating that the program is dependent on constant + * state. + */ + prog->Parameters->StateFlags |= _NEW_PROGRAM; } /* The samplerMap[] table we build here is used to remap/re-index diff --git a/src/kits/opengl/mesa/swrast/s_points.c b/src/kits/opengl/mesa/swrast/s_points.c index 61ff4d0b84..0a3ad97a71 100644 --- a/src/kits/opengl/mesa/swrast/s_points.c +++ b/src/kits/opengl/mesa/swrast/s_points.c @@ -570,6 +570,9 @@ void _swrast_choose_point(GLcontext *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLfloat size = CLAMP(ctx->Point.Size, + ctx->Point.MinSize, + ctx->Point.MaxSize); if (ctx->RenderMode == GL_RENDER) { if (ctx->Point.PointSprite) { @@ -578,7 +581,7 @@ _swrast_choose_point(GLcontext *ctx) else if (ctx->Point.SmoothFlag) { swrast->Point = smooth_point; } - else if (ctx->Point.Size > 1.0 || + else if (size > 1.0 || ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) { swrast->Point = large_point; diff --git a/src/kits/opengl/mesa/swrast/s_span.c b/src/kits/opengl/mesa/swrast/s_span.c index e36c1a48b2..f07014fabd 100644 --- a/src/kits/opengl/mesa/swrast/s_span.c +++ b/src/kits/opengl/mesa/swrast/s_span.c @@ -1399,11 +1399,17 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } /* - * Write to renderbuffers + * Write to renderbuffers. + * Depending on glDrawBuffer() state and the which color outputs are + * written by the fragment shader, we may either replicate one color to + * all renderbuffers or write a different color to each renderbuffer. + * multiFragOutputs=TRUE for the later case. */ { const GLuint numBuffers = fb->_NumColorDrawBuffers; - const GLboolean multiFragOutputs = numBuffers > 1; + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; + const GLboolean multiFragOutputs = + (fp && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0)); GLuint buf; for (buf = 0; buf < numBuffers; buf++) { diff --git a/src/kits/opengl/mesa/swrast/s_texfilter.c b/src/kits/opengl/mesa/swrast/s_texfilter.c index a095b255ab..fce0bcf0ca 100644 --- a/src/kits/opengl/mesa/swrast/s_texfilter.c +++ b/src/kits/opengl/mesa/swrast/s_texfilter.c @@ -2061,6 +2061,7 @@ clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, fcol -= 0.5F; i0 = IFLOOR(fcol); i1 = i0 + 1; + break; default: _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); i0 = i1 = 0;