diff options
Diffstat (limited to 'indra/llrender')
| -rwxr-xr-x | indra/llrender/CMakeLists.txt | 2 | ||||
| -rwxr-xr-x | indra/llrender/llgl.cpp | 42 | ||||
| -rwxr-xr-x | indra/llrender/llgl.h | 8 | ||||
| -rwxr-xr-x | indra/llrender/llglheaders.h | 16 | ||||
| -rwxr-xr-x | indra/llrender/llglslshader.cpp | 305 | ||||
| -rwxr-xr-x | indra/llrender/llglslshader.h | 41 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 50 | ||||
| -rwxr-xr-x | indra/llrender/llrender.h | 8 | ||||
| -rwxr-xr-x | indra/llrender/llshadermgr.cpp | 44 | ||||
| -rwxr-xr-x | indra/llrender/llshadermgr.h | 10 | ||||
| -rwxr-xr-x | indra/llrender/llvertexbuffer.cpp | 91 | ||||
| -rwxr-xr-x | indra/llrender/llvertexbuffer.h | 8 | 
12 files changed, 560 insertions, 65 deletions
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 669b70aa43..dba12d048e 100755 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -92,7 +92,7 @@ if (BUILD_HEADLESS)    set_property(TARGET llrenderheadless      PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 -    ) +      )    target_link_libraries(llrenderheadless      ${LLCOMMON_LIBRARIES} diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 6c798aa4ed..088ba95b75 100755 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -86,7 +86,7 @@ void APIENTRY gl_debug_callback(GLenum source,  	}  	else  	{ -		llwarns << "----- GL WARNING -------" << llendl;		 +		llwarns << "----- GL WARNING -------" << llendl;  	}  	llwarns << "Type: " << std::hex << type << llendl;  	llwarns << "ID: " << std::hex << id << llendl; @@ -216,6 +216,11 @@ PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;  PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;  PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL; +// GL_ARB_timer_query +PFNGLQUERYCOUNTERPROC glQueryCounter = NULL; +PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL; +  // GL_ARB_point_parameters  PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;  PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL; @@ -421,6 +426,7 @@ LLGLManager::LLGLManager() :  	mHasFragmentShader(FALSE),  	mNumTextureImageUnits(0),  	mHasOcclusionQuery(FALSE), +	mHasTimerQuery(FALSE),  	mHasOcclusionQuery2(FALSE),  	mHasPointParameters(FALSE),  	mHasDrawBuffers(FALSE), @@ -445,7 +451,9 @@ LLGLManager::LLGLManager() :  	mIsGFFX(FALSE),  	mATIOffsetVerticalLines(FALSE),  	mATIOldDriver(FALSE), - +#if LL_DARWIN +	mIsMobileGF(FALSE), +#endif  	mHasRequirements(TRUE),  	mHasSeparateSpecularColor(FALSE), @@ -637,6 +645,13 @@ bool LLGLManager::initGL()  		{  			mIsGF3 = TRUE;  		} +#if LL_DARWIN +		else if ((mGLRenderer.find("9400M") != std::string::npos) +			  || (mGLRenderer.find("9600M") != std::string::npos)) +		{ +			mIsMobileGF = TRUE; +		} +#endif  	}  	else if (mGLVendor.find("INTEL") != std::string::npos @@ -745,12 +760,13 @@ bool LLGLManager::initGL()  	{ //using multisample textures on ATI results in black screen for some reason  		mHasTextureMultisample = FALSE;  	} -#endif +  	if (mIsIntel && mGLVersion <= 3.f)  	{ //never try to use framebuffer objects on older intel drivers (crashy)  		mHasFramebufferObject = FALSE;  	} +#endif  	if (mHasFramebufferObject)  	{ @@ -947,13 +963,15 @@ void LLGLManager::initExtensions()  	mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);  	mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");  	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); +	mHasTimerQuery = ExtensionExists("GL_ARB_timer_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); -	mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); +	//mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); +	mHasDepthClamp = FALSE;  	// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad  #ifdef GL_ARB_framebuffer_object  	mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts); @@ -963,6 +981,15 @@ void LLGLManager::initExtensions()  							ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&  							ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);  #endif +#ifdef GL_EXT_texture_sRGB +	mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts); +#endif +	 +#ifdef GL_ARB_framebuffer_sRGB +	mHassRGBFramebuffer = ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts); +#else +	mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts); +#endif  	mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f; @@ -1253,6 +1280,13 @@ void LLGLManager::initExtensions()  		glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");  		glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");  	} +	if (mHasTimerQuery) +	{ +		llinfos << "initExtensions() TimerQuery-related procs..." << llendl; +		glQueryCounter = (PFNGLQUERYCOUNTERPROC) GLH_EXT_GET_PROC_ADDRESS("glQueryCounter"); +		glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjecti64v"); +		glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64v"); +	}  	if (mHasPointParameters)  	{  		llinfos << "initExtensions() PointParameters-related procs..." << llendl; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index d70e764769..60597fd090 100755 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -98,6 +98,7 @@ public:  	BOOL mHasFragmentShader;  	S32  mNumTextureImageUnits;  	BOOL mHasOcclusionQuery; +	BOOL mHasTimerQuery;  	BOOL mHasOcclusionQuery2;  	BOOL mHasPointParameters;  	BOOL mHasDrawBuffers; @@ -115,6 +116,8 @@ public:  	BOOL mHasARBEnvCombine;  	BOOL mHasCubeMap;  	BOOL mHasDebugOutput; +	BOOL mHassRGBTexture; +	BOOL mHassRGBFramebuffer;  	// Vendor-specific extensions  	BOOL mIsATI; @@ -126,6 +129,11 @@ public:  	BOOL mATIOffsetVerticalLines;  	BOOL mATIOldDriver; +#if LL_DARWIN +	// Needed to distinguish problem cards on older Macs that break with Materials +	BOOL mIsMobileGF; +#endif +	  	// Whether this version of GL is good enough for SL to use  	BOOL mHasRequirements; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 509de51f4d..dace572953 100755 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -116,6 +116,11 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB; +// GL_ARB_timer_query +extern PFNGLQUERYCOUNTERPROC glQueryCounter; +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; +  // GL_ARB_point_parameters  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB; @@ -378,6 +383,11 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB; +// GL_ARB_timer_query +extern PFNGLQUERYCOUNTERPROC glQueryCounter; +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; +  // GL_ARB_point_parameters  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB; @@ -619,6 +629,12 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;  extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;  extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB; +// GL_ARB_timer_query +extern PFNGLQUERYCOUNTERPROC glQueryCounter; +extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; +extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; + +  // GL_ARB_point_parameters  extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;  extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 7cbf39096e..62191b4c1a 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -53,6 +53,12 @@ GLhandleARB LLGLSLShader::sCurBoundShader = 0;  LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;  S32 LLGLSLShader::sIndexedTextureChannels = 0;  bool LLGLSLShader::sNoFixedFunction = false; +bool LLGLSLShader::sProfileEnabled = false; +std::set<LLGLSLShader*> LLGLSLShader::sInstances; +U64 LLGLSLShader::sTotalTimeElapsed = 0; +U32 LLGLSLShader::sTotalTrianglesDrawn = 0; +U64 LLGLSLShader::sTotalSamplesDrawn = 0; +U32 LLGLSLShader::sTotalDrawCalls = 0;  //UI shader -- declared here so llui_libtest will link properly  LLGLSLShader	gUIProgram; @@ -87,19 +93,194 @@ LLShaderFeatures::LLShaderFeatures()  //===============================  // LLGLSL Shader implementation  //=============================== + +//static +void LLGLSLShader::initProfile() +{ +	sProfileEnabled = true; +	sTotalTimeElapsed = 0; +	sTotalTrianglesDrawn = 0; +	sTotalSamplesDrawn = 0; +	sTotalDrawCalls = 0; + +	for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) +	{ +		(*iter)->clearStats(); +	} +} + + +struct LLGLSLShaderCompareTimeElapsed +{ +		bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs) +		{ +			return lhs->mTimeElapsed < rhs->mTimeElapsed; +		} +}; + +//static +void LLGLSLShader::finishProfile() +{ +	sProfileEnabled = false; + +	std::vector<LLGLSLShader*> sorted; + +	for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) +	{ +		sorted.push_back(*iter); +	} + +	std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); + +	for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) +	{ +		(*iter)->dumpStats(); +	} + +	llinfos << "-----------------------------------" << llendl; +	llinfos << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << llendl; +	llinfos << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << llendl; +	llinfos << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << llendl; +} + +void LLGLSLShader::clearStats() +{ +	mTrianglesDrawn = 0; +	mTimeElapsed = 0; +	mSamplesDrawn = 0; +	mDrawCalls = 0; +} + +void LLGLSLShader::dumpStats() +{ +	if (mDrawCalls > 0) +	{ +		llinfos << "=============================================" << llendl; +		llinfos << mName << llendl; +		for (U32 i = 0; i < mShaderFiles.size(); ++i) +		{ +			llinfos << mShaderFiles[i].first << llendl; +		} +		llinfos << "=============================================" << llendl; + +		F32 ms = mTimeElapsed/1000000.f; +		F32 seconds = ms/1000.f; + +		F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f; +		F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0); +		tris_sec /= seconds; + +		F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f; +		F32 samples_sec = (F32) mSamplesDrawn/1000000000.0; +		samples_sec /= seconds; + +		F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f; +		U32 avg_batch = mTrianglesDrawn/mDrawCalls; + +		llinfos << "Triangles Drawn: " << mTrianglesDrawn <<  " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << llendl; +		llinfos << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << llendl; +		llinfos << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << llendl; +		llinfos << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << llendl; +	} +} + +//static +void LLGLSLShader::startProfile() +{ +	if (sProfileEnabled && sCurBoundShaderPtr) +	{ +		sCurBoundShaderPtr->placeProfileQuery(); +	} + +} + +//static +void LLGLSLShader::stopProfile(U32 count, U32 mode) +{ +	if (sProfileEnabled) +	{ +		sCurBoundShaderPtr->readProfileQuery(count, mode); +	} +} + +void LLGLSLShader::placeProfileQuery() +{ +#if !LL_DARWIN +	if (mTimerQuery == 0) +	{ +		glGenQueriesARB(1, &mTimerQuery); +	} + +	glBeginQueryARB(GL_SAMPLES_PASSED, 1); +	glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery); +#endif +} + +void LLGLSLShader::readProfileQuery(U32 count, U32 mode) +{ +#if !LL_DARWIN +	glEndQueryARB(GL_TIME_ELAPSED); +	glEndQueryARB(GL_SAMPLES_PASSED); +	 +	U64 time_elapsed = 0; +	glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); + +	U64 samples_passed = 0; +	glGetQueryObjectui64v(1, GL_QUERY_RESULT, &samples_passed); + +	sTotalTimeElapsed += time_elapsed; +	mTimeElapsed += time_elapsed; + +	sTotalSamplesDrawn += samples_passed; +	mSamplesDrawn += samples_passed; + +	U32 tri_count = 0; +	switch (mode) +	{ +		case LLRender::TRIANGLES: tri_count = count/3; break; +		case LLRender::TRIANGLE_FAN: tri_count = count-2; break; +		case LLRender::TRIANGLE_STRIP: tri_count = count-2; break; +		default: tri_count = count; break; //points lines etc just use primitive count +	} + +	mTrianglesDrawn += tri_count; +	sTotalTrianglesDrawn += tri_count; + +	sTotalDrawCalls++; +	mDrawCalls++; +#endif +} + + +  LLGLSLShader::LLGLSLShader() -	: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE) +	: mProgramObject(0),  +	  mAttributeMask(0), +	  mTotalUniformSize(0), +	  mActiveTextureChannels(0),  +	  mShaderLevel(0),  +	  mShaderGroup(SG_DEFAULT),  +	  mUniformsDirty(FALSE), +	  mTimerQuery(0)  { +	 +} +LLGLSLShader::~LLGLSLShader() +{ +	  }  void LLGLSLShader::unload()  { +	sInstances.erase(this); +  	stop_glerror();  	mAttribute.clear();  	mTexture.clear();  	mUniform.clear();  	mShaderFiles.clear(); +	mDefines.clear();  	if (mProgramObject)  	{ @@ -133,6 +314,8 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  								U32 varying_count,  								const char** varyings)  { +	sInstances.insert(this); +  	//reloading, reset matrix hash values  	for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)  	{ @@ -150,7 +333,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();  	for ( ; fileIter != mShaderFiles.end(); fileIter++ )  	{ -		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels); +		GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);  		LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;  		if (shaderhandle > 0)  		{ @@ -285,6 +468,8 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)  	if (res)  	{ //read back channel locations +		mAttributeMask = 0; +  		//read back reserved channels first  		for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)  		{ @@ -293,6 +478,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)  			if (index != -1)  			{  				mAttribute[i] = index; +				mAttributeMask |= 1 << i;  				LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;  			}  		} @@ -325,11 +511,56 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)  	GLenum type;  	GLsizei length; -	GLint size; +	GLint size = -1;  	char name[1024];		/* Flawfinder: ignore */  	name[0] = 0; +  	glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name); +#if !LL_DARWIN +	if (size > 0) +	{ +		switch(type) +		{ +			case GL_FLOAT_VEC2: size *= 2; break; +			case GL_FLOAT_VEC3: size *= 3; break; +			case GL_FLOAT_VEC4: size *= 4; break; +			case GL_DOUBLE: size *= 2; break; +			case GL_DOUBLE_VEC2: size *= 2; break; +			case GL_DOUBLE_VEC3: size *= 6; break; +			case GL_DOUBLE_VEC4: size *= 8; break; +			case GL_INT_VEC2: size *= 2; break; +			case GL_INT_VEC3: size *= 3; break; +			case GL_INT_VEC4: size *= 4; break; +			case GL_UNSIGNED_INT_VEC2: size *= 2; break; +			case GL_UNSIGNED_INT_VEC3: size *= 3; break; +			case GL_UNSIGNED_INT_VEC4: size *= 4; break; +			case GL_BOOL_VEC2: size *= 2; break; +			case GL_BOOL_VEC3: size *= 3; break; +			case GL_BOOL_VEC4: size *= 4; break; +			case GL_FLOAT_MAT2: size *= 4; break; +			case GL_FLOAT_MAT3: size *= 9; break; +			case GL_FLOAT_MAT4: size *= 16; break; +			case GL_FLOAT_MAT2x3: size *= 6; break; +			case GL_FLOAT_MAT2x4: size *= 8; break; +			case GL_FLOAT_MAT3x2: size *= 6; break; +			case GL_FLOAT_MAT3x4: size *= 12; break; +			case GL_FLOAT_MAT4x2: size *= 8; break; +			case GL_FLOAT_MAT4x3: size *= 12; break; +			case GL_DOUBLE_MAT2: size *= 8; break; +			case GL_DOUBLE_MAT3: size *= 18; break; +			case GL_DOUBLE_MAT4: size *= 32; break; +			case GL_DOUBLE_MAT2x3: size *= 12; break; +			case GL_DOUBLE_MAT2x4: size *= 16; break; +			case GL_DOUBLE_MAT3x2: size *= 12; break; +			case GL_DOUBLE_MAT3x4: size *= 24; break; +			case GL_DOUBLE_MAT4x2: size *= 16; break; +			case GL_DOUBLE_MAT4x3: size *= 24; break; +		} +		mTotalUniformSize += size; +	} +#endif +  	S32 location = glGetUniformLocationARB(mProgramObject, name);  	if (location != -1)  	{ @@ -372,11 +603,21 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)  			}  		}  	} - } +} + +void LLGLSLShader::addPermutation(std::string name, std::string value) +{ +	mDefines[name] = value; +} + +void LLGLSLShader::removePermutation(std::string name) +{ +	mDefines[name].erase(); +}  GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)  { -	if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB || +	if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||  		type == GL_SAMPLER_2D_MULTISAMPLE)  	{	//this here is a texture  		glUniform1iARB(location, mActiveTextureChannels); @@ -390,6 +631,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)  {  	BOOL res = TRUE; +	mTotalUniformSize = 0;  	mActiveTextureChannels = 0;  	mUniform.clear();  	mUniformMap.clear(); @@ -413,6 +655,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)  	unbind(); +	LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << llendl;  	return res;  } @@ -471,6 +714,58 @@ void LLGLSLShader::bindNoShader(void)  	}  } +S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode) +{ +	S32 channel = 0; +	channel = getUniformLocation(uniform); +	 +	return bindTexture(channel, texture, mode); +} + +S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode) +{ +	if (uniform < 0 || uniform >= (S32)mTexture.size()) +	{ +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; +		return -1; +	} +	 +	uniform = mTexture[uniform]; +	 +	if (uniform > -1) +	{ +		gGL.getTexUnit(uniform)->bind(texture, mode); +	} +	 +	return uniform; +} + +S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) +{ +	S32 channel = 0; +	channel = getUniformLocation(uniform); +	 +	return unbindTexture(channel); +} + +S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) +{ +	if (uniform < 0 || uniform >= (S32)mTexture.size()) +	{ +		UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; +		return -1; +	} +	 +	uniform = mTexture[uniform]; +	 +	if (uniform > -1) +	{ +		gGL.getTexUnit(uniform)->unbind(mode); +	} +	 +	return uniform; +} +  S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)  {  	if (uniform < 0 || uniform >= (S32)mTexture.size()) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index cf21101e35..3c775cde27 100755 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -67,14 +67,29 @@ public:  		SG_WATER  	}; +	static std::set<LLGLSLShader*> sInstances; +	static bool sProfileEnabled; +  	LLGLSLShader(); +	~LLGLSLShader();  	static GLhandleARB sCurBoundShader;  	static LLGLSLShader* sCurBoundShaderPtr;  	static S32 sIndexedTextureChannels;  	static bool sNoFixedFunction; +	static void initProfile(); +	static void finishProfile(); + +	static void startProfile(); +	static void stopProfile(U32 count, U32 mode); +  	void unload(); +	void clearStats(); +	void dumpStats(); +	void placeProfileQuery(); +	void readProfileQuery(U32 count, U32 mode); +  	BOOL createShader(std::vector<std::string> * attributes,  						std::vector<std::string> * uniforms,  						U32 varying_count = 0, @@ -123,12 +138,22 @@ public:  	GLint getAttribLocation(U32 attrib);  	GLint mapUniformTextureChannel(GLint location, GLenum type); +	void addPermutation(std::string name, std::string value); +	void removePermutation(std::string name); +	  	//enable/disable texture channel for specified uniform  	//if given texture uniform is active in the shader,   	//the corresponding channel will be active upon return  	//returns channel texture is enabled in from [0-MAX)  	S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); -	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);  +	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	 +	// bindTexture returns the texture unit we've bound the texture to. +	// You can reuse the return value to unbind a texture when required. +	S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); +	S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);      BOOL link(BOOL suppress_errors = FALSE);  	void bind(); @@ -142,10 +167,12 @@ public:  	GLhandleARB mProgramObject;  	std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel +	U32 mAttributeMask;  //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())  	std::vector<GLint> mUniform;   //lookup table of uniform enum to uniform location  	std::map<std::string, GLint> mUniformMap;  //lookup map of uniform name to uniform location  	std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value  	std::vector<GLint> mTexture; +	S32 mTotalUniformSize;  	S32 mActiveTextureChannels;  	S32 mShaderLevel;  	S32 mShaderGroup; @@ -153,6 +180,18 @@ public:  	LLShaderFeatures mFeatures;  	std::vector< std::pair< std::string, GLenum > > mShaderFiles;  	std::string mName; +	boost::unordered_map<std::string, std::string> mDefines; + +	//statistcis for profiling shader performance +	U32 mTimerQuery; +	U64 mTimeElapsed; +	static U64 sTotalTimeElapsed; +	U32 mTrianglesDrawn; +	static U32 sTotalTrianglesDrawn; +	U64 mSamplesDrawn; +	static U64 sTotalSamplesDrawn; +	U32 mDrawCalls; +	static U32 sTotalDrawCalls;  };  //UI shader (declared here so llui_libtest will link properly) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 5c171d372c..38764eba23 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -748,12 +748,16 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  				S32 height = getHeight(mCurrentDiscardLevel);  				S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;  				S32 w = width, h = height; + + +				const U8* new_data = 0; +				(void)new_data; +  				const U8* prev_mip_data = 0;  				const U8* cur_mip_data = 0;  #ifdef SHOW_ASSERT  				S32 cur_mip_size = 0;  #endif -				  				mMipLevels = nummips;  				for (int m=0; m<nummips; m++) @@ -773,14 +777,22 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  						llassert(cur_mip_size == bytes*4);  #endif  						U8* new_data = new U8[bytes]; + +#ifdef SHOW_ASSERT +						llassert(prev_mip_data); +						llassert(cur_mip_size == bytes*4);  						llassert_always(new_data); +#endif +  						LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);  						cur_mip_data = new_data;  #ifdef SHOW_ASSERT  						cur_mip_size = bytes;   #endif +  					}  					llassert(w > 0 && h > 0 && cur_mip_data); +					(void)cur_mip_data;  					{  // 						LLFastTimer t1(FTM_TEMP4);  						if(mFormatSwapBytes) @@ -1119,30 +1131,30 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip  			default:  			{  				if (type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1) -				{ //unknown internal format or unknown number of mip levels, not safe to reuse -					glDeleteTextures(numTextures, textures); -				} -				else -				{ -					for (S32 i = 0; i < numTextures; ++i) -					{ //remove texture from VRAM by setting its size to zero +		{ //unknown internal format or unknown number of mip levels, not safe to reuse +			glDeleteTextures(numTextures, textures); +		} +		else +		{ +			for (S32 i = 0; i < numTextures; ++i) +			{ //remove texture from VRAM by setting its size to zero -						for (S32 j = 0; j <= mip_levels; j++) -						{ -							gGL.getTexUnit(0)->bindManual(type, textures[i]); +				for (S32 j = 0; j <= mip_levels; j++) +				{ +					gGL.getTexUnit(0)->bindManual(type, textures[i]);  							U32 internal_type = LLTexUnit::getInternalType(type);  							glTexImage2D(internal_type, j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);  							stop_glerror(); -						} +				} -						llassert(std::find(sDeadTextureList[type][format].begin(), -							sDeadTextureList[type][format].end(), textures[i]) ==  -							sDeadTextureList[type][format].end()); +				llassert(std::find(sDeadTextureList[type][format].begin(), +								   sDeadTextureList[type][format].end(), textures[i]) ==  +								   sDeadTextureList[type][format].end()); -						sDeadTextureList[type][format].push_back(textures[i]); -					}	 -				}				 -			} +				sDeadTextureList[type][format].push_back(textures[i]); +			}	 +		} +	}  			break;  		}  	} diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 78a310e525..98222939e7 100755 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -262,6 +262,14 @@ class LLRender  	friend class LLTexUnit;  public: +	enum eTexIndex +	{ +		DIFFUSE_MAP = 0, +		NORMAL_MAP, +		SPECULAR_MAP, +		NUM_TEXTURE_CHANNELS, +	}; +	  	typedef enum {  		TRIANGLES = 0,  		TRIANGLE_STRIP, diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b6a9a6b653..fea4ee2819 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -521,7 +521,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)  	}   } -GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels) +GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)  {  	GLenum error = GL_NO_ERROR;  	if (gDebugGL) @@ -650,13 +650,15 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  			text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");  		}  	} - -	//copy preprocessor definitions into buffer -	for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter) +	 +	if (defines) +	{ +		for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)  	{  		std::string define = "#define " + iter->first + " " + iter->second + "\n";  		text[count++] = (GLcharARB *) strdup(define.c_str());  	} +	}  	if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)  	{ @@ -693,6 +695,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		}  		*/ +		text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n"); +  		//uniform declartion  		for (S32 i = 0; i < texture_index_channels; ++i)  		{ @@ -750,6 +754,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  			llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;  		}  	} +	else +	{ +		text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n"); +	}  	//copy file into memory  	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )  @@ -806,7 +814,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  				//an error occured, print log  				LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;  				dumpObjectLog(ret); -  #if LL_WINDOWS  				std::stringstream ostr;  				//dump shader source for debugging @@ -824,8 +831,20 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  				}  				LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl; -#endif // LL_WINDOWS - +#else +				std::string str; +				 +				for (GLuint i = 0; i < count; i++) { +					str.append(text[i]); +					 +					if (i % 128 == 0) +					{ +						LL_WARNS("ShaderLoading") << str << llendl; +						str = ""; +					} +				} +#endif +				  				ret = 0;  			}  		} @@ -854,7 +873,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		if (shader_level > 1)  		{  			shader_level--; -			return loadShaderFile(filename,shader_level,type,texture_index_channels); +			return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);  		}  		LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;	  	} @@ -958,7 +977,7 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedAttribs.push_back("texcoord3");  	mReservedAttribs.push_back("diffuse_color");  	mReservedAttribs.push_back("emissive"); -	mReservedAttribs.push_back("binormal"); +	mReservedAttribs.push_back("tangent");  	mReservedAttribs.push_back("weight");  	mReservedAttribs.push_back("weight4");  	mReservedAttribs.push_back("clothing"); @@ -1055,6 +1074,7 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("minimum_alpha"); +	mReservedUniforms.push_back("emissive_brightness");  	mReservedUniforms.push_back("shadow_matrix");  	mReservedUniforms.push_back("env_mat"); @@ -1115,6 +1135,12 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("lightMap");  	mReservedUniforms.push_back("bloomMap");  	mReservedUniforms.push_back("projectionMap"); +	 +	mReservedUniforms.push_back("global_gamma"); +	mReservedUniforms.push_back("texture_gamma"); +	 +	mReservedUniforms.push_back("specular_color"); +	mReservedUniforms.push_back("env_intensity");  	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 7a16b7c20f..c049e935b8 100755 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -109,6 +109,7 @@ public:  		GLOW_DELTA,  		MINIMUM_ALPHA, +		EMISSIVE_BRIGHTNESS,  		DEFERRED_SHADOW_MATRIX,  		DEFERRED_ENV_MAT, @@ -164,6 +165,13 @@ public:  		DEFERRED_LIGHT,  		DEFERRED_BLOOM,  		DEFERRED_PROJECTION, +		 +		GLOBAL_GAMMA, +		TEXTURE_GAMMA, +		 +		SPECULAR_COLOR, +		ENVIRONMENT_INTENSITY, +		  		END_RESERVED_UNIFORMS  	} eGLSLReservedUniforms; @@ -176,7 +184,7 @@ public:  	void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);  	BOOL	linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);  	BOOL	validateProgramObject(GLhandleARB obj); -	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1); +	GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);  	// Implemented in the application to actually point to the shader directory.  	virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4909b43e8a..01541026b1 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -342,13 +342,32 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =  	sizeof(LLVector2), // TYPE_TEXCOORD3,  	sizeof(LLColor4U), // TYPE_COLOR,  	sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently -	sizeof(LLVector4), // TYPE_BINORMAL, +	sizeof(LLVector4), // TYPE_TANGENT,  	sizeof(F32),	   // TYPE_WEIGHT,  	sizeof(LLVector4), // TYPE_WEIGHT4,  	sizeof(LLVector4), // TYPE_CLOTHWEIGHT,  	sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes  }; +static std::string vb_type_name[] = +{ +	"TYPE_VERTEX", +	"TYPE_NORMAL", +	"TYPE_TEXCOORD0", +	"TYPE_TEXCOORD1", +	"TYPE_TEXCOORD2", +	"TYPE_TEXCOORD3", +	"TYPE_COLOR", +	"TYPE_EMISSIVE", +	"TYPE_TANGENT", +	"TYPE_WEIGHT", +	"TYPE_WEIGHT4", +	"TYPE_CLOTHWEIGHT", +	"TYPE_TEXTURE_INDEX", +	"TYPE_MAX", +	"TYPE_INDEX",	 +}; +  U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =   {  	GL_TRIANGLES, @@ -523,16 +542,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  				}  			} -			if (sLastMask & MAP_BINORMAL) +			if (sLastMask & MAP_TANGENT)  			{ -				if (!(data_mask & MAP_BINORMAL)) +				if (!(data_mask & MAP_TANGENT))  				{  					glClientActiveTextureARB(GL_TEXTURE2_ARB);  					glDisableClientState(GL_TEXTURE_COORD_ARRAY);  					glClientActiveTextureARB(GL_TEXTURE0_ARB);  				}  			} -			else if (data_mask & MAP_BINORMAL) +			else if (data_mask & MAP_TANGENT)  			{  				glClientActiveTextureARB(GL_TEXTURE2_ARB);  				glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -593,8 +612,9 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con  		glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);  		glNormalPointer(GL_FLOAT, 0, norm[0].mV);  	} - +	LLGLSLShader::startProfile();  	glDrawArrays(sGLMode[mode], 0, count); +	LLGLSLShader::stopProfile(count, mode);  }  //static @@ -631,7 +651,9 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto  		glVertexPointer(3, GL_FLOAT, 16, pos);  	} +	LLGLSLShader::startProfile();  	glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); +	LLGLSLShader::stopProfile(num_indices, mode);  }  void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const @@ -731,9 +753,14 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  	U16* idx = ((U16*) getIndicesPointer())+indices_offset;  	stop_glerror(); +	LLGLSLShader::startProfile();  	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,   		idx); +	LLGLSLShader::stopProfile(count, mode);  	stop_glerror(); + +	 +  	placeFence();  } @@ -777,8 +804,10 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  	}  	stop_glerror(); +	LLGLSLShader::startProfile();  	glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,  		((U16*) getIndicesPointer()) + indices_offset); +	LLGLSLShader::stopProfile(count, mode);  	stop_glerror();  	placeFence();  } @@ -820,9 +849,12 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  	{  		LLFastTimer t2(FTM_GL_DRAW_ARRAYS); -		stop_glerror(); -		glDrawArrays(sGLMode[mode], first, count); -	} +	stop_glerror(); +	LLGLSLShader::startProfile(); +	glDrawArrays(sGLMode[mode], first, count); +	LLGLSLShader::stopProfile(count, mode); +        } +  	stop_glerror();  	placeFence();  } @@ -1322,7 +1354,7 @@ void LLVertexBuffer::setupVertexArray()  		2, //TYPE_TEXCOORD3,  		4, //TYPE_COLOR,  		4, //TYPE_EMISSIVE, -		3, //TYPE_BINORMAL, +		4, //TYPE_TANGENT,  		1, //TYPE_WEIGHT,  		4, //TYPE_WEIGHT4,  		4, //TYPE_CLOTHWEIGHT, @@ -1339,7 +1371,7 @@ void LLVertexBuffer::setupVertexArray()  		GL_FLOAT, //TYPE_TEXCOORD3,  		GL_UNSIGNED_BYTE, //TYPE_COLOR,  		GL_UNSIGNED_BYTE, //TYPE_EMISSIVE, -		GL_FLOAT,   //TYPE_BINORMAL, +		GL_FLOAT,   //TYPE_TANGENT,  		GL_FLOAT, //TYPE_WEIGHT,  		GL_FLOAT, //TYPE_WEIGHT4,  		GL_FLOAT, //TYPE_CLOTHWEIGHT, @@ -1356,7 +1388,7 @@ void LLVertexBuffer::setupVertexArray()  		false, //TYPE_TEXCOORD3,  		false, //TYPE_COLOR,  		false, //TYPE_EMISSIVE, -		false, //TYPE_BINORMAL, +		false, //TYPE_TANGENT,  		false, //TYPE_WEIGHT,  		false, //TYPE_WEIGHT4,  		false, //TYPE_CLOTHWEIGHT, @@ -1373,7 +1405,7 @@ void LLVertexBuffer::setupVertexArray()  		GL_FALSE, //TYPE_TEXCOORD3,  		GL_TRUE, //TYPE_COLOR,  		GL_TRUE, //TYPE_EMISSIVE, -		GL_FALSE,   //TYPE_BINORMAL, +		GL_FALSE,   //TYPE_TANGENT,  		GL_FALSE, //TYPE_WEIGHT,  		GL_FALSE, //TYPE_WEIGHT4,  		GL_FALSE, //TYPE_CLOTHWEIGHT, @@ -2038,14 +2070,21 @@ bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 inde  {  	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);  } - +bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range) +{ +	return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range); +}  bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  {  	return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);  } -bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)  { -	return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range); +	return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range); +} +bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range) +{ +	return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);  }  bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)  { @@ -2200,7 +2239,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  			if ((data_mask & required_mask) != required_mask)  			{ -				llerrs << "Shader consumption mismatches data provision." << llendl; +				llwarns << "Shader consumption mismatches data provision." << llendl;  			}  		}  	} @@ -2318,6 +2357,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  	if (gDebugGL && ((data_mask & mTypeMask) != data_mask))  	{ +		for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) +		{ +			U32 mask = 1 << i; +			if (mask & data_mask && !(mask & mTypeMask)) +			{ //bit set in data_mask, but not set in mTypeMask +				llwarns << "Missing required component " << vb_type_name[i] << llendl; +			} +		}  		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;  	} @@ -2347,11 +2394,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);  			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{ -			S32 loc = TYPE_BINORMAL; -			void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); -			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); +			S32 loc = TYPE_TANGENT; +			void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); +			glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);  		}  		if (data_mask & MAP_TEXCOORD0)  		{ @@ -2429,10 +2476,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		} -		if (data_mask & MAP_BINORMAL) +		if (data_mask & MAP_TANGENT)  		{  			glClientActiveTextureARB(GL_TEXTURE2_ARB); -			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +			glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));  			glClientActiveTextureARB(GL_TEXTURE0_ARB);  		}  		if (data_mask & MAP_TEXCOORD0) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 11fa4ab6a0..04806c1d8c 100755 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -174,7 +174,7 @@ public:  		TYPE_TEXCOORD3,  		TYPE_COLOR,  		TYPE_EMISSIVE, -		TYPE_BINORMAL, +		TYPE_TANGENT,  		TYPE_WEIGHT,  		TYPE_WEIGHT4,  		TYPE_CLOTHWEIGHT, @@ -192,7 +192,7 @@ public:  		MAP_COLOR = (1<<TYPE_COLOR),  		MAP_EMISSIVE = (1<<TYPE_EMISSIVE),  		// These use VertexAttribPointer and should possibly be made generic -		MAP_BINORMAL = (1<<TYPE_BINORMAL), +		MAP_TANGENT = (1<<TYPE_TANGENT),  		MAP_WEIGHT = (1<<TYPE_WEIGHT),  		MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),  		MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), @@ -250,8 +250,10 @@ public:  	bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); -	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  | 
