PageRenderTime 119ms CodeModel.GetById 55ms app.highlight 57ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llrender/llshadermgr.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1104 lines | 856 code | 131 blank | 117 comment | 184 complexity | b30b483738280cdb848d54780ac3fe60 MD5 | raw file
   1/** 
   2 * @file llshadermgr.cpp
   3 * @brief Shader manager implementation.
   4 *
   5 * $LicenseInfo:firstyear=2005&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "linden_common.h"
  28
  29#include "llshadermgr.h"
  30
  31#include "llfile.h"
  32#include "llrender.h"
  33
  34#if LL_DARWIN
  35#include "OpenGL/OpenGL.h"
  36#endif
  37
  38#ifdef LL_RELEASE_FOR_DOWNLOAD
  39#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
  40#else
  41#define UNIFORM_ERRS LL_ERRS("Shader")
  42#endif
  43
  44// Lots of STL stuff in here, using namespace std to keep things more readable
  45using std::vector;
  46using std::pair;
  47using std::make_pair;
  48using std::string;
  49
  50LLShaderMgr * LLShaderMgr::sInstance = NULL;
  51
  52LLShaderMgr::LLShaderMgr()
  53{
  54}
  55
  56
  57LLShaderMgr::~LLShaderMgr()
  58{
  59}
  60
  61// static
  62LLShaderMgr * LLShaderMgr::instance()
  63{
  64	if(NULL == sInstance)
  65	{
  66		LL_ERRS("Shaders") << "LLShaderMgr should already have been instantiated by the application!" << LL_ENDL;
  67	}
  68
  69	return sInstance;
  70}
  71
  72BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
  73{
  74	llassert_always(shader != NULL);
  75	LLShaderFeatures *features = & shader->mFeatures;
  76	
  77	//////////////////////////////////////
  78	// Attach Vertex Shader Features First
  79	//////////////////////////////////////
  80	
  81	// NOTE order of shader object attaching is VERY IMPORTANT!!!
  82	if (features->calculatesAtmospherics)
  83	{
  84		if (features->hasWaterFog)
  85		{
  86			if (!shader->attachObject("windlight/atmosphericsVarsWaterV.glsl"))
  87			{
  88				return FALSE;
  89			}
  90		}
  91		else if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
  92		{
  93			return FALSE;
  94		}
  95	}
  96
  97	if (features->calculatesLighting)
  98	{
  99		if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
 100		{
 101			return FALSE;
 102		}
 103		
 104		if (features->isSpecular)
 105		{
 106			if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
 107			{
 108				return FALSE;
 109			}
 110		
 111			if (!features->isAlphaLighting)
 112			{
 113				if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
 114				{
 115					return FALSE;
 116				}
 117			}
 118			
 119			if (!shader->attachObject("lighting/lightSpecularV.glsl"))
 120			{
 121				return FALSE;
 122			}
 123		}
 124		else 
 125		{
 126			if (!shader->attachObject("lighting/lightFuncV.glsl"))
 127			{
 128				return FALSE;
 129			}
 130			
 131			if (!features->isAlphaLighting)
 132			{
 133				if (!shader->attachObject("lighting/sumLightsV.glsl"))
 134				{
 135					return FALSE;
 136				}
 137			}
 138			
 139			if (!shader->attachObject("lighting/lightV.glsl"))
 140			{
 141				return FALSE;
 142			}
 143		}
 144	}
 145	
 146	// NOTE order of shader object attaching is VERY IMPORTANT!!!
 147	if (features->calculatesAtmospherics)
 148	{
 149		if (!shader->attachObject("windlight/atmosphericsV.glsl"))
 150		{
 151			return FALSE;
 152		}
 153	}
 154
 155	if (features->hasSkinning)
 156	{
 157		if (!shader->attachObject("avatar/avatarSkinV.glsl"))
 158		{
 159			return FALSE;
 160		}
 161	}
 162
 163	if (features->hasObjectSkinning)
 164	{
 165		if (!shader->attachObject("avatar/objectSkinV.glsl"))
 166		{
 167			return FALSE;
 168		}
 169	}
 170	
 171	///////////////////////////////////////
 172	// Attach Fragment Shader Features Next
 173	///////////////////////////////////////
 174
 175	if(features->calculatesAtmospherics)
 176	{
 177		if (features->hasWaterFog)
 178		{
 179			if (!shader->attachObject("windlight/atmosphericsVarsWaterF.glsl"))
 180			{
 181				return FALSE;
 182			}
 183		}
 184		else if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
 185		{
 186			return FALSE;
 187		}
 188	}
 189
 190	// NOTE order of shader object attaching is VERY IMPORTANT!!!
 191	if (features->hasGamma)
 192	{
 193		if (!shader->attachObject("windlight/gammaF.glsl"))
 194		{
 195			return FALSE;
 196		}
 197	}
 198	
 199	if (features->hasAtmospherics)
 200	{
 201		if (!shader->attachObject("windlight/atmosphericsF.glsl"))
 202		{
 203			return FALSE;
 204		}
 205	}
 206	
 207	if (features->hasTransport)
 208	{
 209		if (!shader->attachObject("windlight/transportF.glsl"))
 210		{
 211			return FALSE;
 212		}
 213
 214		// Test hasFullbright and hasShiny and attach fullbright and 
 215		// fullbright shiny atmos transport if we split them out.
 216	}
 217
 218	// NOTE order of shader object attaching is VERY IMPORTANT!!!
 219	if (features->hasWaterFog)
 220	{
 221		if (!shader->attachObject("environment/waterFogF.glsl"))
 222		{
 223			return FALSE;
 224		}
 225	}
 226	
 227	if (features->hasLighting)
 228	{
 229		if (features->hasWaterFog)
 230		{
 231			if (features->disableTextureIndex)
 232			{
 233				if (features->hasAlphaMask)
 234				{
 235					if (!shader->attachObject("lighting/lightWaterAlphaMaskNonIndexedF.glsl"))
 236					{
 237						return FALSE;
 238					}
 239				}
 240				else
 241				{
 242					if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
 243					{
 244						return FALSE;
 245					}
 246				}
 247			}
 248			else 
 249			{
 250				if (features->hasAlphaMask)
 251				{
 252					if (!shader->attachObject("lighting/lightWaterAlphaMaskF.glsl"))
 253					{
 254						return FALSE;
 255					}
 256				}
 257				else
 258				{
 259					if (!shader->attachObject("lighting/lightWaterF.glsl"))
 260					{
 261						return FALSE;
 262					}
 263				}
 264				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 265			}
 266		}
 267		
 268		else
 269		{
 270			if (features->disableTextureIndex)
 271			{
 272				if (features->hasAlphaMask)
 273				{
 274					if (!shader->attachObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
 275					{
 276						return FALSE;
 277					}
 278				}
 279				else
 280				{
 281					if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
 282					{
 283						return FALSE;
 284					}
 285				}
 286			}
 287			else 
 288			{
 289				if (features->hasAlphaMask)
 290				{
 291					if (!shader->attachObject("lighting/lightAlphaMaskF.glsl"))
 292					{
 293						return FALSE;
 294					}
 295				}
 296				else
 297				{
 298					if (!shader->attachObject("lighting/lightF.glsl"))
 299					{
 300						return FALSE;
 301					}
 302				}
 303				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 304			}
 305		}
 306	}
 307	
 308	// NOTE order of shader object attaching is VERY IMPORTANT!!!
 309	else if (features->isFullbright)
 310	{
 311	
 312		if (features->isShiny && features->hasWaterFog)
 313		{
 314			if (features->disableTextureIndex)
 315			{
 316				if (!shader->attachObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl"))
 317				{
 318					return FALSE;
 319				}
 320			}
 321			else 
 322			{
 323				if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
 324				{
 325					return FALSE;
 326				}
 327				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 328			}
 329		}
 330		else if (features->hasWaterFog)
 331		{
 332			if (features->disableTextureIndex)
 333			{
 334				if (features->hasAlphaMask)
 335				{
 336					if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl"))
 337					{
 338						return FALSE;
 339					}
 340				}
 341				else if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
 342				{
 343					return FALSE;
 344				}
 345			}
 346			else 
 347			{
 348				if (features->hasAlphaMask)
 349				{
 350					if (!shader->attachObject("lighting/lightFullbrightWaterAlphaMaskF.glsl"))
 351					{
 352						return FALSE;
 353					}
 354				}
 355				else if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
 356				{
 357					return FALSE;
 358				}
 359				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 360			}
 361		}
 362		
 363		else if (features->isShiny)
 364		{
 365			if (features->disableTextureIndex)
 366			{
 367				if (!shader->attachObject("lighting/lightFullbrightShinyNonIndexedF.glsl"))
 368				{
 369					return FALSE;
 370				}
 371			}
 372			else 
 373			{
 374				if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
 375				{
 376					return FALSE;
 377				}
 378				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 379			}
 380		}
 381		
 382		else
 383		{
 384			if (features->disableTextureIndex)
 385			{
 386
 387				if (features->hasAlphaMask)
 388				{
 389					if (!shader->attachObject("lighting/lightFullbrightNonIndexedAlphaMaskF.glsl"))
 390					{
 391						return FALSE;
 392					}
 393				}
 394				else
 395				{
 396					if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
 397					{
 398						return FALSE;
 399					}
 400				}
 401			}
 402			else 
 403			{
 404				if (features->hasAlphaMask)
 405				{
 406					if (!shader->attachObject("lighting/lightFullbrightAlphaMaskF.glsl"))
 407					{
 408						return FALSE;
 409					}
 410				}
 411				else
 412				{
 413					if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
 414					{
 415						return FALSE;
 416					}
 417				}
 418				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 419			}
 420		}
 421	}
 422
 423	// NOTE order of shader object attaching is VERY IMPORTANT!!!
 424	else if (features->isShiny)
 425	{
 426	
 427		if (features->hasWaterFog)
 428		{
 429			if (features->disableTextureIndex)
 430			{
 431				if (!shader->attachObject("lighting/lightShinyWaterNonIndexedF.glsl"))
 432				{
 433					return FALSE;
 434				}
 435			}
 436			else 
 437			{
 438				if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
 439				{
 440					return FALSE;
 441				}
 442				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 443			}
 444		}
 445		
 446		else 
 447		{
 448			if (features->disableTextureIndex)
 449			{
 450				if (!shader->attachObject("lighting/lightShinyNonIndexedF.glsl"))
 451				{
 452					return FALSE;
 453				}
 454			}
 455			else 
 456			{
 457				if (!shader->attachObject("lighting/lightShinyF.glsl"))
 458				{
 459					return FALSE;
 460				}
 461				shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
 462			}
 463		}
 464	}
 465
 466	if (features->mIndexedTextureChannels <= 1)
 467	{
 468		if (!shader->attachObject("objects/nonindexedTextureV.glsl"))
 469		{
 470			return FALSE;
 471		}
 472	}
 473	else
 474	{
 475		if (!shader->attachObject("objects/indexedTextureV.glsl"))
 476		{
 477			return FALSE;
 478		}
 479	}
 480
 481	return TRUE;
 482}
 483
 484//============================================================================
 485// Load Shader
 486
 487static std::string get_object_log(GLhandleARB ret)
 488{
 489	std::string res;
 490	
 491	//get log length 
 492	GLint length;
 493	glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
 494	if (length > 0)
 495	{
 496		//the log could be any size, so allocate appropriately
 497		GLcharARB* log = new GLcharARB[length];
 498		glGetInfoLogARB(ret, length, &length, log);
 499		res = std::string((char *)log);
 500		delete[] log;
 501	}
 502	return res;
 503}
 504
 505void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) 
 506{
 507	std::string log = get_object_log(ret);
 508	if ( log.length() > 0 )
 509	{
 510		if (warns)
 511		{
 512			LL_WARNS("ShaderLoading") << log << LL_ENDL;
 513		}
 514		else
 515		{
 516			LL_INFOS("ShaderLoading") << log << LL_ENDL;
 517		}
 518	}
 519 }
 520
 521GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
 522{
 523	GLenum error = GL_NO_ERROR;
 524	if (gDebugGL)
 525	{
 526		error = glGetError();
 527		if (error != GL_NO_ERROR)
 528		{
 529			LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
 530		}
 531	}
 532	
 533	LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
 534
 535	if (filename.empty()) 
 536	{
 537		return 0;
 538	}
 539
 540
 541	//read in from file
 542	LLFILE* file = NULL;
 543
 544	S32 try_gpu_class = shader_level;
 545	S32 gpu_class;
 546
 547	//find the most relevant file
 548	for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
 549	{	//search from the current gpu class down to class 1 to find the most relevant shader
 550		std::stringstream fname;
 551		fname << getShaderDirPrefix();
 552		fname << gpu_class << "/" << filename;
 553		
 554 		LL_DEBUGS("ShaderLoading") << "Looking in " << fname.str() << LL_ENDL;
 555		file = LLFile::fopen(fname.str(), "r");		/* Flawfinder: ignore */
 556		if (file)
 557		{
 558			LL_INFOS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
 559			break; // done
 560		}
 561	}
 562	
 563	if (file == NULL)
 564	{
 565		LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << filename << LL_ENDL;
 566		return 0;
 567	}
 568
 569	//we can't have any lines longer than 1024 characters 
 570	//or any shaders longer than 4096 lines... deal - DaveP
 571	GLcharARB buff[1024];
 572	GLcharARB* text[4096];
 573	GLuint count = 0;
 574
 575	F32 version = gGLManager.mGLVersion;
 576
 577//hack to never use GLSL > 1.20 on OSX
 578#if LL_DARWIN
 579	version = llmin(version, 2.9f);
 580#endif
 581
 582	if (version < 2.1f)
 583	{
 584		text[count++] = strdup("#version 110\n");
 585		text[count++] = strdup("#define ATTRIBUTE attribute\n");
 586		text[count++] = strdup("#define VARYING varying\n");
 587	}
 588	else if (version < 3.3f)
 589	{
 590		//set version to 1.20
 591		text[count++] = strdup("#version 120\n");
 592		text[count++] = strdup("#define FXAA_GLSL_120 1\n");
 593		text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
 594		text[count++] = strdup("#define ATTRIBUTE attribute\n");
 595		text[count++] = strdup("#define VARYING varying\n");
 596	}
 597	else
 598	{  
 599		if (version < 4.f)
 600		{
 601			//set version to 1.30
 602			text[count++] = strdup("#version 130\n");
 603		}
 604		else
 605		{ //set version to 400
 606			text[count++] = strdup("#version 400\n");
 607		}
 608
 609		text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
 610		text[count++] = strdup("#define FXAA_GLSL_130 1\n");
 611
 612		text[count++] = strdup("#define ATTRIBUTE in\n");
 613
 614		if (type == GL_VERTEX_SHADER_ARB)
 615		{ //"varying" state is "out" in a vertex program, "in" in a fragment program 
 616			// ("varying" is deprecated after version 1.20)
 617			text[count++] = strdup("#define VARYING out\n");
 618		}
 619		else
 620		{
 621			text[count++] = strdup("#define VARYING in\n");
 622		}
 623
 624		//backwards compatibility with legacy texture lookup syntax
 625		text[count++] = strdup("#define textureCube texture\n");
 626		text[count++] = strdup("#define texture2DLod textureLod\n");
 627		text[count++] = strdup("#define	shadow2D(a,b) vec2(texture(a,b))\n");
 628	}
 629
 630	//copy preprocessor definitions into buffer
 631	for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
 632	{
 633		std::string define = "#define " + iter->first + " " + iter->second + "\n";
 634		text[count++] = (GLcharARB *) strdup(define.c_str());
 635	}
 636
 637	if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
 638	{
 639		//use specified number of texture channels for indexed texture rendering
 640
 641		/* prepend shader code that looks like this:
 642
 643		uniform sampler2D tex0;
 644		uniform sampler2D tex1;
 645		uniform sampler2D tex2;
 646		.
 647		.
 648		.
 649		uniform sampler2D texN;
 650		
 651		VARYING float vary_texture_index;
 652
 653		vec4 diffuseLookup(vec2 texcoord)
 654		{
 655			switch (int(vary_texture_index+0.25))
 656			{
 657				case 0: return texture2D(tex0, texcoord);
 658				case 1: return texture2D(tex1, texcoord);
 659				case 2: return texture2D(tex2, texcoord);
 660				.
 661				.
 662				.
 663				case N: return texture2D(texN, texcoord);
 664			}
 665
 666			return vec4(0,0,0,0);
 667		}
 668		*/
 669
 670		//uniform declartion
 671		for (S32 i = 0; i < texture_index_channels; ++i)
 672		{
 673			std::string decl = llformat("uniform sampler2D tex%d;\n", i);
 674			text[count++] = strdup(decl.c_str());
 675		}
 676
 677		if (texture_index_channels > 1)
 678		{
 679			text[count++] = strdup("VARYING float vary_texture_index;\n");
 680		}
 681
 682		text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
 683		text[count++] = strdup("{\n");
 684		
 685		
 686		if (texture_index_channels == 1)
 687		{ //don't use flow control, that's silly
 688			text[count++] = strdup("return texture2D(tex0, texcoord);\n");
 689			text[count++] = strdup("}\n");
 690		}
 691		else if (gGLManager.mGLVersion >= 3.f)
 692		{ 
 693			text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");
 694			text[count++] = strdup("\t{\n");
 695		
 696			//switch body
 697			for (S32 i = 0; i < texture_index_channels; ++i)
 698			{
 699				std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
 700				text[count++] = strdup(case_str.c_str());
 701			}
 702
 703			text[count++] = strdup("\t}\n");
 704			text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
 705			text[count++] = strdup("}\n");
 706		}
 707		else
 708		{
 709			//switches aren't supported, make block that looks like:
 710			/*
 711				int ti = int(vary_texture_index+0.25);
 712				if (ti == 0) return texture2D(tex0, texcoord);
 713				if (ti == 1) return texture2D(tex1, texcoord);
 714				.
 715				.
 716				.
 717				if (ti == N) return texture2D(texN, texcoord);
 718			*/
 719				
 720			text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n");
 721			for (S32 i = 0; i < texture_index_channels; ++i)
 722			{
 723				std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);
 724				text[count++] = strdup(if_str.c_str());
 725			}
 726
 727			text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
 728			text[count++] = strdup("}\n");
 729		}			
 730	}
 731
 732	//copy file into memory
 733	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) ) 
 734	{
 735		text[count++] = (GLcharARB *)strdup((char *)buff); 
 736	}
 737	fclose(file);
 738
 739	//create shader object
 740	GLhandleARB ret = glCreateShaderObjectARB(type);
 741	if (gDebugGL)
 742	{
 743		error = glGetError();
 744		if (error != GL_NO_ERROR)
 745		{
 746			LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
 747		}
 748	}
 749	
 750	//load source
 751	glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
 752
 753	if (gDebugGL)
 754	{
 755		error = glGetError();
 756		if (error != GL_NO_ERROR)
 757		{
 758			LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL;
 759		}
 760	}
 761
 762	//compile source
 763	glCompileShaderARB(ret);
 764
 765	if (gDebugGL)
 766	{
 767		error = glGetError();
 768		if (error != GL_NO_ERROR)
 769		{
 770			LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
 771		}
 772	}
 773		
 774	if (error == GL_NO_ERROR)
 775	{
 776		//check for errors
 777		GLint success = GL_TRUE;
 778		glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
 779		if (gDebugGL || success == GL_FALSE)
 780		{
 781			error = glGetError();
 782			if (error != GL_NO_ERROR || success == GL_FALSE) 
 783			{
 784				//an error occured, print log
 785				LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
 786				dumpObjectLog(ret);
 787
 788#if LL_WINDOWS
 789				std::stringstream ostr;
 790				//dump shader source for debugging
 791				for (GLuint i = 0; i < count; i++)
 792				{
 793					ostr << i << ": " << text[i];
 794
 795					if (i % 128 == 0)
 796					{ //dump every 128 lines
 797
 798						LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
 799						ostr = std::stringstream();
 800					}
 801
 802				}
 803
 804				LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
 805#endif // LL_WINDOWS
 806
 807				ret = 0;
 808			}
 809		}
 810	}
 811	else
 812	{
 813		ret = 0;
 814	}
 815	stop_glerror();
 816
 817	//free memory
 818	for (GLuint i = 0; i < count; i++)
 819	{
 820		free(text[i]);
 821	}
 822
 823	//successfully loaded, save results
 824	if (ret)
 825	{
 826		// Add shader file to map
 827		mShaderObjects[filename] = ret;
 828		shader_level = try_gpu_class;
 829	}
 830	else
 831	{
 832		if (shader_level > 1)
 833		{
 834			shader_level--;
 835			return loadShaderFile(filename,shader_level,type,texture_index_channels);
 836		}
 837		LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;	
 838	}
 839	return ret;
 840}
 841
 842BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors) 
 843{
 844	//check for errors
 845	glLinkProgramARB(obj);
 846	GLint success = GL_TRUE;
 847	glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success);
 848	if (!suppress_errors && success == GL_FALSE) 
 849	{
 850		//an error occured, print log
 851		LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
 852	}
 853
 854#if LL_DARWIN
 855
 856	// For some reason this absolutely kills the frame rate when VBO's are enabled
 857	if (0)
 858	{
 859		// Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
 860		// per Apple's suggestion
 861		LLGLSLShader::sNoFixedFunction = false;
 862		
 863		glUseProgramObjectARB(obj);
 864
 865		gGL.begin(LLRender::TRIANGLES);
 866		gGL.vertex3f(0.0f, 0.0f, 0.0f);
 867		gGL.vertex3f(0.0f, 0.0f, 0.0f);
 868		gGL.vertex3f(0.0f, 0.0f, 0.0f);
 869		gGL.end();
 870		gGL.flush();
 871		
 872		glUseProgramObjectARB(0);
 873		
 874		LLGLSLShader::sNoFixedFunction = true;
 875
 876		// Query whether the shader can or cannot run in hardware
 877		// http://developer.apple.com/qa/qa2007/qa1502.html
 878		GLint vertexGPUProcessing, fragmentGPUProcessing;
 879		CGLContextObj ctx = CGLGetCurrentContext();
 880		CGLGetParameter(ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing);	
 881		CGLGetParameter(ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
 882		if (!fragmentGPUProcessing || !vertexGPUProcessing)
 883		{
 884			LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
 885			success = GL_FALSE;
 886			suppress_errors = FALSE;		
 887		}
 888	}
 889
 890#else
 891	std::string log = get_object_log(obj);
 892	LLStringUtil::toLower(log);
 893	if (log.find("software") != std::string::npos)
 894	{
 895		LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
 896		success = GL_FALSE;
 897		suppress_errors = FALSE;
 898	}
 899#endif
 900	if (!suppress_errors)
 901	{
 902        dumpObjectLog(obj, !success);
 903	}
 904
 905	return success;
 906}
 907
 908BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
 909{
 910	//check program validity against current GL
 911	glValidateProgramARB(obj);
 912	GLint success = GL_TRUE;
 913	glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
 914	if (success == GL_FALSE)
 915	{
 916		LL_WARNS("ShaderLoading") << "GLSL program not valid: " << LL_ENDL;
 917		dumpObjectLog(obj);
 918	}
 919	else
 920	{
 921		dumpObjectLog(obj, FALSE);
 922	}
 923
 924	return success;
 925}
 926
 927//virtual
 928void LLShaderMgr::initAttribsAndUniforms()
 929{
 930	//MUST match order of enum in LLVertexBuffer.h
 931	mReservedAttribs.push_back("position");
 932	mReservedAttribs.push_back("normal");
 933	mReservedAttribs.push_back("texcoord0");
 934	mReservedAttribs.push_back("texcoord1");
 935	mReservedAttribs.push_back("texcoord2");
 936	mReservedAttribs.push_back("texcoord3");
 937	mReservedAttribs.push_back("diffuse_color");
 938	mReservedAttribs.push_back("emissive");
 939	mReservedAttribs.push_back("binormal");
 940	mReservedAttribs.push_back("weight");
 941	mReservedAttribs.push_back("weight4");
 942	mReservedAttribs.push_back("clothing");
 943	mReservedAttribs.push_back("texture_index");
 944	
 945	//matrix state
 946	mReservedUniforms.push_back("modelview_matrix");
 947	mReservedUniforms.push_back("projection_matrix");
 948	mReservedUniforms.push_back("inv_proj");
 949	mReservedUniforms.push_back("modelview_projection_matrix");
 950	mReservedUniforms.push_back("normal_matrix");
 951	mReservedUniforms.push_back("texture_matrix0");
 952	mReservedUniforms.push_back("texture_matrix1");
 953	mReservedUniforms.push_back("texture_matrix2");
 954	mReservedUniforms.push_back("texture_matrix3");
 955	llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1);
 956
 957	mReservedUniforms.push_back("viewport");
 958
 959	mReservedUniforms.push_back("light_position");
 960	mReservedUniforms.push_back("light_direction");
 961	mReservedUniforms.push_back("light_attenuation");
 962	mReservedUniforms.push_back("light_diffuse");
 963	mReservedUniforms.push_back("light_ambient");
 964	mReservedUniforms.push_back("light_count");
 965	mReservedUniforms.push_back("light");
 966	mReservedUniforms.push_back("light_col");
 967	mReservedUniforms.push_back("far_z");
 968
 969	llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
 970
 971
 972	mReservedUniforms.push_back("proj_mat");
 973	mReservedUniforms.push_back("proj_near");
 974	mReservedUniforms.push_back("proj_p");
 975	mReservedUniforms.push_back("proj_n");
 976	mReservedUniforms.push_back("proj_origin");
 977	mReservedUniforms.push_back("proj_range");
 978	mReservedUniforms.push_back("proj_ambiance");
 979	mReservedUniforms.push_back("proj_shadow_idx");
 980	mReservedUniforms.push_back("shadow_fade");
 981	mReservedUniforms.push_back("proj_focus");
 982	mReservedUniforms.push_back("proj_lod");
 983	mReservedUniforms.push_back("proj_ambient_lod");
 984
 985	llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
 986
 987	mReservedUniforms.push_back("color");
 988		
 989	mReservedUniforms.push_back("diffuseMap");
 990	mReservedUniforms.push_back("specularMap");
 991	mReservedUniforms.push_back("bumpMap");
 992	mReservedUniforms.push_back("environmentMap");
 993	mReservedUniforms.push_back("cloude_noise_texture");
 994	mReservedUniforms.push_back("fullbright");
 995	mReservedUniforms.push_back("lightnorm");
 996	mReservedUniforms.push_back("sunlight_color_copy");
 997	mReservedUniforms.push_back("ambient");
 998	mReservedUniforms.push_back("blue_horizon");
 999	mReservedUniforms.push_back("blue_density");
1000	mReservedUniforms.push_back("haze_horizon");
1001	mReservedUniforms.push_back("haze_density");
1002	mReservedUniforms.push_back("cloud_shadow");
1003	mReservedUniforms.push_back("density_multiplier");
1004	mReservedUniforms.push_back("distance_multiplier");
1005	mReservedUniforms.push_back("max_y");
1006	mReservedUniforms.push_back("glow");
1007	mReservedUniforms.push_back("cloud_color");
1008	mReservedUniforms.push_back("cloud_pos_density1");
1009	mReservedUniforms.push_back("cloud_pos_density2");
1010	mReservedUniforms.push_back("cloud_scale");
1011	mReservedUniforms.push_back("gamma");
1012	mReservedUniforms.push_back("scene_light_strength");
1013
1014	llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1);
1015
1016	mReservedUniforms.push_back("center");
1017	mReservedUniforms.push_back("size");
1018	mReservedUniforms.push_back("falloff");
1019
1020
1021	mReservedUniforms.push_back("minLuminance");
1022	mReservedUniforms.push_back("maxExtractAlpha");
1023	mReservedUniforms.push_back("lumWeights");
1024	mReservedUniforms.push_back("warmthWeights");
1025	mReservedUniforms.push_back("warmthAmount");
1026	mReservedUniforms.push_back("glowStrength");
1027	mReservedUniforms.push_back("glowDelta");
1028
1029	llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_DELTA+1);
1030
1031
1032	mReservedUniforms.push_back("minimum_alpha");
1033
1034	mReservedUniforms.push_back("shadow_matrix");
1035	mReservedUniforms.push_back("env_mat");
1036	mReservedUniforms.push_back("shadow_clip");
1037	mReservedUniforms.push_back("sun_wash");
1038	mReservedUniforms.push_back("shadow_noise");
1039	mReservedUniforms.push_back("blur_size");
1040	mReservedUniforms.push_back("ssao_radius");
1041	mReservedUniforms.push_back("ssao_max_radius");
1042	mReservedUniforms.push_back("ssao_factor");
1043	mReservedUniforms.push_back("ssao_factor_inv");
1044	mReservedUniforms.push_back("ssao_effect_mat");
1045	mReservedUniforms.push_back("screen_res");
1046	mReservedUniforms.push_back("near_clip");
1047	mReservedUniforms.push_back("shadow_offset");
1048	mReservedUniforms.push_back("shadow_bias");
1049	mReservedUniforms.push_back("spot_shadow_bias");
1050	mReservedUniforms.push_back("spot_shadow_offset");
1051	mReservedUniforms.push_back("sun_dir");
1052	mReservedUniforms.push_back("shadow_res");
1053	mReservedUniforms.push_back("proj_shadow_res");
1054	mReservedUniforms.push_back("depth_cutoff");
1055	mReservedUniforms.push_back("norm_cutoff");
1056	
1057	llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_NORM_CUTOFF+1);
1058
1059	mReservedUniforms.push_back("tc_scale");
1060	mReservedUniforms.push_back("rcp_screen_res");
1061	mReservedUniforms.push_back("rcp_frame_opt");
1062	mReservedUniforms.push_back("rcp_frame_opt2");
1063	
1064	mReservedUniforms.push_back("focal_distance");
1065	mReservedUniforms.push_back("blur_constant");
1066	mReservedUniforms.push_back("tan_pixel_angle");
1067	mReservedUniforms.push_back("magnification");
1068	mReservedUniforms.push_back("max_cof");
1069	mReservedUniforms.push_back("res_scale");
1070
1071	mReservedUniforms.push_back("depthMap");
1072	mReservedUniforms.push_back("shadowMap0");
1073	mReservedUniforms.push_back("shadowMap1");
1074	mReservedUniforms.push_back("shadowMap2");
1075	mReservedUniforms.push_back("shadowMap3");
1076	mReservedUniforms.push_back("shadowMap4");
1077	mReservedUniforms.push_back("shadowMap5");
1078
1079	llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1);
1080
1081	mReservedUniforms.push_back("normalMap");
1082	mReservedUniforms.push_back("positionMap");
1083	mReservedUniforms.push_back("diffuseRect");
1084	mReservedUniforms.push_back("specularRect");
1085	mReservedUniforms.push_back("noiseMap");
1086	mReservedUniforms.push_back("lightFunc");
1087	mReservedUniforms.push_back("lightMap");
1088	mReservedUniforms.push_back("bloomMap");
1089	mReservedUniforms.push_back("projectionMap");
1090
1091	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
1092
1093	std::set<std::string> dupe_check;
1094
1095	for (U32 i = 0; i < mReservedUniforms.size(); ++i)
1096	{
1097		if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end())
1098		{
1099			llerrs << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << llendl;
1100		}
1101		dupe_check.insert(mReservedUniforms[i]);
1102	}
1103}
1104