diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index cd0494dc679d05cf2fe36f240a379bff662c02f3..2b5509400e7be0700b578ca9f7b9ae321a767515 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -88,45 +88,71 @@ float getAmbientClamp();
 
 vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
 {
+    vec3 col = vec3(0);
+
 	//get light vector
 	vec3 lv = lp.xyz-v;
 
 	//get distance
-	float d = length(lv);
-	
+	float dist = length(lv);
 	float da = 1.0;
 
-	vec3 col = vec3(0);
+    if (dist > la)
+    {
+        return col;
+    }
+
+    dist /= la;
 
-	if (d > 0.0 && la > 0.0 && fa > 0.0)
+    /* clip to projector bounds
+     vec4 proj_tc = proj_mat * lp;
+
+    if (proj_tc.z < 0
+     || proj_tc.z > 1
+     || proj_tc.x < 0
+     || proj_tc.x > 1 
+     || proj_tc.y < 0
+     || proj_tc.y > 1)
+    {
+        return col;
+    }*/
+
+    fa += 1.0;
+	if (dist > 0.0 && la > 0.0 && fa > 0.0)
 	{
 		//normalize light vector
 		lv = normalize(lv);
 	
 		//distance attenuation
-		float dist = d/la;
 		float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
 		dist_atten *= dist_atten;
-        //dist_atten *= 2.0f;
+        dist_atten *= 2.0f;
+
+        if (dist_atten <= 0.0)
+        {
+           return col;
+        }
 
 		// spotlight coefficient.
 		float spot = max(dot(-ln, lv), is_pointlight);
 		da *= spot*spot; // GL_SPOT_EXPONENT=2
 
 		//angular attenuation
-		da *= max(dot(n, lv), 0.0);		
+		da *= dot(n, lv);
 
-		float lit = max(da * dist_atten,0.0);
+		float lit = 0.0f;
 
         float amb_da = ambiance;
-        if (lit > 0)
+        if (da > 0)
         {
+		    lit = max(da * dist_atten,0.0);
             col = lit * light_col * diffuse;
             amb_da += (da*0.5+0.5) * ambiance;
         }
         amb_da += (da*da*0.5 + 0.5) * ambiance;
         amb_da *= dist_atten;
         amb_da = min(amb_da, 1.0f - lit);
+
         col.rgb += amb_da * light_col * diffuse;
 
         // no spec for alpha shader...
@@ -150,14 +176,14 @@ void main()
 #endif
 
 #ifdef USE_DIFFUSE_TEX
-    vec4 diffuse_linear = texture2D(diffuseMap,vary_texcoord0.xy);
+    vec4 diffuse_srgb = texture2D(diffuseMap,vary_texcoord0.xy);
+    vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
 #endif
 
 #ifdef USE_INDEXED_TEX
     vec4 diffuse_linear = diffuseLookup(vary_texcoord0.xy);
-#endif
-
     vec4 diffuse_srgb = vec4(linear_to_srgb(diffuse_linear.rgb), diffuse_linear.a);
+#endif
 
 #ifdef FOR_IMPOSTOR
     vec4 color;
@@ -229,12 +255,11 @@ vec3 post_ambient = color.rgb;
 
 vec3 post_sunlight = color.rgb;
 
-    color.rgb *= diffuse_linear.rgb;
+    color.rgb *= diffuse_srgb.rgb;
 
 vec3 post_diffuse = color.rgb;
 
     color.rgb = atmosFragLighting(color.rgb, additive, atten);
-    color.rgb = scaleSoftClipFrag(color.rgb);
 
 vec3 post_atmo = color.rgb;
 
@@ -243,7 +268,7 @@ vec3 post_atmo = color.rgb;
     // to linear!
     color.rgb = srgb_to_linear(color.rgb);
 
-   #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
+   #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_srgb.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
 
     LIGHT_LOOP(1)
     LIGHT_LOOP(2)
@@ -258,6 +283,8 @@ vec3 post_atmo = color.rgb;
     color.rgb += light.rgb;
 #endif
 
+    color.rgb = scaleSoftClipFrag(color.rgb);
+
     // back to sRGB as we're going directly to the final RT post-deferred gamma correction
     color.rgb = linear_to_srgb(color.rgb);
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
index e4d96a002835173ab1caf5afb7a88dd4b8546a57..bbdc8fdd1ca1caa7b6df5c31f6a4d80e0aa2f2e3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
@@ -55,35 +55,7 @@ uniform vec3 light_direction[8];
 uniform vec3 light_attenuation[8]; 
 uniform vec3 light_diffuse[8];
 
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
-	//get light vector
-	vec3 lv = lp.xyz-v;
-	
-	//get distance
-	float d = dot(lv,lv);
-	
-	float da = 0.0;
-
-	if (d > 0.0 && la > 0.0 && fa > 0.0)
-	{
-		//normalize light vector
-		lv = normalize(lv);
-	
-		//distance attenuation
-		float dist2 = d/la;
-		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
-		// spotlight coefficient.
-		float spot = max(dot(-ln, lv), is_pointlight);
-		da *= spot*spot; // GL_SPOT_EXPONENT=2
-
-		//angular attenuation
-		da *= max(dot(n, lv), 0.0);		
-	}
-
-	return da;	
-}
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
 
 void main()
 {
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index b599b6d2fcaed1a21c6e8cefd9c3b4708d76470c..c3ca9a6904a56805c6ce92fe07d48987443e8331 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -88,17 +88,19 @@ float getAmbientClamp();
 
 vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
 {
-	vec3 col = vec3(0);
+    vec3 col = vec3(0);
 
 	//get light vector
 	vec3 lv = lp.xyz-v;
-	
+
 	//get distance
-	float d = length(lv);
-	
+	float dist = length(lv);
 	float da = 1.0;
 
-    /*vec4 proj_tc = proj_mat * lp;
+    dist /= la;
+
+    /* clip to projector bounds
+     vec4 proj_tc = proj_mat * lp;
 
     if (proj_tc.z < 0
      || proj_tc.z > 1
@@ -110,35 +112,42 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
         return col;
     }*/
 
-	if (d > 0.0 && la > 0.0 && fa > 0.0)
+    fa += 1.0;
+	if (dist > 0.0 && la > 0.0 && fa > 0.0)
 	{
 		//normalize light vector
 		lv = normalize(lv);
 	
 		//distance attenuation
-		float dist = d/la;
 		float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
 		dist_atten *= dist_atten;
-        //dist_atten *= 2.0f;
+        dist_atten *= 2.0f;
+
+        if (dist_atten <= 0.0)
+        {
+           return col;
+        }
 
 		// spotlight coefficient.
 		float spot = max(dot(-ln, lv), is_pointlight);
 		da *= spot*spot; // GL_SPOT_EXPONENT=2
 
 		//angular attenuation
-		da *= max(dot(n, lv), 0.0);		
-		
-		float lit = max(da * dist_atten, 0.0);
+		da *= dot(n, lv);
+
+		float lit = 0.0f;
 
         float amb_da = ambiance;
-        if (lit > 0)
-        {            
-            col = light_col*lit*diffuse;
-            amb_da += (da*0.5 + 0.5) * ambiance;
+        if (da > 0)
+        {
+		    lit = max(da * dist_atten,0.0);
+            col = lit * light_col * diffuse;
+            amb_da += (da*0.5+0.5) * ambiance;
         }
-        amb_da += (da*da*0.5+0.5) * ambiance;
+        amb_da += (da*da*0.5 + 0.5) * ambiance;
         amb_da *= dist_atten;
         amb_da = min(amb_da, 1.0f - lit);
+
         col.rgb += amb_da * light_col * diffuse;
 
 		if (spec.a > 0.0)
@@ -217,8 +226,15 @@ void main()
 {
     vec2 pos_screen = vary_texcoord0.xy;
 
-    vec4 diffuse_linear = texture2D(diffuseMap, vary_texcoord0.xy);
-    vec4 diffuse_srgb   = vec4(linear_to_srgb(diffuse_linear.rgb), diffuse_linear.a);
+    vec4 diffuse_tap = texture2D(diffuseMap, vary_texcoord0.xy);
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+    vec4 diffuse_srgb = diffuse_tap;
+    vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_tap.a);
+#else
+    vec4 diffuse_linear = diffuse_tap;
+    vec4 diffuse_srgb = vec4(linear_to_srgb(diffuse_linear.rgb), diffuse_tap.a);
+#endif
 
 #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
     if (diffuse_linear.a < minimum_alpha)
@@ -331,7 +347,7 @@ vec3 post_ambient = color.rgb;
 
 vec3 post_sunlight = color.rgb;
 
-    color.rgb *= diffuse_linear.rgb;
+    color.rgb *= diffuse_srgb.rgb;
  
 vec3 post_diffuse = color.rgb;
 
@@ -358,7 +374,9 @@ vec3 post_diffuse = color.rgb;
             vec3 sp = sun_contrib*scol / 16.0f;
             sp = clamp(sp, vec3(0), vec3(1));
             bloom = dot(sp, sp) / 6.0;
+#if !defined(SUNLIGHT_KILL)
             color += sp * spec.rgb;
+#endif
         }
     }
 
@@ -371,8 +389,9 @@ vec3 post_spec = color.rgb;
         
         vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
 
+#if !defined(SUNLIGHT_KILL)
         color = mix(color.rgb, reflected_color, envIntensity); 
-
+#endif
         float cur_glare = max(reflected_color.r, reflected_color.g);
         cur_glare = max(cur_glare, reflected_color.b);
         cur_glare *= envIntensity*4.0;
@@ -382,13 +401,12 @@ vec3 post_spec = color.rgb;
 vec3 post_env = color.rgb;
 
     color = atmosFragLighting(color, additive, atten);
-    color = scaleSoftClipFrag(color);
-
-vec3 post_atmo = color.rgb;
 
     //convert to linear space before adding local lights
 	color = srgb_to_linear(color);
 
+vec3 post_atmo = color.rgb;
+
     vec3 npos = normalize(-pos.xyz);
             
     vec3 light = vec3(0,0,0);
@@ -410,6 +428,8 @@ vec3 post_atmo = color.rgb;
     color.rgb += light.rgb;
 #endif
 
+    color = scaleSoftClipFrag(color);
+
     // (only) post-deferred needs inline gamma correction
     color.rgb = linear_to_srgb(color.rgb);
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index c7426788c4ba2926a032646485ee43fcb3b1b252..39d14314cc4b39125234c147eaa4b7c11cd47df4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -153,7 +153,9 @@ vec3 post_diffuse = color.rgb;
                 vec3 sp = sun_contrib*scontrib / 16.0;
                 sp = clamp(sp, vec3(0), vec3(1));
                 bloom += dot(sp, sp) / 6.0;
+#if !defined(SUNLIGHT_KILL)
                 color += sp * spec.rgb;
+#endif
             }
         }
        
@@ -167,15 +169,19 @@ vec3 post_diffuse = color.rgb;
         { //add environmentmap
             vec3 env_vec = env_mat * refnormpersp;
             vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
+#if !defined(SUNLIGHT_KILL)
             color = mix(color.rgb, reflected_color, envIntensity); 
+#endif
         }
         
 vec3 post_env = color.rgb;
 
         if (norm.w < 1)
         {
+#if !defined(SUNLIGHT_KILL)
             color = atmosFragLighting(color, additive, atten);
             color = scaleSoftClipFrag(color);
+#endif
         }
 
 vec3 post_atmo = color.rgb;
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
index d5448a1d31a8792efca5d87106e10ded996419e7..2762a35403809bad27fcd8bcb5cccfd99e262f6a 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
@@ -28,32 +28,38 @@
 
 float calcDirectionalLight(vec3 n, vec3 l)
 {
-	float a = max(dot(n,normalize(l)),0.0);
+	float a = max(dot(n,l),0.0);
 	return a;
 }
 
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
 {
 	//get light vector
 	vec3 lv = lp.xyz-v;
 	
 	//get distance
-	float d = length(lv);
+	float dist = length(lv);
+
+    if (dist > la)
+    {
+        return 0;
+    }
 	
 	//normalize light vector
-	lv *= 1.0/d;
-	
-	//distance attenuation
-	float da = clamp(1.0/(la * d), 0.0, 1.0);
-	
+	lv = normalize(lv);
+
+    fa += 1.0;
+    float dist_atten = min(1.0 - (dist-1.0*(1.0 - fa))/fa, 1.0);	
+
+    float da = max(dot(n, lv), 0.0);
+
 	// spotlight coefficient.
 	float spot = max(dot(-ln, lv), is_pointlight);
 	da *= spot*spot; // GL_SPOT_EXPONENT=2
 
 	//angular attenuation
-	da *= calcDirectionalLight(n, lv);
+	da *= dist_atten;
 
-	return da;	
+	return da;
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 7f3f84398b102ab07dd68c2106a67fc2a9509408..88959266c8ad04edc1b147c1b51af3cda8385db4 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -52,7 +52,7 @@ float calcDirectionalLight(vec3 n, vec3 l)
 }
 
 
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
+float calcLocalLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
 {
 	//get light vector
 	vec3 lv = lp.xyz-v;
@@ -91,8 +91,8 @@ void main()
 
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
 	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
-	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
-	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
+	col.rgb += light_diffuse[2].rgb*calcLocalLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcLocalLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
 		
 	vertex_color = col*color;
 }
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
index 8795d69a3a112c7627863519888de20e5b8044d4..30ca88afd2ee29705272de05576b00fdef6f0253 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
@@ -24,7 +24,7 @@
  */
  
 float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
 
 vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
@@ -40,8 +40,8 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
 	
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
 	col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
-	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
-	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
 	col.rgb = scaleDownLight(col.rgb);
 
 #if defined(LOCAL_LIGHT_KILL)
@@ -50,6 +50,7 @@ i#endif
 
 	// Add windlight lights
 	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
+
 #if !defined(SUNLIGHT_KILL)
 	col.rgb = min(col.rgb*color.rgb, 1.0);
 #endif
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
index 38dd850296f4dfb7f84275f8feebf75517908079..4b663dd5b2ee751d20278bb7f87ba4214184d5d4 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
@@ -25,7 +25,7 @@
  
 
 float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
 
 vec3 atmosAffectDirectionalLight(float lightIntensity);
 vec3 scaleDownLight(vec3 light);
@@ -42,12 +42,12 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
 	// Collect normal lights (need to be divided by two, as we later multiply by 2)
 	
 	// Collect normal lights
-	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
-	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
-	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].z);
-	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].z);
-	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].z);
-	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].z);
+	col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+	col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+	col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+	col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+	col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
 	col.rgb += light_diffuse[1].rgb*calcDirectionalLight(norm, light_position[1].xyz);
     col.rgb = scaleDownLight(col.rgb);
 
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e5af47ab6cb69111f161585c53e9700b2bd1bed7..2e54d3de390b4280061f56552acf649884b49001 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -39,6 +39,10 @@
 #include "llappviewer.h" 
 #include "llmemory.h"
 
+#if LL_WINDOWS
+#pragma optimize("", off)
+#endif
+
 // Cache organization:
 // cache/texture.entries
 //  Unordered array of Entry structs
@@ -1225,7 +1229,8 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create
 		{
 			readEntryFromHeaderImmediately(idx, entry) ;
 		}
-		if(entry.mImageSize <= entry.mBodySize)//it happens on 64-bit systems, do not know why
+        llassert(entry.mImageSize < 0 || entry.mImageSize > entry.mBodySize);
+		/*if(entry.mImageSize <= entry.mBodySize)//it happens on 64-bit systems, do not know why
 		{
 			LL_WARNS() << "corrupted entry: " << id << " entry image size: " << entry.mImageSize << " entry body size: " << entry.mBodySize << LL_ENDL ;
 
@@ -1234,7 +1239,7 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create
 			removeEntry(idx, entry, tex_filename) ;
 			mUpdatedEntryMap.erase(idx) ;
 			idx = -1 ;
-		}
+		}*/
 	}
 	return idx;
 }
@@ -1262,12 +1267,12 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool
 	{
 		aprfile = openHeaderEntriesFile(false, offset);
 	}
+    llassert(entry.mImageSize > entry.mBodySize);
 	bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry));
 	if(bytes_written != sizeof(Entry))
 	{
 		clearCorruptedCache() ; //clear the cache.
 		idx = -1 ;//mark the idx invalid.
-
 		return ;
 	}
 
@@ -1314,6 +1319,8 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)
 //update an existing entry, write to header file immediately.
 bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size)
 {
+    llassert(new_image_size >= new_data_size);
+
 	S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ;
 	
 	if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize)
@@ -1402,6 +1409,10 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
 		}
 		entries.push_back(entry);
 // 		LL_INFOS() << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << LL_ENDL;
+        if(entry.mImageSize < 0)
+        {
+            mFreeList.insert(idx);
+        }
 		if(entry.mImageSize > entry.mBodySize)
 		{
 			mHeaderIDMap[entry.mID] = idx;
@@ -1733,28 +1744,27 @@ void LLTextureCache::purgeTextures(bool validate)
 		 iter != time_idx_set.end(); ++iter)
 	{
 		S32 idx = iter->second;
-		bool purge_entry = false;
-		std::string filename = getTextureFileName(entries[idx].mID);
-		if (cache_size >= purged_cache_size)
-		{
-			purge_entry = true;
-		}
-		else if (validate)
+		bool purge_entry = false;		
+        if (validate)
 		{
 			// make sure file exists and is the correct size
 			U32 uuididx = entries[idx].mID.mData[0];
 			if (uuididx == validate_idx)
 			{
+                std::string filename = getTextureFileName(entries[idx].mID);
  				LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
 				S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
 				if (bodysize != entries[idx].mBodySize)
 				{
-					LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
-							<< filename << LL_ENDL;
+					LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize << filename << LL_ENDL;
 					purge_entry = true;
 				}
 			}
 		}
+		else if (cache_size >= purged_cache_size)
+		{
+			purge_entry = true;
+		}
 		else
 		{
 			break;
@@ -1763,6 +1773,7 @@ void LLTextureCache::purgeTextures(bool validate)
 		if (purge_entry)
 		{
 			purge_count++;
+            std::string filename = getTextureFileName(entries[idx].mID);
 	 		LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL;
 			cache_size -= entries[idx].mBodySize;
 			removeEntry(idx, entries[idx], filename) ;			
@@ -1826,6 +1837,8 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
 // Writes imagesize to the header, updates timestamp
 S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize)
 {
+    llassert(imagesize >= datasize);
+
 	mHeaderMutex.lock();
 	S32 idx = openAndReadEntry(id, entry, true); // read or create
 	mHeaderMutex.unlock();
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 81ea7aeee2d98057c70f25b486bfc45b95af1d5e..d29cd0682d3d5d506d2da457a4df5abbd5ff930f 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -45,6 +45,11 @@ class LLTextureCache : public LLWorkerThread
 	friend class LLTextureCacheLocalFileWorker;
 
 private:
+
+#if LL_WINDOWS
+#pragma pack(push,1)
+#endif
+
 	// Entries
 	static const U32 sHeaderEncoderStringSize = 32;
 	struct EntriesInfo
@@ -73,7 +78,10 @@ class LLTextureCache : public LLWorkerThread
 		U32 mTime; // seconds since 1/1/1970
 	};
 
-	
+#if LL_WINDOWS
+#pragma pack(pop)
+#endif
+
 public:
 
 	class Responder : public LLResponder
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f8ef4ee5d7ffb47224061240392fb8256853fffe..f903fdb570fe7dc37e9815feae41d27d09ef986e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6284,12 +6284,27 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			{
 				continue;
 			}
+
+            if (light->isAttachment())
+            {
+                if (!sRenderAttachedLights)
+                {
+                    continue;
+                }
+            }
+
+            const LLViewerObject *vobj = drawable->getVObj();
+            if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList())
+            {
+                continue;
+            }
+
 			if (drawable->isState(LLDrawable::ACTIVE))
 			{
 				mLightMovingMask |= (1<<cur_light);
 			}
 			
-			LLColor4  light_color = light->getLightColor();
+			LLColor4  light_color = sRenderDeferred ? light->getLightSRGBColor() : light->getLightColor();
 			light_color.mV[3] = 0.0f;
 
 			F32 fade = iter->fade;
@@ -6310,13 +6325,27 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 				light_color *= fade;
 			}
 
+            if (light_color.magVecSquared() < 0.001f)
+            {
+                continue;
+            }
+
 			LLVector3 light_pos(light->getRenderPosition());
 			LLVector4 light_pos_gl(light_pos, 1.0f);
 	
 			F32 light_radius = llmax(light->getLightRadius(), 0.001f);
+            F32 size = light_radius *  sRenderDeferred ? 1.5f : 1.0f;
+
+            if (size <= 0.001f)
+            {
+                continue;
+            }
 
 			F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic?  probably trying to match a historic behavior.
-			float linatten = x / (light_radius); // % of brightness at radius
+			F32 linatten = x / (light_radius); // % of brightness at radius
+
+            // get falloff to match for forward deferred rendering lights
+            F32 falloff = light->getLightFalloff()*0.5f + sRenderDeferred ? 0.0 : 1.f;
 
 			mHWLightColors[cur_light] = light_color;
 			LLLightState* light_state = gGL.getLight(cur_light);
@@ -6326,10 +6355,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			light_state->setAmbient(LLColor4::black);
 			light_state->setConstantAttenuation(0.f);
 			if (sRenderDeferred)
-			{
-				F32 size = light_radius*1.5f;
+			{				
 				light_state->setLinearAttenuation(size);
-				light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);
+				light_state->setQuadraticAttenuation(falloff);
 			}
 			else
 			{
@@ -8883,7 +8911,8 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
 
                     LLVector3 center = drawablep->getPositionAgent();
                     F32* c = center.mV;
-                    F32 s = volume->getLightRadius()*1.5f;
+                    F32 light_size_final = volume->getLightRadius()*1.5f;
+                    F32 light_falloff_final = volume->getLightFalloff()*0.5f;
 
                     sVisibleLightCount++;
 
@@ -8893,11 +8922,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
                     setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
 
                     LLColor3 col = volume->getLightSRGBColor();
+
                     
                     gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
-                    gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+                    gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final);
                     gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
-                    gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+                    gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final);
                     mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
                 }