diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 68892453b79ce05c04625d906f1c479752756256..77b34eb5462cab9f0a76e3c423f3a3e153293368 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -673,6 +673,14 @@ std::string LLGLManager::getRawGLString()
 	return gl_string;
 }
 
+U32 LLGLManager::getNumFBOFSAASamples(U32 samples)
+{
+	samples = llmin(samples, (U32) mMaxColorTextureSamples);
+	samples = llmin(samples, (U32) mMaxDepthTextureSamples);
+	samples = llmin(samples, (U32) 4);
+	return samples;
+}
+
 void LLGLManager::shutdownGL()
 {
 	if (mInited)
@@ -979,7 +987,7 @@ void LLGLManager::initExtensions()
 	{
 		glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
 	}
-	if (mHasTextureRectangle)
+	if (mHasTextureMultisample)
 	{
 		glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample");
 		glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 3719b25557d0ee33f69217ee0479f6dac7404166..420922cf0670e1eb26933aa1cfa0263d8d6ae0d3 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -145,6 +145,7 @@ class LLGLManager
 	void printGLInfoString();
 	void getGLInfo(LLSD& info);
 
+	U32 getNumFBOFSAASamples(U32 desired_samples = 32);
 	// In ALL CAPS
 	std::string mGLVendor;
 	std::string mGLVendorShort;
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index ddd6072fff3c89b3853bde848df461ea32b3daf0..715f46631480cda357949690ca538dc5f8b4e625 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -83,11 +83,10 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
 	mUseDepth = depth;
 	mSamples = samples;
 
-	mSamples = llmin(mSamples, (U32) gGLManager.mMaxColorTextureSamples);
-
-	if (mSamples > 0 && gGLManager.mHasTextureMultisample)
+	mSamples = gGLManager.getNumFBOFSAASamples(mSamples);
+	
+	if (mSamples > 1 && gGLManager.mHasTextureMultisample)
 	{
-		mSamples = llmin(mSamples, (U32) gGLManager.mMaxColorTextureSamples);
 		mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE;
 		//no support for multisampled stencil targets yet
 		mStencil = false;
@@ -155,7 +154,7 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
 	stop_glerror();
 
 
-	if (mSamples > 0)
+	if (mSamples > 1)
 	{
 		glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);
 	}
@@ -207,6 +206,12 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
 
 	mTex.push_back(tex);
 
+	if (gDebugGL)
+	{ //bind and unbind to validate target
+		bindTarget();
+		flush();
+	}
+
 }
 
 void LLRenderTarget::allocateDepth()
@@ -272,6 +277,9 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
 			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
 			stop_glerror();
 		}
+
+		check_framebuffer_status();
+
 		glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
 		target.mUseDepth = true;
@@ -456,6 +464,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
 		stop_glerror();
 		
 		glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO);
+		check_framebuffer_status();
 		gGL.getTexUnit(0)->bind(this, true);
 		stop_glerror();
 		glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
@@ -473,6 +482,10 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
 		stop_glerror();
 		glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
 		stop_glerror();
+		glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+		stop_glerror();
+		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+		stop_glerror();
 		glBindFramebuffer(GL_FRAMEBUFFER, 0);
 		stop_glerror();
 	}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl
index 4366376d99d31e344570604ca6b1dfd656ab37ea..edec83ea072ce2ed17d958f3cf9251c2b853c735 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightMSF.glsl
@@ -12,7 +12,7 @@
 
 uniform sampler2DMS depthMap;
 uniform sampler2DMS normalMap;
-uniform sampler2DMS lightMap;
+uniform sampler2DRect lightMap;
 
 uniform float dist_factor;
 uniform float blur_size;
@@ -25,12 +25,23 @@ varying vec2 vary_fragcoord;
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
 
-vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
+vec3 texture2DMS3(sampler2DMS tex, ivec2 tc)
 {
-	vec4 ret = vec4(0,0,0,0);
+	vec3 ret = vec3(0,0,0);
 	for (int i = 0; i < samples; i++)
 	{
-		ret += texelFetch(tex, tc, i);
+		ret += texelFetch(tex, tc, i).rgb;
+	}
+
+	return ret/samples;
+}
+
+float texture2DMS1(sampler2DMS tex, ivec2 tc)
+{
+	float ret = 0;
+	for (int i = 0; i < samples; i++)
+	{
+		ret += texelFetch(tex, tc, i).r;
 	}
 
 	return ret/samples;
@@ -38,7 +49,7 @@ vec4 texture2DMS(sampler2DMS tex, ivec2 tc)
 
 vec4 getPosition(ivec2 pos_screen)
 {
-	float depth = texture2DMS(depthMap, pos_screen.xy).r;
+	float depth = texture2DMS1(depthMap, pos_screen.xy);
 	vec2 sc = pos_screen.xy*2.0;
 	sc /= screen_res;
 	sc -= vec2(1.0,1.0);
@@ -54,10 +65,10 @@ void main()
     vec2 tc = vary_fragcoord.xy;
 	ivec2 itc = ivec2(tc);
 
-	vec3 norm = texture2DMS(normalMap, itc).xyz;
+	vec3 norm = texture2DMS3(normalMap, itc).xyz;
 	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
 	vec3 pos = getPosition(itc).xyz;
-	vec4 ccol = texture2DMS(lightMap, itc).rgba;
+	vec4 ccol = texture2DRect(lightMap, tc).rgba;
 	
 	vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
 	dlt /= max(-pos.z*dist_factor, 1.0);
@@ -73,23 +84,23 @@ void main()
 
 	for (int i = 1; i < 4; i++)
 	{
-		ivec2 samptc = ivec2(tc + kern[i].z*dlt);
-		vec3 samppos = getPosition(samptc).xyz; 
+		vec2 samptc = tc + kern[i].z*dlt;
+		vec3 samppos = getPosition(ivec2(samptc)).xyz; 
 		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
 		if (d*d <= pointplanedist_tolerance_pow2)
 		{
-			col += texture2DMS(lightMap, samptc)*kern[i].xyxx;
+			col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
 			defined_weight += kern[i].xy;
 		}
 	}
 	for (int i = 1; i < 4; i++)
 	{
-		ivec2 samptc = ivec2(tc - kern[i].z*dlt);
-		vec3 samppos = getPosition(samptc).xyz; 
+		vec2 samptc = vec2(tc - kern[i].z*dlt);
+		vec3 samppos = getPosition(ivec2(samptc)).xyz; 
 		float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
 		if (d*d <= pointplanedist_tolerance_pow2)
 		{
-			col += texture2DMS(lightMap, samptc)*kern[i].xyxx;
+			col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
 			defined_weight += kern[i].xy;
 		}
 	}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl
index 16e97109f9225c1dcc2b7bc8de0a506628c4cf4f..66c7a5cb4ac7b93fb3302439866438de89d52565 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightMSF.glsl
@@ -130,7 +130,7 @@ void main()
 		discard;
 	}
 
-	gl_FragColor.rgb = fcol/wght;
+	gl_FragColor.rgb = fcol/samples;
 	gl_FragColor.a = 0.0;
 
 	
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl
index bdaa8e59c4d170af3cead9646c83e0042e728ddf..b450ff1ca2a1b4cec0c4e0cb706a1d38f69a79ab 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightMSF.glsl
@@ -34,7 +34,6 @@ uniform float far_clip;
 
 uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
 uniform float sun_wash;
-uniform int proj_shadow_idx;
 uniform float shadow_fade;
 
 varying vec4 vary_light;
@@ -228,6 +227,6 @@ void main()
 		discard;
 	}
 
-	gl_FragColor.rgb = fcol/wght;	
+	gl_FragColor.rgb = fcol/samples;	
 	gl_FragColor.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl
index 23b5e7673547e5003114e581cb5cb3703180fa24..7521c3310c3e635aef8e96081ca9cdee85170204 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightMSF.glsl
@@ -103,6 +103,6 @@ void main()
 		discard;
 	}
 		
-	gl_FragColor.rgb = fcol/wght;	
+	gl_FragColor.rgb = fcol/samples;	
 	gl_FragColor.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl
index 3a9d9266bb7f92985681b0a62dcf1f477c04378c..6702bd5014290a2e977b0e20d0302fd1f2c2f546 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightMSF.glsl
@@ -229,6 +229,6 @@ void main()
 		discard;
 	}
 
-	gl_FragColor.rgb = fcol/wght;	
+	gl_FragColor.rgb = fcol/samples;	
 	gl_FragColor.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl
index c6f0ea2a5d8318a68437b4bcb0130f6888cbeef4..d0f910177472993ac8b0ce51ba2d9aa81ae51f22 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightMSF.glsl
@@ -14,7 +14,7 @@ uniform sampler2DMS diffuseRect;
 uniform sampler2DMS specularRect;
 uniform sampler2DMS depthMap;
 uniform sampler2DMS normalMap;
-uniform sampler2DMS lightMap;
+uniform sampler2DRect lightMap;
 uniform sampler2D noiseMap;
 uniform sampler2D lightFunc;
 uniform sampler2D projectionMap;
@@ -112,6 +112,17 @@ void main()
 	
 	ivec2 itc = ivec2(frag.xy);
 
+	float shadow = 1.0;
+
+	if (proj_shadow_idx >= 0)
+	{
+		vec4 shd = texture2DRect(lightMap, frag);
+		float sh[2];
+		sh[0] = shd.b;
+		sh[1] = shd.a;
+		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
+	}
+		
 	for (int i = 0; i < samples; i++)
 	{
 		vec3 pos = getPosition(itc, i).xyz;
@@ -120,17 +131,6 @@ void main()
 		dist2 /= vary_light.w;
 		if (dist2 <= 1.0)
 		{
-			float shadow = 1.0;
-	
-			if (proj_shadow_idx >= 0)
-			{
-				vec4 shd = texelFetch(lightMap, itc, i);
-				float sh[2];
-				sh[0] = shd.b;
-				sh[1] = shd.a;
-				shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
-			}
-	
 			vec3 norm = texelFetch(normalMap, itc, i).xyz;
 			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
 	
@@ -239,6 +239,6 @@ void main()
 		discard;
 	}
 
-	gl_FragColor.rgb = fcol/wght;	
+	gl_FragColor.rgb = fcol/samples;	
 	gl_FragColor.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
index 71482d0c7bd9d60a951cde4107fb26afa26dd28f..cb09fe9895139f68a2c9204e7ede821a6aa5708f 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
@@ -13,7 +13,7 @@
 uniform sampler2DMS diffuseRect;
 uniform sampler2DMS specularRect;
 uniform sampler2DMS normalMap;
-uniform sampler2DMS lightMap;
+uniform sampler2DRect lightMap;
 uniform sampler2DMS depthMap;
 uniform sampler2D	  noiseMap;
 uniform samplerCube environmentMap;
@@ -257,7 +257,8 @@ void main()
 
 	vec3 fcol = vec3(0,0,0);
 
-	float amb = 0;
+	vec2 scol_ambocc = texture2DRect(lightMap, tc).rg;
+	float ambocc = scol_ambocc.g;
 
 	for (int i = 0; i < samples; ++i)
 	{
@@ -271,9 +272,9 @@ void main()
 		vec4 diffuse = texelFetch(diffuseRect, itc, i);
 		vec4 spec = texelFetch(specularRect, itc, i);
 	
-		vec2 scol_ambocc = texelFetch(lightMap, itc, i).rg;
+		float amb = 0;
+
 		float scol = max(scol_ambocc.r, diffuse.a); 
-		float ambocc = scol_ambocc.g;
 		amb += ambocc;
 
 		calcAtmospherics(pos.xyz, ambocc);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl
index 099a45718a1043cb6995ae261971039d1e538737..8d6ffd79c5692f1a22fd4ffbd47c1cfe94102342 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightMSF.glsl
@@ -14,7 +14,7 @@ uniform sampler2DMS diffuseRect;
 uniform sampler2DMS specularRect;
 uniform sampler2DMS depthMap;
 uniform sampler2DMS normalMap;
-uniform sampler2DMS lightMap;
+uniform sampler2DRect lightMap;
 uniform sampler2D noiseMap;
 uniform sampler2D lightFunc;
 uniform sampler2D projectionMap;
@@ -113,6 +113,17 @@ void main()
 	vec3 fcol = vec3(0,0,0);
 	int wght = 0;
 
+	float shadow = 1.0;
+	
+	if (proj_shadow_idx >= 0)
+	{
+		vec4 shd = texture2DRect(lightMap, frag.xy);
+		float sh[2];
+		sh[0] = shd.b;
+		sh[1] = shd.a;
+		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
+	}
+	
 	for (int i = 0; i < samples; i++)
 	{
 		vec3 pos = getPosition(itc, i).xyz;
@@ -121,17 +132,6 @@ void main()
 		dist2 /= vary_light.w;
 		if (dist2 <= 1.0)
 		{
-			float shadow = 1.0;
-	
-			if (proj_shadow_idx >= 0)
-			{
-				vec4 shd = texelFetch(lightMap, itc, i);
-				float sh[2];
-				sh[0] = shd.b;
-				sh[1] = shd.a;
-				shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
-			}
-	
 			vec3 norm = texelFetch(normalMap, itc, i).xyz;
 			norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
 	
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 911a8bb65ffcea6d0e3ea997fd98aa6ab11e53e1..b818da205eaade022ead9658955b21d79434b092 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -353,7 +353,7 @@ void LLViewerShaderMgr::setShaders()
 	}
 
 	//setup preprocessor definitions
-	LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gSavedSettings.getU32("RenderFSAASamples"));
+	LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")));
 
 	reentrance = true;
 
@@ -841,7 +841,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
 {
 	BOOL success = TRUE;
 
-	bool multisample = gSavedSettings.getU32("RenderFSAASamples") > 0 && gGLManager.mHasTextureMultisample;
+	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));
+	bool multisample = samples > 1 && LLPipeline::sRenderDeferred && gGLManager.mHasTextureMultisample;
 
 	if (mVertexShaderLevel[SHADER_EFFECT] == 0)
 	{
@@ -870,7 +871,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
 	{
 		std::string fragment;
 
-		if (gSavedSettings.getU32("RenderFSAASamples") > 0 && LLRenderTarget::sUseFBO && gGLManager.mHasTextureMultisample)
+		if (multisample)
 		{
 			fragment = "effects/glowExtractMSF.glsl";
 		}
@@ -983,7 +984,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 
 	BOOL success = TRUE;
 
-	bool multisample = gSavedSettings.getU32("RenderFSAASamples") > 0 && gGLManager.mHasTextureMultisample;
+	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));
+	bool multisample = samples > 1 && gGLManager.mHasTextureMultisample;
 
 	if (success)
 	{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ffe3b4b1a4e55224c7bcca719e7c8e5f767d9fa1..1214d1b545a3f505bb7cc9d685e15b665c74ed73 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -589,7 +589,8 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 	mScreenWidth = resX;
 	mScreenHeight = resY;
 	
-	U32 samples = llmin(gSavedSettings.getU32("RenderFSAASamples"), (U32) 16);
+	//cap samples at 4 for render targets to avoid out of memory errors
+	U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"));
 
 	if (gGLManager.mIsATI)
 	{ //disable multisampling of render targets where ATI is involved
@@ -631,7 +632,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 
 		if (shadow_detail > 0 || ssao)
 		{ //only need mDeferredLight[0] for shadows OR ssao
-			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples);
+			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
 		}
 		else
 		{
@@ -640,7 +641,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 
 		if (ssao)
 		{ //only need mDeferredLight[1] for ssao
-			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false, samples);
+			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false);
 		}
 		else
 		{
@@ -742,13 +743,6 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
 	if (LLPipeline::sRenderDeferred)
 	{ //share depth buffer between deferred targets
 		mDeferredScreen.shareDepthBuffer(mScreen);
-		for (U32 i = 0; i < 3; i++)
-		{ //share stencil buffer with screen space lightmap to stencil out sky
-			if (mDeferredLight[i].getTexture(0))
-			{
-				mDeferredScreen.shareDepthBuffer(mDeferredLight[i]);
-			}
-		}
 	}
 
 	gGL.getTexUnit(0)->disable();
@@ -7751,18 +7745,27 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
 
 	LLViewerTexture* img = volume->getLightTexture();
 
+	if (img == NULL)
+	{
+		img = LLViewerFetchedTexture::sWhiteImagep;
+	}
+
 	S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
 
-	if (channel > -1 && img)
+	if (channel > -1)
 	{
-		gGL.getTexUnit(channel)->bind(img);
+		if (img)
+		{
+			gGL.getTexUnit(channel)->bind(img);
 
-		F32 lod_range = logf(img->getWidth())/logf(2.f);
+			F32 lod_range = logf(img->getWidth())/logf(2.f);
 
-		shader.uniform1f("proj_focus", focus);
-		shader.uniform1f("proj_lod", lod_range);
-		shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
+			shader.uniform1f("proj_focus", focus);
+			shader.uniform1f("proj_lod", lod_range);
+			shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
+		}
 	}
+		
 }
 
 void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
@@ -9372,6 +9375,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 			mShadow[i+4].flush();
  		}
 	}
+	else
+	{ //no spotlight shadows
+		mShadowSpotLight[0] = mShadowSpotLight[1] = NULL;
+	}
+
 
 	if (!gSavedSettings.getBOOL("CameraOffset"))
 	{