diff options
| author | Dave Parks <davep@lindenlab.com> | 2012-02-10 20:04:19 -0600 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2012-02-10 20:04:19 -0600 | 
| commit | 3710c6110d65d3a604f7b419cd764cf5b9b98600 (patch) | |
| tree | 544b689c3c084976b05a69a34726524e6e68f214 /indra/llrender | |
| parent | e0582d4bc71e2f367b4cf4a6f0b808451620b52f (diff) | |
SH-2908 Rework indexed texture rendering to use a uvec4 instead of a float for texture indices in the data stream.  Also rework gl_FragColor overrides to not collide with some odd driver implementations.
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llgl.cpp | 62 | ||||
| -rw-r--r-- | indra/llrender/llgl.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llglheaders.h | 3 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.cpp | 5 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 92 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 46 | 
6 files changed, 153 insertions, 57 deletions
| diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 946e602fee..79d4415117 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -97,6 +97,8 @@ void APIENTRY gl_debug_callback(GLenum source,  }  #endif +void parse_glsl_version(S32& major, S32& minor); +  void ll_init_fail_log(std::string filename)  {  	gFailLog.open(filename.c_str()); @@ -295,6 +297,7 @@ PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;  PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;  PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;  PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;  #if LL_WINDOWS  PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL; @@ -341,6 +344,7 @@ PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB = NULL;  PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB = NULL;  PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB = NULL;  PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;  PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;  PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;  PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL; @@ -443,7 +447,8 @@ LLGLManager::LLGLManager() :  	mDriverVersionMinor(0),  	mDriverVersionRelease(0),  	mGLVersion(1.0f), -		 +	mGLSLVersionMajor(0), +	mGLSLVersionMinor(0),		  	mVRAM(0),  	mGLMaxVertexRange(0),  	mGLMaxIndexRange(0) @@ -554,6 +559,11 @@ bool LLGLManager::initGL()  	mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f; +	if (mGLVersion >= 2.f) +	{ +		parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor); +	} +  	// Trailing space necessary to keep "nVidia Corpor_ati_on" cards  	// from being recognized as ATI.  	if (mGLVendor.substr(0,4) == "ATI ") @@ -1300,6 +1310,7 @@ void LLGLManager::initExtensions()  		glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");  		glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");  		glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB"); +		glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");  		glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");  		glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");  		glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB"); @@ -2098,6 +2109,55 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor  	}  } + +void parse_glsl_version(S32& major, S32& minor) +{ +	// GL_SHADING_LANGUAGE_VERSION returns a null-terminated string with the format:  +	// <major>.<minor>[.<release>] [<vendor specific>] + +	const char* version = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); +	major = 0; +	minor = 0; +	 +	if( !version ) +	{ +		return; +	} + +	std::string ver_copy( version ); +	S32 len = (S32)strlen( version );	/* Flawfinder: ignore */ +	S32 i = 0; +	S32 start; +	// Find the major version +	start = i; +	for( ; i < len; i++ ) +	{ +		if( '.' == version[i] ) +		{ +			break; +		} +	} +	std::string major_str = ver_copy.substr(start,i-start); +	LLStringUtil::convertToS32(major_str, major); + +	if( '.' == version[i] ) +	{ +		i++; +	} + +	// Find the minor version +	start = i; +	for( ; i < len; i++ ) +	{ +		if( ('.' == version[i]) || isspace(version[i]) ) +		{ +			break; +		} +	} +	std::string minor_str = ver_copy.substr(start,i-start); +	LLStringUtil::convertToS32(minor_str, minor); +} +  LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)  {  	mApply = apply; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 6a147b8e19..5a33c98708 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -138,6 +138,8 @@ public:  	S32 mDriverVersionMinor;  	S32 mDriverVersionRelease;  	F32 mGLVersion; // e.g = 1.4 +	S32 mGLSLVersionMajor; +	S32 mGLSLVersionMinor;  	std::string mDriverVersionVendorString;  	S32 mVRAM; // VRAM in MB diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 10aad202e1..d61ec707f0 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -199,6 +199,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;  extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;  extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;  extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB; +extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;  extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;  extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;  extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB; @@ -460,6 +461,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;  extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;  extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;  extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB; +extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;  extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;  extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;  extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB; @@ -693,6 +695,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;  extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;  extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;  extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB; +extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;  extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;  extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;  extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 7eba62e59e..a879a18895 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -164,8 +164,9 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  		return FALSE;  	} -	if (gGLManager.mGLVersion < 3.1f) -	{ //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again +	if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3) +	{ //indexed texture rendering requires GLSL 1.3 or later +		//attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again  		mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);  	} diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index d03d349f0f..321b139181 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -575,31 +575,39 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	GLcharARB* text[4096];  	GLuint count = 0; -	F32 version = gGLManager.mGLVersion; - -//hack to never use GLSL > 1.20 on OSX -#if LL_DARWIN -	version = llmin(version, 2.9f); -#endif - -	if (version < 2.1f) -	{ -		text[count++] = strdup("#version 110\n"); -		text[count++] = strdup("#define ATTRIBUTE attribute\n"); -		text[count++] = strdup("#define VARYING varying\n"); -	} -	else if (version < 3.3f) +	S32 major_version = gGLManager.mGLSLVersionMajor; +	S32 minor_version = gGLManager.mGLSLVersionMinor; +	 +	if (major_version == 1 && minor_version < 30)  	{ -		//set version to 1.20 -		text[count++] = strdup("#version 120\n"); -		text[count++] = strdup("#define FXAA_GLSL_120 1\n"); -		text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n"); -		text[count++] = strdup("#define ATTRIBUTE attribute\n"); -		text[count++] = strdup("#define VARYING varying\n"); +		if (minor_version < 10) +		{ +			//should NEVER get here -- if major version is 1 and minor version is less than 10,  +			// viewer should never attempt to use shaders, continuing will result in undefined behavior +			llerrs << "Unsupported GLSL Version." << llendl; +		} + +		if (minor_version <= 19) +		{ +			text[count++] = strdup("#version 110\n"); +			text[count++] = strdup("#define ATTRIBUTE attribute\n"); +			text[count++] = strdup("#define VARYING varying\n"); +			text[count++] = strdup("#define VARYING_FLAT varying\n"); +		} +		else if (minor_version <= 29) +		{ +			//set version to 1.20 +			text[count++] = strdup("#version 120\n"); +			text[count++] = strdup("#define FXAA_GLSL_120 1\n"); +			text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n"); +			text[count++] = strdup("#define ATTRIBUTE attribute\n"); +			text[count++] = strdup("#define VARYING varying\n"); +			text[count++] = strdup("#define VARYING_FLAT varying\n"); +		}  	}  	else  	{   -		if (version < 4.f) +		if (major_version < 4)  		{  			//set version to 1.30  			text[count++] = strdup("#version 130\n"); @@ -618,13 +626,17 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		{ //"varying" state is "out" in a vertex program, "in" in a fragment program   			// ("varying" is deprecated after version 1.20)  			text[count++] = strdup("#define VARYING out\n"); +			text[count++] = strdup("#define VARYING_FLAT flat out\n");  		}  		else  		{  			text[count++] = strdup("#define VARYING in\n"); +			text[count++] = strdup("#define VARYING_FLAT flat in\n");  		}  		//backwards compatibility with legacy texture lookup syntax +		text[count++] = strdup("#define texture2D texture\n"); +		text[count++] = strdup("#define texture2DRect texture\n");  		text[count++] = strdup("#define textureCube texture\n");  		text[count++] = strdup("#define texture2DLod textureLod\n");  		text[count++] = strdup("#define	shadow2D(a,b) vec2(texture(a,b))\n"); @@ -651,11 +663,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		.  		uniform sampler2D texN; -		VARYING float vary_texture_index; +		VARYING uvec4 vary_texture_index;  		vec4 diffuseLookup(vec2 texcoord)  		{ -			switch (int(vary_texture_index+0.25)) +			switch (vary_texture_index.r))  			{  				case 0: return texture2D(tex0, texcoord);  				case 1: return texture2D(tex1, texcoord); @@ -679,7 +691,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		if (texture_index_channels > 1)  		{ -			text[count++] = strdup("VARYING float vary_texture_index;\n"); +			text[count++] = strdup("VARYING_FLAT uvec4 vary_texture_index;\n");  		}  		text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n"); @@ -691,9 +703,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  			text[count++] = strdup("return texture2D(tex0, texcoord);\n");  			text[count++] = strdup("}\n");  		} -		else if (gGLManager.mGLVersion >= 3.f) -		{  -			text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n"); +		else if (major_version > 1 || minor_version >= 30) +		{  //switches are supported in GLSL 1.30 and later +			text[count++] = strdup("\tswitch (vary_texture_index.r)\n");  			text[count++] = strdup("\t{\n");  			//switch body @@ -708,28 +720,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  			text[count++] = strdup("}\n");  		}  		else -		{ -			//switches aren't supported, make block that looks like: -			/* -				int ti = int(vary_texture_index+0.25); -				if (ti == 0) return texture2D(tex0, texcoord); -				if (ti == 1) return texture2D(tex1, texcoord); -				. -				. -				. -				if (ti == N) return texture2D(texN, texcoord); -			*/ -				 -			text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n"); -			for (S32 i = 0; i < texture_index_channels; ++i) -			{ -				std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i); -				text[count++] = strdup(if_str.c_str()); -			} - -			text[count++] = strdup("\treturn vec4(1,0,1,1);\n"); -			text[count++] = strdup("}\n"); -		}			 +		{ //should never get here.  Indexed texture rendering requires GLSL 1.30 or later  +			// (for passing integers between vertex and fragment shaders) +			llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl; +		}  	}  	//copy file into memory diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index e4a5cd0299..b2438ef824 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -284,6 +284,12 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  	{  		bool error = false; +		if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30) +		{ +			//make sure texture index is disabled +			data_mask = data_mask & ~MAP_TEXTURE_INDEX; +		} +  		if (LLGLSLShader::sNoFixedFunction)  		{  			for (U32 i = 0; i < TYPE_MAX; ++i) @@ -1193,7 +1199,7 @@ void LLVertexBuffer::setupVertexArray()  		1, //TYPE_WEIGHT,  		4, //TYPE_WEIGHT4,  		4, //TYPE_CLOTHWEIGHT, -		1, //TYPE_TEXTURE_INDEX +		4, //TYPE_TEXTURE_INDEX  	};  	U32 attrib_type[] = @@ -1210,7 +1216,24 @@ void LLVertexBuffer::setupVertexArray()  		GL_FLOAT, //TYPE_WEIGHT,  		GL_FLOAT, //TYPE_WEIGHT4,  		GL_FLOAT, //TYPE_CLOTHWEIGHT, -		GL_FLOAT, //TYPE_TEXTURE_INDEX +		GL_UNSIGNED_BYTE, //TYPE_TEXTURE_INDEX +	}; + +	bool attrib_integer[] =  +	{ +		false, //TYPE_VERTEX, +		false, //TYPE_NORMAL, +		false, //TYPE_TEXCOORD0, +		false, //TYPE_TEXCOORD1, +		false, //TYPE_TEXCOORD2, +		false, //TYPE_TEXCOORD3, +		false, //TYPE_COLOR, +		false, //TYPE_EMISSIVE, +		false, //TYPE_BINORMAL, +		false, //TYPE_WEIGHT, +		false, //TYPE_WEIGHT4, +		false, //TYPE_CLOTHWEIGHT, +		true, //TYPE_TEXTURE_INDEX  	};  	U32 attrib_normalized[] = @@ -1238,7 +1261,19 @@ void LLVertexBuffer::setupVertexArray()  		if (mTypeMask & (1 << i))  		{  			glEnableVertexAttribArrayARB(i); -			glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);  + +			if (attrib_integer) +			{ +				//glVertexattribIPointer requires GLSL 1.30 or later +				if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) +				{ +					glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (void*) mOffsets[i]);  +				} +			} +			else +			{ +				glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);  +			}  		}  		else  		{ @@ -2220,11 +2255,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  			void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);  			glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);  		} -		if (data_mask & MAP_TEXTURE_INDEX) +		if (data_mask & MAP_TEXTURE_INDEX &&  +				(gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later  		{  			S32 loc = TYPE_TEXTURE_INDEX;  			void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); -			glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); +			glVertexAttribIPointer(loc, 4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);  		}  		if (data_mask & MAP_VERTEX)  		{ | 
