Commits

Scott Lawrence  committed 8186734 Merge

merge changes for vmrg-193

  • Participants
  • Parent commits 1bc0a35, e08d784

Comments (0)

Files changed (434)

File doc/contributions.txt

 	STORM-546
 	VWR-24509
     STORM-1684
+	SH-2477
 Tony Kembia
 Torben Trautman
 TouchaHoney Perhaps

File indra/llcommon/llsdserialize_xml.cpp

File contents unchanged.

File indra/llmath/CMakeLists.txt

     llvector4a.h
     llvector4a.inl
     llvector4logical.h
-    llv4math.h
-    llv4matrix3.h
-    llv4matrix4.h
-    llv4vector3.h
     llvolume.h
     llvolumemgr.h
     llvolumeoctree.h

File indra/llmath/llv4math.h

-/** 
- * @file llv4math.h
- * @brief LLV4* class header file - vector processor enabled math
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef	LL_LLV4MATH_H
-#define	LL_LLV4MATH_H
-
-// *NOTE: We do not support SSE acceleration on Windows builds.
-// Our minimum specification for the viewer includes 1 GHz Athlon processors,
-// which covers the Athlon Thunderbird series that does not support SSE.
-//
-// Our header files include statements like this
-//   const F32 HAVOK_TIMESTEP = 1.f / 45.f;
-// This creates "globals" that are included in each .obj file.  If a single
-// .cpp file has SSE code generation turned on (eg, llviewerjointmesh_sse.cpp)
-// these globals will be initialized using SSE instructions.  This causes SL
-// to crash before main() on processors without SSE.  Untangling all these 
-// headers/variables is too much work for the small performance gains of 
-// vectorization.
-//
-// Therefore we only support vectorization on builds where the everything is 
-// built with SSE or Altivec.  See https://jira.secondlife.com/browse/VWR-1610
-// and https://jira.lindenlab.com/browse/SL-47720 for details.
-//
-// Sorry the code is such a mess. JC
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4MATH - GNUC
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#if LL_GNUC && __GNUC__ >= 4 && __SSE__
-
-#define			LL_VECTORIZE					1
-
-#if LL_DARWIN
-
-#include <Accelerate/Accelerate.h>
-#include <xmmintrin.h>
-typedef vFloat	V4F32;
-
-#else
-
-#include <xmmintrin.h>
-typedef float	V4F32							__attribute__((vector_size(16)));
-
-#endif
-
-#endif
-#if LL_GNUC
-
-#define			LL_LLV4MATH_ALIGN_PREFIX
-#define			LL_LLV4MATH_ALIGN_POSTFIX		__attribute__((aligned(16)))
-
-#endif
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4MATH - MSVC
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-// Only vectorize if the entire Windows build uses SSE.
-// _M_IX86_FP is set when SSE code generation is turned on, and I have
-// confirmed this in VS2003, VS2003 SP1, and VS2005. JC
-#if LL_MSVC && _M_IX86_FP
-
-#define			LL_VECTORIZE					1
-
-#include <xmmintrin.h>
-
-typedef __m128	V4F32;
-
-#endif
-#if LL_MSVC
-
-#define			LL_LLV4MATH_ALIGN_PREFIX		__declspec(align(16))
-#define			LL_LLV4MATH_ALIGN_POSTFIX
-
-#endif
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4MATH - default - no vectorization
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#if !LL_VECTORIZE
-
-#define			LL_VECTORIZE					0
-
-struct			V4F32							{ F32 __pad__[4]; };
-
-inline F32 llv4lerp(F32 a, F32 b, F32 w)		{ return ( b - a ) * w + a; }
-
-#endif
-
-#ifndef			LL_LLV4MATH_ALIGN_PREFIX
-#	define			LL_LLV4MATH_ALIGN_PREFIX
-#endif
-#ifndef			LL_LLV4MATH_ALIGN_POSTFIX
-#	define			LL_LLV4MATH_ALIGN_POSTFIX
-#endif
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4MATH
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-
-#define			LLV4_NUM_AXIS					4
-
-class LLV4Vector3;
-class LLV4Matrix3;
-class LLV4Matrix4;
-
-#endif

File indra/llmath/llv4matrix3.h

-/** 
- * @file llviewerjointmesh.cpp
- * @brief LLV4* class header file - vector processor enabled math
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLV4MATRIX3_H
-#define LL_LLV4MATRIX3_H
-
-#include "llv4math.h"
-#include "llv4vector3.h"
-#include "m3math.h"			// for operator LLMatrix3()
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix3
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-LL_LLV4MATH_ALIGN_PREFIX
-
-class LLV4Matrix3
-{
-public:
-	union {
-		F32		mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
-		V4F32	mV[LLV4_NUM_AXIS];
-	};
-
-	void				lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w);
-	void				multiply(const LLVector3 &a, LLVector3& out) const;
-	void				multiply(const LLVector4 &a, LLV4Vector3& out) const;
-	void				multiply(const LLVector3 &a, LLV4Vector3& out) const;
-
-	const LLV4Matrix3&	transpose();
-	const LLV4Matrix3&	operator=(const LLMatrix3& a);
-
-	operator			LLMatrix3()	const { return (reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0])))->getMat3(); }
-
-	friend LLVector3	operator*(const LLVector3& a, const LLV4Matrix3& b);
-}
-
-LL_LLV4MATH_ALIGN_POSTFIX;
-
-
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix3 - SSE
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#if LL_VECTORIZE
-
-inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
-{
-	__m128 vw = _mm_set1_ps(w);
-	mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
-	mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
-	mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
-}
-
-inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
-{
-	LLV4Vector3 j;
-	j.v = 				 	_mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
-	j.v = _mm_add_ps(j.v  , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
-	j.v = _mm_add_ps(j.v  , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
-	o.setVec(j.mV);
-}
-
-inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
-{
-	o.v =					_mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
-	o.v = _mm_add_ps(o.v  , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
-	o.v = _mm_add_ps(o.v  , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
-}
-
-inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
-{
-	o.v =					_mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
-	o.v = _mm_add_ps(o.v  , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
-	o.v = _mm_add_ps(o.v  , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix3
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#else
-
-inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
-{
-	mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
-	mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
-	mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
-
-	mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
-	mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
-	mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
-
-	mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
-	mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
-	mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
-}
-
-inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
-{
-	o.setVec(		a.mV[VX] * mMatrix[VX][VX] + 
-					a.mV[VY] * mMatrix[VY][VX] + 
-					a.mV[VZ] * mMatrix[VZ][VX],
-					 
-					a.mV[VX] * mMatrix[VX][VY] + 
-					a.mV[VY] * mMatrix[VY][VY] + 
-					a.mV[VZ] * mMatrix[VZ][VY],
-					 
-					a.mV[VX] * mMatrix[VX][VZ] + 
-					a.mV[VY] * mMatrix[VY][VZ] + 
-					a.mV[VZ] * mMatrix[VZ][VZ]);
-}
-
-inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
-{
-	o.setVec(		a.mV[VX] * mMatrix[VX][VX] + 
-					a.mV[VY] * mMatrix[VY][VX] + 
-					a.mV[VZ] * mMatrix[VZ][VX],
-					 
-					a.mV[VX] * mMatrix[VX][VY] + 
-					a.mV[VY] * mMatrix[VY][VY] + 
-					a.mV[VZ] * mMatrix[VZ][VY],
-					 
-					a.mV[VX] * mMatrix[VX][VZ] + 
-					a.mV[VY] * mMatrix[VY][VZ] + 
-					a.mV[VZ] * mMatrix[VZ][VZ]);
-}
-
-inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
-{
-	o.setVec(		a.mV[VX] * mMatrix[VX][VX] + 
-					a.mV[VY] * mMatrix[VY][VX] + 
-					a.mV[VZ] * mMatrix[VZ][VX],
-					 
-					a.mV[VX] * mMatrix[VX][VY] + 
-					a.mV[VY] * mMatrix[VY][VY] + 
-					a.mV[VZ] * mMatrix[VZ][VY],
-					 
-					a.mV[VX] * mMatrix[VX][VZ] + 
-					a.mV[VY] * mMatrix[VY][VZ] + 
-					a.mV[VZ] * mMatrix[VZ][VZ]);
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix3
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#endif
-
-inline const LLV4Matrix3&	LLV4Matrix3::transpose()
-{
-#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
-	_MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
-	return *this;
-#else
-	F32 temp;
-	temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
-	temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
-	temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
-#endif
-	return *this;
-}
-
-inline const LLV4Matrix3& LLV4Matrix3::operator=(const LLMatrix3& a)
-{
-	memcpy(mMatrix[VX], a.mMatrix[VX], sizeof(F32) * 3 );
-	memcpy(mMatrix[VY], a.mMatrix[VY], sizeof(F32) * 3 );
-	memcpy(mMatrix[VZ], a.mMatrix[VZ], sizeof(F32) * 3 );
-	return *this;
-}
-
-inline LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b)
-{
-	return LLVector3(
-				a.mV[VX] * b.mMatrix[VX][VX] + 
-				a.mV[VY] * b.mMatrix[VY][VX] + 
-				a.mV[VZ] * b.mMatrix[VZ][VX],
-	
-				a.mV[VX] * b.mMatrix[VX][VY] + 
-				a.mV[VY] * b.mMatrix[VY][VY] + 
-				a.mV[VZ] * b.mMatrix[VZ][VY],
-	
-				a.mV[VX] * b.mMatrix[VX][VZ] + 
-				a.mV[VY] * b.mMatrix[VY][VZ] + 
-				a.mV[VZ] * b.mMatrix[VZ][VZ] );
-}
-
-#endif

File indra/llmath/llv4matrix4.h

-/** 
- * @file llviewerjointmesh.cpp
- * @brief LLV4* class header file - vector processor enabled math
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLV4MATRIX4_H
-#define LL_LLV4MATRIX4_H
-
-#include "llv4math.h"
-#include "llv4matrix3.h"	// just for operator LLV4Matrix3()
-#include "llv4vector3.h"
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix4
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-LL_LLV4MATH_ALIGN_PREFIX
-
-class LLV4Matrix4
-{
-public:
-	union {
-		F32		mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
-		V4F32	mV[LLV4_NUM_AXIS];
-	};
-
-	void				lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w);
-	void				multiply(const LLVector3 &a, LLVector3& o) const;
-	void				multiply(const LLVector3 &a, LLV4Vector3& o) const;
-
-	const LLV4Matrix4&	transpose();
-	const LLV4Matrix4&  translate(const LLVector3 &vec);
-	const LLV4Matrix4&  translate(const LLV4Vector3 &vec);
-	const LLV4Matrix4&	operator=(const LLMatrix4& a);
-
-	operator			LLMatrix4()	const { return *(reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0]))); }
-	operator			LLV4Matrix3()	const { return *(reinterpret_cast<const LLV4Matrix3*>(const_cast<const F32*>(&mMatrix[0][0]))); }
-	
-	friend LLVector3	operator*(const LLVector3 &a, const LLV4Matrix4 &b);
-}
-
-LL_LLV4MATH_ALIGN_POSTFIX;
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix4 - SSE
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#if LL_VECTORIZE
-
-inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
-{
-	__m128 vw = _mm_set1_ps(w);
-	mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
-	mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
-	mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
-	mV[VW] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VW], a.mV[VW]), vw), a.mV[VW]);
-}
-
-inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
-{
-	LLV4Vector3 j;
-	j.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
-	j.v = _mm_add_ps(j.v   , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
-	j.v = _mm_add_ps(j.v   , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
-	o.setVec(j.mV);
-}
-
-inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
-{
-	o.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
-	o.v = _mm_add_ps(o.v   , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
-	o.v = _mm_add_ps(o.v   , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
-}
-
-inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
-{
-	mV[VW] = _mm_add_ps(mV[VW], vec.v);
-	return (*this);
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix4
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#else
-
-inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
-{
-	mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
-	mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
-	mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
-
-	mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
-	mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
-	mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
-
-	mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
-	mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
-	mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
-
-	mMatrix[VW][VX] = llv4lerp(a.mMatrix[VW][VX], b.mMatrix[VW][VX], w);
-	mMatrix[VW][VY] = llv4lerp(a.mMatrix[VW][VY], b.mMatrix[VW][VY], w);
-	mMatrix[VW][VZ] = llv4lerp(a.mMatrix[VW][VZ], b.mMatrix[VW][VZ], w);
-}
-
-inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
-{
-	o.setVec(		a.mV[VX] * mMatrix[VX][VX] + 
-					a.mV[VY] * mMatrix[VY][VX] + 
-					a.mV[VZ] * mMatrix[VZ][VX] +
-					mMatrix[VW][VX],
-					 
-					a.mV[VX] * mMatrix[VX][VY] + 
-					a.mV[VY] * mMatrix[VY][VY] + 
-					a.mV[VZ] * mMatrix[VZ][VY] +
-					mMatrix[VW][VY],
-					 
-					a.mV[VX] * mMatrix[VX][VZ] + 
-					a.mV[VY] * mMatrix[VY][VZ] + 
-					a.mV[VZ] * mMatrix[VZ][VZ] +
-					mMatrix[VW][VZ]);
-}
-
-inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
-{
-	o.setVec(		a.mV[VX] * mMatrix[VX][VX] + 
-					a.mV[VY] * mMatrix[VY][VX] + 
-					a.mV[VZ] * mMatrix[VZ][VX] +
-					mMatrix[VW][VX],
-					 
-					a.mV[VX] * mMatrix[VX][VY] + 
-					a.mV[VY] * mMatrix[VY][VY] + 
-					a.mV[VZ] * mMatrix[VZ][VY] +
-					mMatrix[VW][VY],
-					 
-					a.mV[VX] * mMatrix[VX][VZ] + 
-					a.mV[VY] * mMatrix[VY][VZ] + 
-					a.mV[VZ] * mMatrix[VZ][VZ] +
-					mMatrix[VW][VZ]);
-}
-
-inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
-{
-	mMatrix[3][0] += vec.mV[0];
-	mMatrix[3][1] += vec.mV[1];
-	mMatrix[3][2] += vec.mV[2];
-	return (*this);
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Matrix4
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-#endif
-
-inline const LLV4Matrix4& LLV4Matrix4::operator=(const LLMatrix4& a)
-{
-	memcpy(mMatrix, a.mMatrix, sizeof(F32) * 16 );
-	return *this;
-}
-
-inline const LLV4Matrix4& LLV4Matrix4::transpose()
-{
-#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
-	_MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
-#else
-	LLV4Matrix4 mat;
-	mat.mMatrix[0][0] = mMatrix[0][0];
-	mat.mMatrix[1][0] = mMatrix[0][1];
-	mat.mMatrix[2][0] = mMatrix[0][2];
-	mat.mMatrix[3][0] = mMatrix[0][3];
-
-	mat.mMatrix[0][1] = mMatrix[1][0];
-	mat.mMatrix[1][1] = mMatrix[1][1];
-	mat.mMatrix[2][1] = mMatrix[1][2];
-	mat.mMatrix[3][1] = mMatrix[1][3];
-
-	mat.mMatrix[0][2] = mMatrix[2][0];
-	mat.mMatrix[1][2] = mMatrix[2][1];
-	mat.mMatrix[2][2] = mMatrix[2][2];
-	mat.mMatrix[3][2] = mMatrix[2][3];
-
-	mat.mMatrix[0][3] = mMatrix[3][0];
-	mat.mMatrix[1][3] = mMatrix[3][1];
-	mat.mMatrix[2][3] = mMatrix[3][2];
-	mat.mMatrix[3][3] = mMatrix[3][3];
-
-	*this = mat;
-#endif
-	return *this;
-}
-
-inline const LLV4Matrix4& LLV4Matrix4::translate(const LLVector3 &vec)
-{
-	mMatrix[3][0] += vec.mV[0];
-	mMatrix[3][1] += vec.mV[1];
-	mMatrix[3][2] += vec.mV[2];
-	return (*this);
-}
-
-inline LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b)
-{
-	return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + 
-					 a.mV[VY] * b.mMatrix[VY][VX] + 
-					 a.mV[VZ] * b.mMatrix[VZ][VX] +
-					 b.mMatrix[VW][VX],
-					 
-					 a.mV[VX] * b.mMatrix[VX][VY] + 
-					 a.mV[VY] * b.mMatrix[VY][VY] + 
-					 a.mV[VZ] * b.mMatrix[VZ][VY] +
-					 b.mMatrix[VW][VY],
-					 
-					 a.mV[VX] * b.mMatrix[VX][VZ] + 
-					 a.mV[VY] * b.mMatrix[VY][VZ] + 
-					 a.mV[VZ] * b.mMatrix[VZ][VZ] +
-					 b.mMatrix[VW][VZ]);
-}
-
-
-#endif

File indra/llmath/llv4vector3.h

-/** 
- * @file llviewerjointmesh.cpp
- * @brief LLV4* class header file - vector processor enabled math
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLV4VECTOR3_H
-#define LL_LLV4VECTOR3_H
-
-#include "llv4math.h"
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Vector3
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-LL_LLV4MATH_ALIGN_PREFIX
-
-class LLV4Vector3
-{
-public:
-	union {
-		F32		mV[LLV4_NUM_AXIS];
-		V4F32	v;
-	};
-
-	enum {
-		ALIGNMENT = 16
-		};
-
-	void				setVec(F32 x, F32 y, F32 z);
-	void				setVec(F32 a);
-}
-
-LL_LLV4MATH_ALIGN_POSTFIX;
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLV4Vector3
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-inline void	LLV4Vector3::setVec(F32 x, F32 y, F32 z)
-{
-	mV[VX] = x;
-	mV[VY] = y;
-	mV[VZ] = z;
-}
-
-inline void	LLV4Vector3::setVec(F32 a)
-{
-#if LL_VECTORIZE
-	v = _mm_set1_ps(a);
-#else
-	setVec(a, a, a);
-#endif
-}
-
-#endif

File indra/llmath/llvolume.cpp

 }
 
 
-S32 LLVolume::getNumTriangles() const
+S32 LLVolume::getNumTriangles(S32* vcount) const
 {
 	U32 triangle_count = 0;
+	U32 vertex_count = 0;
 
 	for (S32 i = 0; i < getNumVolumeFaces(); ++i)
 	{
-		triangle_count += getVolumeFace(i).mNumIndices/3;
-	}
-
+		const LLVolumeFace& face = getVolumeFace(i);
+		triangle_count += face.mNumIndices/3;
+
+		vertex_count += face.mNumVertices;
+	}
+
+
+	if (vcount)
+	{
+		*vcount = vertex_count;
+	}
+	
 	return triangle_count;
 }
 

File indra/llmath/llvolume.h

 	S32 getNumTriangleIndices() const;
 	static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
 
-	S32 getNumTriangles() const;
+	S32 getNumTriangles(S32* vcount = NULL) const;
 
 	void generateSilhouetteVertices(std::vector<LLVector3> &vertices, 
 									std::vector<LLVector3> &normals, 

File indra/llmessage/llassetstorage.cpp

 	setName( buf );
 	buf.assign( str, pos2, std::string::npos );
 	setDescription( buf );
-	llinfos << "uuid: " << mUuid << llendl;
-	llinfos << "creator: " << mCreatorID << llendl;
+	LL_DEBUGS("AssetStorage") << "uuid: " << mUuid << llendl;
+	LL_DEBUGS("AssetStorage") << "creator: " << mCreatorID << llendl;
 }
 
 ///----------------------------------------------------------------------------
 // IW - uuid is passed by value to avoid side effects, please don't re-add &    
 void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LLGetAssetCallback callback, void *user_data, BOOL is_priority)
 {
-	lldebugs << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << llendl;
+	LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << llendl;
 
-	llinfos << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << llendl;
+	LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << llendl;
 
 	if (user_data)
 	{
 
 	if (mShutDown)
 	{
-		llinfos << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << llendl;
+		LL_DEBUGS("AssetStorage") << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << llendl;
 
 		if (callback)
 		{
 	// Try static VFS first.
 	if (findInStaticVFSAndInvokeCallback(uuid,type,callback,user_data))
 	{
-		llinfos << "ASSET_TRACE asset " << uuid << " found in static VFS" << llendl;
+		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in static VFS" << llendl;
 		return;
 	}
 
 			callback(mVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
 		}
 
-		llinfos << "ASSET_TRACE asset " << uuid << " found in VFS" << llendl;
+		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in VFS" << llendl;
 	}
 	else
 	{
 		}
 		if (duplicate)
 		{
-			llinfos << "Adding additional non-duplicate request for asset " << uuid 
+			LL_DEBUGS("AssetStorage") << "Adding additional non-duplicate request for asset " << uuid 
 					<< "." << LLAssetType::lookup(type) << llendl;
 		}
 		
 	LLAssetType::EType file_type,
 	void* user_data, LLExtStat ext_status)
 {
-	llinfos << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << llendl;
+	LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << llendl;
 
-	lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id
+	LL_DEBUGS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback() for " << file_id
 		 << "," << LLAssetType::lookup(file_type) << llendl;
 	LLAssetRequest* req = (LLAssetRequest*)user_data;
 	if(!req)
 			tpvf.setAsset(asset_id, atype);
 			tpvf.setCallback(downloadEstateAssetCompleteCallback, req);
 
-			llinfos << "Starting transfer for " << asset_id << llendl;
+			LL_DEBUGS("AssetStorage") << "Starting transfer for " << asset_id << llendl;
 			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
 			ttcp->requestTransfer(spe, tpvf, 100.f + (is_priority ? 1.f : 0.f));
 		}
 			tpvf.setAsset(asset_id, atype);
 			tpvf.setCallback(downloadInvItemCompleteCallback, req);
 
-			llinfos << "Starting transfer for inventory asset "
+			LL_DEBUGS("AssetStorage") << "Starting transfer for inventory asset "
 				<< item_id << " owned by " << owner_id << "," << task_id
 				<< llendl;
 			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
 	request_list_t* requests = getRequestList(rt);
 	if (deletePendingRequestImpl(requests, asset_type, asset_id))
 	{
-		llinfos << "Asset " << getRequestName(rt) << " request for "
+		LL_DEBUGS("AssetStorage") << "Asset " << getRequestName(rt) << " request for "
 				<< asset_id << "." << LLAssetType::lookup(asset_type)
 				<< " removed from pending queue." << llendl;
 		return true;
 			user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData)
 		{
 			// this is a duplicate from the same subsystem - throw it away
-			llinfos << "Discarding duplicate request for UUID " << uuid << llendl;
+			LL_DEBUGS("AssetStorage") << "Discarding duplicate request for UUID " << uuid << llendl;
 			return;
 		}
 	}
 {
 	if( !metric_recipient )
 	{
-		llinfos << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << llendl;
+		LL_DEBUGS("AssetStorage") << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << llendl;
 		return;
 	}
 

File indra/llplugin/llpluginclassmedia.h

 	std::string	getHoverText() const { return mHoverText; };
 	std::string	getHoverLink() const { return mHoverLink; };
 	
-	std::string getMediaName() const { return mMediaName; };
+	const std::string& getMediaName() const { return mMediaName; };
 	std::string getMediaDescription() const { return mMediaDescription; };
 
 	// Crash the plugin.  If you use this outside of a testbed, you will be punished.

File indra/llrender/llcubemap.cpp

 #include "m4math.h"
 
 #include "llrender.h"
+#include "llglslshader.h"
 
 #include "llglheaders.h"
 
 void LLCubeMap::enableTextureCoords(S32 stage)
 {
 	mTextureCoordStage = stage;
-	if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
+	if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
 	{
 		if (stage > 0)
 		{
 
 void LLCubeMap::disableTextureCoords(void)
 {
-	if (gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
+	if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
 	{
 		if (mTextureCoordStage > 0)
 		{
 		gGL.getTexUnit(stage)->activate();
 	}
 
-	LLVector3 x(LLVector3d(gGLModelView+0));
-	LLVector3 y(LLVector3d(gGLModelView+4));
-	LLVector3 z(LLVector3d(gGLModelView+8));
+	LLVector3 x(gGLModelView+0);
+	LLVector3 y(gGLModelView+4);
+	LLVector3 z(gGLModelView+8);
 
 	LLMatrix3 mat3;
 	mat3.setRows(x,y,z);
 	LLMatrix4 trans(mat3);
 	trans.transpose();
 
-	glMatrixMode(GL_TEXTURE);
-	glPushMatrix();
-	glLoadMatrixf((F32 *)trans.mMatrix);
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.pushMatrix();
+	gGL.loadMatrix((F32 *)trans.mMatrix);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
 	/*if (stage > 0)
 	{
 	{
 		gGL.getTexUnit(mMatrixStage)->activate();
 	}
-	glMatrixMode(GL_TEXTURE);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	gGL.matrixMode(LLRender::MM_TEXTURE);
+	gGL.popMatrix();
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	
 	/*if (mMatrixStage > 0)
 	{

File indra/llrender/llfontgl.cpp

File contents unchanged.

File indra/llrender/llgl.cpp

 
 std::ofstream gFailLog;
 
+#if GL_ARB_debug_output
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+void APIENTRY gl_debug_callback(GLenum source,
+                                GLenum type,
+                                GLuint id,
+                                GLenum severity,
+                                GLsizei length,
+                                const GLchar* message,
+                                GLvoid* userParam)
+{
+	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+	{
+		llwarns << "----- GL ERROR --------" << llendl;
+	}
+	else
+	{
+		llwarns << "----- GL WARNING -------" << llendl;
+	}
+	llwarns << "Type: " << std::hex << type << llendl;
+	llwarns << "ID: " << std::hex << id << llendl;
+	llwarns << "Severity: " << std::hex << severity << llendl;
+	llwarns << "Message: " << message << llendl;
+	llwarns << "-----------------------" << llendl;
+}
+#endif
+
 void ll_init_fail_log(std::string filename)
 {
 	gFailLog.open(filename.c_str());
 
 #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS)  && !LL_MESA_HEADLESS
 // ATI prototypes
+
+#if LL_WINDOWS
+PFNGLGETSTRINGIPROC glGetStringi = NULL;
+#endif
+
 // vertex blending prototypes
 PFNGLWEIGHTPOINTERARBPROC			glWeightPointerARB = NULL;
 PFNGLVERTEXBLENDARBPROC				glVertexBlendARB = NULL;
 PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB = NULL;
 PFNGLGETBUFFERPOINTERVARBPROC		glGetBufferPointervARB = NULL;
 
+//GL_ARB_vertex_array_object
+PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
+PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
+PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
+PFNGLISVERTEXARRAYPROC glIsVertexArray = NULL;
+
 // GL_ARB_map_buffer_range
 PFNGLMAPBUFFERRANGEPROC			glMapBufferRange = NULL;
 PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange = NULL;
 PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL;
 
 //GL_ARB_texture_multisample
-PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
-PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
-PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
-PFNGLSAMPLEMASKIPROC glSampleMaski;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
+PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
+PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
+
+//GL_ARB_debug_output
+PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
+PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
+PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = NULL;
+PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = NULL;
 
 // GL_EXT_blend_func_separate
 PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
 PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
 PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
 
+#if LL_WINDOWS
+PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
+#endif
+
 // vertex shader prototypes
 #if LL_LINUX || LL_SOLARIS
 PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
 	mHasBlendFuncSeparate(FALSE),
 	mHasSync(FALSE),
 	mHasVertexBufferObject(FALSE),
+	mHasVertexArrayObject(FALSE),
 	mHasMapBufferRange(FALSE),
 	mHasFlushBufferRange(FALSE),
 	mHasPBuffer(FALSE),
 	mHasAnisotropic(FALSE),
 	mHasARBEnvCombine(FALSE),
 	mHasCubeMap(FALSE),
+	mHasDebugOutput(FALSE),
 
 	mIsATI(FALSE),
 	mIsNVIDIA(FALSE),
 		LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
 	}
 
+	if (ExtensionExists("WGL_ARB_create_context",gGLHExts.mSysExts))
+	{
+		GLH_EXT_NAME(wglCreateContextAttribsARB) = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
+	}
+	else
+	{
+		LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
+	}
+	
 	if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
 	{
         GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
 		LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
 	}
 
-	GLint alpha_bits;
-	glGetIntegerv( GL_ALPHA_BITS, &alpha_bits );
-	if( 8 != alpha_bits )
+	stop_glerror();
+
+#if LL_WINDOWS
+	if (!glGetStringi)
 	{
-		LL_WARNS("RenderInit") << "Frame buffer has less than 8 bits of alpha.  Avatar texture compositing will fail." << LL_ENDL;
+		glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
 	}
 
+	//reload extensions string (may have changed after using wglCreateContextAttrib)
+	if (glGetStringi)
+	{
+		std::stringstream str;
+
+		GLint count = 0;
+		glGetIntegerv(GL_NUM_EXTENSIONS, &count);
+		for (GLint i = 0; i < count; ++i)
+		{
+			std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
+			str << ext << " ";
+			LL_DEBUGS("GLExtensions") << ext << llendl;
+		}
+		
+		{
+			PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
+			wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
+			if(wglGetExtensionsStringARB)
+			{
+				str << (const char*) wglGetExtensionsStringARB(wglGetCurrentDC());
+			}
+		}
+
+		free(gGLHExts.mSysExts);
+		std::string extensions = str.str();
+		gGLHExts.mSysExts = strdup(extensions.c_str());
+	}
+#endif
+	
+	stop_glerror();
+
 	// Extract video card strings and convert to upper case to
 	// work around driver-to-driver variation in capitalization.
 	mGLVendor = std::string((const char *)glGetString(GL_VENDOR));
 		&mDriverVersionVendorString );
 
 	mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
-	
+
 	// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
 	// from being recognized as ATI.
 	if (mGLVendor.substr(0,4) == "ATI ")
 		mGLVendorShort = "MISC";
 	}
 	
+	stop_glerror();
 	// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
 	initExtensions();
+	stop_glerror();
+
+	S32 old_vram = mVRAM;
 
 	if (mHasATIMemInfo)
 	{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
 		mVRAM = dedicated_memory/1024;
 	}
 
-	if (mHasMultitexture)
+	if (mVRAM < 256)
+	{ //something likely went wrong using the above extensions, fall back to old method
+		mVRAM = old_vram;
+	}
+
+	stop_glerror();
+
+	stop_glerror();
+
+	if (mHasFragmentShader)
+	{
+		GLint num_tex_image_units;
+		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
+		mNumTextureImageUnits = llmin(num_tex_image_units, 32);
+	}
+
+	if (LLRender::sGLCoreProfile)
+	{
+		mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS);
+	}
+	else if (mHasMultitexture)
 	{
 		GLint num_tex_units;		
 		glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
 		return false;
 	}
 	
-	if (mHasFragmentShader)
-	{
-		GLint num_tex_image_units;
-		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
-		mNumTextureImageUnits = llmin(num_tex_image_units, 32);
-	}
+	stop_glerror();
 
 	if (mHasTextureMultisample)
 	{
 		glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
 	}
 
+	stop_glerror();
+
+#if LL_WINDOWS
+	if (mHasDebugOutput && gDebugGL)
+	{ //setup debug output callback
+		//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
+		glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
+		glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+	}
+#endif
+
+	stop_glerror();
+
+	//HACK always disable texture multisample, use FXAA instead
+	mHasTextureMultisample = FALSE;
 #if LL_WINDOWS
 	if (mIsATI)
 	{ //using multisample textures on ATI results in black screen for some reason
 	{
 		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
 	}
+
+	stop_glerror();
 	
 	setToDebugGPU();
 
+	stop_glerror();
+
 	initGLStates();
+
+	stop_glerror();
+
 	return true;
 }
 
 	return gl_string;
 }
 
-U32 LLGLManager::getNumFBOFSAASamples(U32 samples)
-{
-	samples = llmin(samples, (U32) mMaxColorTextureSamples);
-	samples = llmin(samples, (U32) mMaxDepthTextureSamples);
-	samples = llmin(samples, (U32) 4);
-	return samples;
-}
-
 void LLGLManager::shutdownGL()
 {
 	if (mInited)
 	mHasVertexShader = FALSE;
 	mHasFragmentShader = FALSE;
 	mHasTextureRectangle = FALSE;
-#else // LL_MESA_HEADLESS
+#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
 	mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
 	mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
 	mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
 	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
 	mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
 	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
+	mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
 	mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
 	mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
 	mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
 	mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
 	mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
 	mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
+	mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
 #if !LL_DARWIN
 	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
 #endif
-	mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
+	mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
 	mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
-						&& ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
-	mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
+		&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
+	mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
 #endif
 
 #if LL_LINUX || LL_SOLARIS
 			mHasVertexBufferObject = FALSE;
 		}
 	}
+	if (mHasVertexArrayObject)
+	{
+		glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glBindVertexArray");
+		glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteVertexArrays");
+		glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenVertexArrays");
+		glIsVertexArray = (PFNGLISVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glIsVertexArray");
+	}
 	if (mHasSync)
 	{
 		glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
 		glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
 		glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
 	}	
+	if (mHasDebugOutput)
+	{
+		glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
+		glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsertARB");
+		glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
+		glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
+	}
 #if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
 	// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
 	glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
 {
 	F32 angle_radians, x, y, z;
 	rotation.getAngleAxis(&angle_radians, &x, &y, &z);
-	glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
+	gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 }
 
 void flush_glerror()
 
 void do_assert_glerror()
 {
-	if (LL_UNLIKELY(!gGLManager.mInited))
-	{
-		LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
-	}
 	//  Create or update texture to be used with this data 
 	GLenum error;
 	error = glGetError();
 	//make sure multisample defaults to disabled
 	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
 	glDisable(GL_MULTISAMPLE_ARB);
-
-	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
-	glDisable(GL_MULTISAMPLE_ARB);
-
-	glEnableClientState(GL_VERTEX_ARRAY);
 }
 
 //static
 
 void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
 {
-	if (!gDebugGL)
+	if (!gDebugGL || LLGLSLShader::sNoFixedFunction)
 	{
 		return;
 	}
 		error = TRUE;
 	}
 
-	glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
+	/*glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
 	if (active_texture != GL_TEXTURE0_ARB)
 	{
 		llwarns << "Active texture corrupted: " << active_texture << llendl;
 			gFailLog << "Active texture corrupted: " << active_texture << std::endl;
 		}
 		error = TRUE;
-	}
+	}*/
 
 	static const char* label[] =
 	{
 	};
 
 
-	for (S32 j = 0; j < 4; j++)
+	for (S32 j = 1; j < 4; j++)
 	{
 		if (glIsEnabled(value[j]))
 		{
 	mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
 {
 	if (LLGLSLShader::sNoFixedFunction)
-	{ //always disable state that's deprecated post GL 3.0
+	{ //always ignore state that's deprecated post GL 3.0
 		switch (state)
 		{
 			case GL_ALPHA_TEST:
-				enabled = 0;
+			case GL_NORMALIZE:
+			case GL_TEXTURE_GEN_R:
+			case GL_TEXTURE_GEN_S:
+			case GL_TEXTURE_GEN_T:
+			case GL_TEXTURE_GEN_Q:
+			case GL_LIGHTING:
+			case GL_COLOR_MATERIAL:
+			case GL_FOG:
+			case GL_LINE_STIPPLE:
+				mState = 0;
 				break;
 		}
 	}
 
 	stop_glerror();
-	if (state)
+	if (mState)
 	{
 		mWasEnabled = sStateMap[state];
 		llassert(mWasEnabled == glIsEnabled(state));
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void enable_vertex_weighting(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glEnableVertexAttribArrayARB(index);	// vertex weights
-#endif
-}
-
-void disable_vertex_weighting(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0) glDisableVertexAttribArrayARB(index);	// vertex weights
-#endif
-}
-
-void enable_binormals(const S32 index)
-{
-#if GL_ARB_vertex_program
-	if (index > 0)
-	{
-		glEnableVertexAttribArrayARB(index);	// binormals
-	}