From 38e0b7de96de02243453eeaf5710b924f68abc7a Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 6 Feb 2012 18:56:19 -0600
Subject: SH-2729 Fix for horizontal line of glitching graphics when DoF
 enabled

---
 indra/newview/pipeline.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a64655960f..dffc541001 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6642,9 +6642,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 				mDeferredLight.flush();
 			}
 
+			U32 dof_width = mScreen.getWidth()*CameraDoFResScale;
+			U32 dof_height = mScreen.getHeight()*CameraDoFResScale;
+			
 			{ //perform DoF sampling at half-res (preserve alpha channel)
 				mScreen.bindTarget();
-				glViewport(0,0,(GLsizei) (mScreen.getWidth()*CameraDoFResScale), (GLsizei) (mScreen.getHeight()*CameraDoFResScale));
+				glViewport(0,0, dof_width, dof_height);
 				gGL.setColorMask(true, false);
 
 				shader = &gDeferredPostProgram;
@@ -6657,7 +6660,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
 				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-
+				
 				gGL.begin(LLRender::TRIANGLE_STRIP);
 				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
 				gGL.vertex2f(-1,-1);
@@ -6702,6 +6705,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 
 				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
 				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+				shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1);
+				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1);
 
 				gGL.begin(LLRender::TRIANGLE_STRIP);
 				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-- 
cgit v1.2.3


From 8c15a7e17fceeba9e55e254d7654c1a4f8c3b871 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 7 Feb 2012 14:51:30 -0600
Subject: SH-2902 Fix for avatar bakes etc. getting garbage data sometimes.

---
 indra/newview/pipeline.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dffc541001..c8a8b910ea 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1076,10 +1076,11 @@ void LLPipeline::createGLBuffers()
 
 	if (LLPipeline::sWaterReflections)
 	{ //water reflection texture
-		U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution");
+		U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
 			
 		mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
-		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE);
+		//always use FBO for mWaterDis so it can be used for avatar texture bakes
+		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
 	}
 
 	mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
-- 
cgit v1.2.3


From 001e32074d4fbc5d115c9a2fa1cb5de4b5932731 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 13 Feb 2012 15:32:15 -0600
Subject: SH-2908 More linux build fixes.

---
 indra/newview/pipeline.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c8a8b910ea..ce3a4893bf 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6643,8 +6643,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 				mDeferredLight.flush();
 			}
 
-			U32 dof_width = mScreen.getWidth()*CameraDoFResScale;
-			U32 dof_height = mScreen.getHeight()*CameraDoFResScale;
+			U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale);
+			U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale);
 			
 			{ //perform DoF sampling at half-res (preserve alpha channel)
 				mScreen.bindTarget();
-- 
cgit v1.2.3


From 48f5b69c43d4d4a2b6e272f7ac8d706ccc0c0601 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 17 Feb 2012 19:40:48 -0600
Subject: SH-2915 Smoother transition between sun shadow splits.

---
 indra/newview/pipeline.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ce3a4893bf..d5bcfe12ab 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8817,16 +8817,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 		
 		da = powf(da, split_exp.mV[2]);
 
-
 		F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da;
-
-
+		
 		for (U32 i = 0; i < 4; ++i)
 		{
 			F32 x = (F32)(i+1)/4.f;
 			x = powf(x, sxp);
 			mSunClipPlanes.mV[i] = near_clip+range*x;
 		}
+
+		mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding
 	}
 
 	// convenience array of 4 near clip plane distances
@@ -8883,8 +8883,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 				delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;
 				delta.normVec();
 				F32 dp = delta*pn;
-				frust[i] = eye + (delta*dist[j]*0.95f)/dp;
-				frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp;
+				frust[i] = eye + (delta*dist[j]*0.75f)/dp;
+				frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp;
 			}
 						
 			shadow_cam.calcAgentFrustumPlanes(frust);
-- 
cgit v1.2.3


From 302f4085a5f9fd7b5267fd573a8e15f890cfe573 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Tue, 28 Feb 2012 16:35:50 -0600
Subject: SH-2908 Reset graphics drivers to "low" if viewer crashes when
 allocating deferred rendering targets.

---
 indra/newview/pipeline.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d5bcfe12ab..e2cb22e307 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -811,6 +811,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 
 	if (LLPipeline::sRenderDeferred)
 	{
+		// Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
+		gSavedSettings.setBOOL("RenderInitError", TRUE);
+		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+
 		S32 shadow_detail = RenderShadowDetail;
 		BOOL ssao = RenderDeferredSSAO;
 		
@@ -872,6 +876,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 				mShadow[i].release();
 			}
 		}
+
+		// don't disable shaders on next session
+		gSavedSettings.setBOOL("RenderInitError", FALSE);
+		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
 	}
 	else
 	{
-- 
cgit v1.2.3


From c7106a02b9d16256f2677778074322707faf4d83 Mon Sep 17 00:00:00 2001
From: Jonathan Goodman <geenz@geenzo.com>
Date: Mon, 26 Mar 2012 13:44:28 -0400
Subject: Merging latest changes for normalized blinn-phong.

---
 indra/newview/pipeline.cpp | 82 ++++++++++++++++++++++++++++++----------------
 1 file changed, 53 insertions(+), 29 deletions(-)

(limited to 'indra/newview/pipeline.cpp')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c523a78b22..b7417549ab 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1032,11 +1032,7 @@ void LLPipeline::releaseGLBuffers()
 		mTrueNoiseMap = 0;
 	}
 
-	if (mLightFunc)
-	{
-		LLImageGL::deleteTextures(1, &mLightFunc);
-		mLightFunc = 0;
-	}
+	releaseLUTBuffers();
 
 	mWaterRef.release();
 	mWaterDis.release();
@@ -1052,6 +1048,15 @@ void LLPipeline::releaseGLBuffers()
 	LLVOAvatar::resetImpostors();
 }
 
+void LLPipeline::releaseLUTBuffers()
+{
+	if (mLightFunc)
+	{
+		LLImageGL::deleteTextures(1, &mLightFunc);
+		mLightFunc = 0;
+	}
+}
+
 void LLPipeline::releaseScreenBuffers()
 {
 	mUIScreen.release();
@@ -1146,50 +1151,69 @@ void LLPipeline::createGLBuffers()
 			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 		}
 
+		createLUTBuffers();
+	}
+
+	gBumpImageList.restoreGL();
+}
+
+void LLPipeline::createLUTBuffers()
+{
+	if (sRenderDeferred)
+	{
 		if (!mLightFunc)
 		{
 			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
 			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
-			U8* lg = new U8[lightResX*lightResY];
-
+			U8* ls = new U8[lightResX*lightResY];
+			F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
+            // Calculate the (normalized) Blinn-Phong specular lookup texture.
 			for (U32 y = 0; y < lightResY; ++y)
 			{
 				for (U32 x = 0; x < lightResX; ++x)
 				{
-					//spec func
+					ls[y*lightResX+x] = 0;
 					F32 sa = (F32) x/(lightResX-1);
 					F32 spec = (F32) y/(lightResY-1);
-					//lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255);
-
-					//F32 sp = acosf(sa)/(1.f-spec);
-
-					sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent"));
-					F32 a = acosf(sa*0.25f+0.75f);
-					F32 m = llmax(0.5f-spec*0.5f, 0.001f);
-					F32 t2 = tanf(a)/m;
-					t2 *= t2;
-
-					F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f;
-					F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2);
-
-					lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255);
+					F32 n = spec * spec * specExp;
+					
+					// Nothing special here.  Just your typical blinn-phong term.
+					spec = powf(sa, n);
+					
+					// Apply our normalization function.
+					// Note: This is the full equation that applies the full normalization curve, not an approximation.
+					// This is fine, given we only need to create our LUT once per buffer initialization.
+					// The only trade off is we have a really low dynamic range.
+					// This means we have to account for things not being able to exceed 0 to 1 in our shaders.
+					spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+					
+					// Always sample at a 1.0/2.2 curve.
+					// This "Gamma corrects" our specular term, boosting our lower exponent reflections.
+					spec = powf(spec, 1.f/2.2f);
+					
+					// Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders.
+					// This allows for our specular term to exceed a value of 1 in our shaders.
+					// This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1.
+					// Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times.
+					// This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents.
+					// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
+					ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
 				}
 			}
-
+			
 			LLImageGL::generateTextures(1, &mLightFunc);
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
-			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, lg);
+			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls);
 			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
 			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
-
-			delete [] lg;
+			
+			delete [] ls;
 		}
 	}
-
-	gBumpImageList.restoreGL();
 }
 
-void LLPipeline::restoreGL() 
+
+void LLPipeline::restoreGL()
 {
 	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_RESTORE_GL);
 	assertInitialized();
-- 
cgit v1.2.3