From 82ba39d2ff6eb0067bcb384246541eb54e206cd9 Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Sat, 8 Apr 2023 19:30:58 -0700
Subject: Start moving our post process into methods.

Lets make post processing make sense again.

DRTVWR-559
SL-19524
SL-19513
---
 indra/newview/llviewerdisplay.cpp |   3 -
 indra/newview/pipeline.cpp        | 989 +++++++++++++++++++-------------------
 indra/newview/pipeline.h          |   6 +
 3 files changed, 490 insertions(+), 508 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 59333b6cee..a44452f0d1 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1307,9 +1307,6 @@ void render_ui(F32 zoom_factor, int subfield)
 		gGL.popMatrix();
 	}
 
-    // Render our post process prior to the HUD, UI, etc.
-    gPipeline.renderPostProcess();
-
     // apply gamma correction and post effects
     gPipeline.renderFinalize();
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e4ffa5b6b0..a1183ccb0f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6924,514 +6924,219 @@ void LLPipeline::renderPostProcess()
 
 	LLVertexBuffer::unbind();
 
-    {
-		bool dof_enabled = 
-			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
-			RenderDepthOfField &&
-			!gCubeSnapshot;
+    
+}
 
-		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
+LLRenderTarget* LLPipeline::screenTarget() {
 
-		gViewerWindow->setup3DViewport();
+	bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+		(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+		RenderDepthOfField &&
+		!gCubeSnapshot;
 
-		if (dof_enabled)
-		{
-			LL_PROFILE_GPU_ZONE("dof");
-			LLGLSLShader* shader = &gDeferredPostProgram;
-			LLGLDisable blend(GL_BLEND);
+	bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
 
-			// depth of field focal plane calculations
-			static F32 current_distance = 16.f;
-			static F32 start_distance = 16.f;
-			static F32 transition_time = 1.f;
+	if (multisample || dof_enabled)
+		return &mRT->deferredLight;
+	
+	return &mRT->screen;
+}
 
-			LLVector3 focus_point;
+void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) {
+	// luminance sample and mipmap generation
+	{
+		LL_PROFILE_GPU_ZONE("luminance sample");
 
-			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
-			if (obj && obj->mDrawable && obj->isSelected())
-			{ // focus on selected media object
-				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
-				if (obj && obj->mDrawable)
-				{
-					LLFace* face = obj->mDrawable->getFace(face_idx);
-					if (face)
-					{
-						focus_point = face->getPositionAgent();
-					}
-				}
-			}
+		dst->bindTarget();
 
-			if (focus_point.isExactlyZero())
-			{
-				if (LLViewerJoystick::getInstance()->getOverrideCamera())
-				{ // focus on point under cursor
-					focus_point.set(gDebugRaycastIntersection.getF32ptr());
-				}
-				else if (gAgentCamera.cameraMouselook())
-				{ // focus on point under mouselook crosshairs
-					LLVector4a result;
-					result.clear();
+		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
-					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
+		gLuminanceProgram.bind();
 
-					focus_point.set(result.getF32ptr());
-				}
-				else
-				{
-					// focus on alt-zoom target
-					LLViewerRegion* region = gAgent.getRegion();
-					if (region)
-					{
-						focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
-					}
-				}
-			}
 
-			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
-			F32 target_distance = 16.f;
-			if (!focus_point.isExactlyZero())
-			{
-				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
-			}
+		S32 channel = 0;
+		channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
+		if (channel > -1)
+		{
+			src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+		}
 
-			if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
-			{ // large shift happened, interpolate smoothly to new target distance
-				transition_time = 0.f;
-				start_distance = current_distance;
-			}
-			else if (transition_time < 1.f)
-			{ // currently in a transition, continue interpolating
-				transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
-				transition_time = llmin(transition_time, 1.f);
+		channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+		if (channel > -1)
+		{
+			mGlow[1].bindTexture(0, channel);
+		}
 
-				F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
-				current_distance = start_distance + (target_distance - start_distance) * t;
-			}
-			else
-			{ // small or no change, just snap to target distance
-				current_distance = target_distance;
-			}
 
-			// convert to mm
-			F32 subject_distance = current_distance * 1000.f;
-			F32 fnumber = CameraFNumber;
-			F32 default_focal_length = CameraFocalLength;
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+		dst->flush();
 
-			F32 fov = LLViewerCamera::getInstance()->getView();
+		dst->bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
+		glGenerateMipmap(GL_TEXTURE_2D);
 
-			const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
+		// note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance"
+		// also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader
+		gLuminanceProgram.unbind();
+	}
+}
 
-			// F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
+void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
+	// exposure sample
+	{
+		LL_PROFILE_GPU_ZONE("exposure sample");
 
-			F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
+		{
+			// copy last frame's exposure into mLastExposure
+			mLastExposure.bindTarget();
+			gCopyProgram.bind();
+			gGL.getTexUnit(0)->bind(&mExposureMap);
 
-			F32 focal_length = dv / (2 * tanf(fov / 2.f));
+			mScreenTriangleVB->setBuffer();
+			mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-			// F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+			mLastExposure.flush();
+		}
 
-			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
-			// where	 N = fnumber
-			//			 s2 = dot distance
-			//			 s1 = subject distance
-			//			 f = focal length
-			//
+		dst->bindTarget();
 
-			F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
-			blur_constant /= 1000.f; // convert to meters for shader
-			F32 magnification = focal_length / (subject_distance - focal_length);
+		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
-			{ // build diffuse+bloom+CoF
-                mRT->deferredLight.bindTarget();
-				shader = &gDeferredCoFProgram;
+		gExposureProgram.bind();
 
-				bindDeferredShader(*shader);
+		S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+		if (channel > -1)
+		{
+			src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
+		}
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
-				if (channel > -1)
-				{
-					mRT->screen.bindTexture(0, channel);
-				}
+		channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
+		if (channel > -1)
+		{
+			mLastExposure.bindTexture(0, channel);
+		}
 
-				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
-				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
-				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
-				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+		static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
+		static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f);
+		static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f);
 
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1, -1);
+		static LLStaticHashedString dt("dt");
+		static LLStaticHashedString noiseVec("noiseVec");
+		static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
+		gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
+		gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
+		gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max);
 
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1, 3);
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3, -1);
+		gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
+		gExposureProgram.unbind();
+		dst->flush();
+	}
+}
 
-				gGL.end();
+void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
+	dst->bindTarget();
+	// gamma correct lighting
+	{
+		LL_PROFILE_GPU_ZONE("gamma correct");
 
-				unbindDeferredShader(*shader);
-                mRT->deferredLight.flush();
-			}
+		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
-			U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
-			U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
+		// Apply gamma correction to the frame here.
+		gDeferredPostGammaCorrectProgram.bind();
 
-			{ // perform DoF sampling at half-res (preserve alpha channel)
-				mRT->screen.bindTarget();
-				glViewport(0, 0, dof_width, dof_height);
-				gGL.setColorMask(true, false);
+		S32 channel = 0;
 
-				shader = &gDeferredPostProgram;
-				bindDeferredShader(*shader);
-                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
-				if (channel > -1)
-				{
-                    mRT->deferredLight.bindTexture(0, channel);
-				}
+		gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
 
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+		gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
 
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1, -1);
+		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight());
 
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1, 3);
+		static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
 
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3, -1);
+		F32 e = llclamp(exposure(), 0.5f, 4.f);
 
-				gGL.end();
+		static LLStaticHashedString s_exposure("exposure");
 
-				unbindDeferredShader(*shader);
-				mRT->screen.flush();
-				gGL.setColorMask(true, true);
-			}
+		gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
 
-			{ // combine result based on alpha
-				if (multisample)
-				{
-					mRT->deferredLight.bindTarget();
-					glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight());
-				}
-				else
-				{
-					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-				}
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-				shader = &gDeferredDoFCombineProgram;
-				bindDeferredShader(*shader);
+		gGL.getTexUnit(channel)->unbind(src->getUsage());
+		gDeferredPostGammaCorrectProgram.unbind();
+	}
+	dst->flush();
+}
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
-				if (channel > -1)
-				{
-					mRT->screen.bindTexture(0, channel);
-				}
+void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) {
 
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-				shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth());
-				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight());
+	if (RenderScreenSpaceReflections && !gCubeSnapshot)
+	{
+		LL_PROFILE_GPU_ZONE("ssr copy");
+		LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
 
-				gGL.begin(LLRender::TRIANGLE_STRIP);
-				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-				gGL.vertex2f(-1, -1);
+		LLRenderTarget& depth_src = mRT->deferredScreen;
 
-				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-				gGL.vertex2f(-1, 3);
+		dst->bindTarget();
+		dst->clear();
+		gCopyDepthProgram.bind();
 
-				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-				gGL.vertex2f(3, -1);
+		S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+		S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
 
-				gGL.end();
+		gGL.getTexUnit(diff_map)->bind(src);
+		gGL.getTexUnit(depth_map)->bind(&depth_src, true);
 
-				unbindDeferredShader(*shader);
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-				if (multisample)
-				{
-					mRT->deferredLight.flush();
-				}
-			}
-		}
-		else
-		{
-			LL_PROFILE_GPU_ZONE("no dof");
-			if (multisample)
-			{
-				mRT->deferredLight.bindTarget();
-			}
-			LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
+		dst->flush();
+	}
+}
 
-			bindDeferredShader(*shader);
+void LLPipeline::renderGlow(LLRenderTarget* src, LLRenderTarget* dst) {
+	if (sRenderGlow)
+	{
+		LL_PROFILE_GPU_ZONE("glow");
+		mGlow[2].bindTarget();
+		mGlow[2].clear();
 
-			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
-			if (channel > -1)
-			{
-				mRT->screen.bindTexture(0, channel);
-			}
+		gGlowExtractProgram.bind();
+		F32 maxAlpha = RenderGlowMaxExtractAlpha;
+		F32 warmthAmount = RenderGlowWarmthAmount;
+		LLVector3 lumWeights = RenderGlowLumWeights;
+		LLVector3 warmthWeights = RenderGlowWarmthWeights;
 
-			gGL.begin(LLRender::TRIANGLE_STRIP);
-			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
-			gGL.vertex2f(-1, -1);
+		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999);
+		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
+			lumWeights.mV[2]);
+		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
+			warmthWeights.mV[2]);
+		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
 
-			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
-			gGL.vertex2f(-1, 3);
+		{
+			LLGLEnable blend_on(GL_BLEND);
+			LLGLEnable test(GL_ALPHA_TEST);
 
-			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
-			gGL.vertex2f(3, -1);
+			gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 
-			gGL.end();
+			gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src);
 
-			unbindDeferredShader(*shader);
+			gGL.color4f(1, 1, 1, 1);
+			gPipeline.enableLightsFullbright();
 
-			if (multisample)
-			{
-				mRT->deferredLight.flush();
-			}
+			mScreenTriangleVB->setBuffer();
+			mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+			mGlow[2].flush();
 		}
-	}
-}
 
-LLRenderTarget* LLPipeline::screenTarget() {
-
-	bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
-		(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
-		RenderDepthOfField &&
-		!gCubeSnapshot;
-
-	bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
-
-	if (multisample || dof_enabled)
-		return &mRT->deferredLight;
-	
-	return &mRT->screen;
-}
-
-void LLPipeline::renderFinalize()
-{
-    LLVertexBuffer::unbind();
-    LLGLState::checkStates();
-
-    assertInitialized();
-
-    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
-    LL_PROFILE_GPU_ZONE("renderFinalize");
-
-    gGL.color4f(1, 1, 1, 1);
-    LLGLDepthTest depth(GL_FALSE);
-    LLGLDisable blend(GL_BLEND);
-    LLGLDisable cull(GL_CULL_FACE);
-
-    enableLightsFullbright();
-
-    LLGLDisable test(GL_ALPHA_TEST);
-
-    gGL.setColorMask(true, true);
-    glClearColor(0, 0, 0, 0);
-
-    if (!gCubeSnapshot)
-    {
-        LLRenderTarget* screen_target = screenTarget();
-
-        if (RenderScreenSpaceReflections && !gCubeSnapshot)
-        {
-            LL_PROFILE_GPU_ZONE("ssr copy");
-            LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
-
-            LLRenderTarget& src = *screen_target;
-            LLRenderTarget& depth_src = mRT->deferredScreen;
-            LLRenderTarget& dst = mSceneMap;
-
-            dst.bindTarget();
-            dst.clear();
-            gCopyDepthProgram.bind();
-
-            S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
-            S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
-
-            gGL.getTexUnit(diff_map)->bind(&src);
-            gGL.getTexUnit(depth_map)->bind(&depth_src, true);
-
-            mScreenTriangleVB->setBuffer();
-            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
-            dst.flush();
-        }
-
-        // luminance sample and mipmap generation
-        {
-            LL_PROFILE_GPU_ZONE("luminance sample");
-
-            mLuminanceMap.bindTarget();
-
-            LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
-            gLuminanceProgram.bind();
-
-
-            S32 channel = 0;
-            channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
-            if (channel > -1)
-            {
-                screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
-            }
-
-            channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
-            if (channel > -1)
-            {
-                mGlow[1].bindTexture(0, channel);
-            }
-
-
-            mScreenTriangleVB->setBuffer();
-            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-            mLuminanceMap.flush();
-
-            mLuminanceMap.bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
-            glGenerateMipmap(GL_TEXTURE_2D);
-
-            // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance"
-            // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader
-            gLuminanceProgram.unbind();
-        }
-
-        // exposure sample
-        {
-            LL_PROFILE_GPU_ZONE("exposure sample");
-
-            {
-                // copy last frame's exposure into mLastExposure
-                mLastExposure.bindTarget();
-                gCopyProgram.bind();
-                gGL.getTexUnit(0)->bind(&mExposureMap);
-
-                mScreenTriangleVB->setBuffer();
-                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
-                mLastExposure.flush();
-            }
-
-            mExposureMap.bindTarget();
-
-            LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-            
-            gExposureProgram.bind();
-
-            S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
-            if (channel > -1)
-            {
-                mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
-            }
-
-            channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
-            if (channel > -1)
-            {
-                mLastExposure.bindTexture(0, channel);
-            }
-
-            static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
-            static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f);
-            static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f);
-
-            static LLStaticHashedString dt("dt");
-            static LLStaticHashedString noiseVec("noiseVec");
-            static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
-            gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
-            gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
-            gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max);
-
-            mScreenTriangleVB->setBuffer();
-            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
-            gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
-            gExposureProgram.unbind();
-            mExposureMap.flush();
-        }
-
-        mPostMap.bindTarget();
-
-        // gamma correct lighting
-        {
-            LL_PROFILE_GPU_ZONE("gamma correct");
-
-            LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
-            // Apply gamma correction to the frame here.
-            gDeferredPostGammaCorrectProgram.bind();
-            
-            S32 channel = 0;
-
-            gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget(), false, LLTexUnit::TFO_POINT);
-
-			gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
-
-            gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight());
-
-            static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
-
-            F32 e = llclamp(exposure(), 0.5f, 4.f);
-
-            static LLStaticHashedString s_exposure("exposure");
-
-            gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
-
-            mScreenTriangleVB->setBuffer();
-            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
-            gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
-            gDeferredPostGammaCorrectProgram.unbind();
-        }
-
-        mPostMap.flush();
-
-        LLVertexBuffer::unbind();
-    }
-
-	if (sRenderGlow)
-	{
-		LL_PROFILE_GPU_ZONE("glow");
-		mGlow[2].bindTarget();
-		mGlow[2].clear();
-
-		gGlowExtractProgram.bind();
-		F32 maxAlpha = RenderGlowMaxExtractAlpha;
-		F32 warmthAmount = RenderGlowWarmthAmount;
-		LLVector3 lumWeights = RenderGlowLumWeights;
-		LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999);
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
-		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
-			lumWeights.mV[2]);
-		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
-			warmthWeights.mV[2]);
-		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
-
-		{
-			LLGLEnable blend_on(GL_BLEND);
-			LLGLEnable test(GL_ALPHA_TEST);
-
-			gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-
-			gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mPostMap);
-
-			gGL.color4f(1, 1, 1, 1);
-			gPipeline.enableLightsFullbright();
-
-			mScreenTriangleVB->setBuffer();
-			mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
-			mGlow[2].flush();
-		}
-
-		gGlowExtractProgram.unbind();
+		gGlowExtractProgram.unbind();
 
 		// power of two between 1 and 1024
 		U32 glowResPow = RenderGlowResolutionPow;
@@ -7480,7 +7185,7 @@ void LLPipeline::renderFinalize()
 		}
 
 		gGlowProgram.unbind();
-		gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
 	}
 	else // !sRenderGlow, skip the glow ping-pong and just clear the result target
 	{
@@ -7489,16 +7194,35 @@ void LLPipeline::renderFinalize()
 		mGlow[1].flush();
 	}
 
+	// Go ahead and do our glow combine here in our destination.  We blit this later into the front buffer.
+
+	dst->bindTarget();
+
+	{
+		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+		gGlowCombineProgram.bind();
+
+		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
+		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
+
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+	}
+
+	dst->flush();
+}
+
+void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
 	{
-        llassert(!gCubeSnapshot);
+		llassert(!gCubeSnapshot);
 		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
 		LLGLSLShader* shader = &gGlowCombineProgram;
 
 		S32 width = screenTarget()->getWidth();
 		S32 height = screenTarget()->getHeight();
 
-		S32 channel = -1;
-
 		// Present everything.
 		if (multisample)
 		{
@@ -7506,38 +7230,27 @@ void LLPipeline::renderFinalize()
 			// bake out texture2D with RGBL for FXAA shader
 			mRT->fxaaBuffer.bindTarget();
 
-			glViewport(0, 0, width, height);
-
-			shader = &gGlowCombineFXAAProgram;
-
+			shader = &gDeferredPostNoDoFProgram;
 			shader->bind();
-			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
 
-			channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage());
+			S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
 			if (channel > -1)
 			{
-				mPostMap.bindTexture(0, channel);
+				src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
 			}
 
-			channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, mGlow[1].getUsage());
-			if (channel > -1)
 			{
-				mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+				LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+				mScreenTriangleVB->setBuffer();
+				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 			}
 
-            {
-                LLGLDepthTest depth_test(GL_FALSE, GL_FALSE, GL_ALWAYS);
-                mScreenTriangleVB->setBuffer();
-                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-            }
-
-			gGL.flush();
-
-			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage());
+			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
 			shader->unbind();
 
 			mRT->fxaaBuffer.flush();
 
+			dst->bindTarget();
 			shader = &gFXAAProgram;
 			shader->bind();
 
@@ -7547,12 +7260,6 @@ void LLPipeline::renderFinalize()
 				mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
 			}
 
-			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-
 			F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth();
 			F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight();
 			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
@@ -7562,46 +7269,318 @@ void LLPipeline::renderFinalize()
 			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
 				2.f / width * scale_x, 2.f / height * scale_y);
 
-            {
-                // at this point we should pointed at the backbuffer (or a snapshot render target)
-                llassert(gSnapshot || LLRenderTarget::sCurFBO == 0);
-                LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
-                S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
-                gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
+			{
+				// at this point we should pointed at the backbuffer (or a snapshot render target)
+				LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+				S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+				gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
+
+				mScreenTriangleVB->setBuffer();
+				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+			}
 
-                mScreenTriangleVB->setBuffer();
-                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-            }
-			
 			shader->unbind();
+			dst->flush();
 		}
-		else
+	}
+}
+
+void LLPipeline::renderFinalize()
+{
+    LLVertexBuffer::unbind();
+    LLGLState::checkStates();
+
+    assertInitialized();
+
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+    LL_PROFILE_GPU_ZONE("renderFinalize");
+
+    gGL.color4f(1, 1, 1, 1);
+    LLGLDepthTest depth(GL_FALSE);
+    LLGLDisable blend(GL_BLEND);
+    LLGLDisable cull(GL_CULL_FACE);
+
+    enableLightsFullbright();
+
+    LLGLDisable test(GL_ALPHA_TEST);
+
+    gGL.setColorMask(true, true);
+    glClearColor(0, 0, 0, 0);
+
+    if (!gCubeSnapshot)
+    {
+
+		copyScreenSpaceReflections(&mSceneMap, screenTarget());
+
+		generateLuminance(screenTarget(), &mLuminanceMap);
+
+		generateExposure(&mLuminanceMap, &mExposureMap);
+
+		gammaCorrect(screenTarget(), &mPostMap);
+
+        LLVertexBuffer::unbind();
+    }
+
+	renderGlow(&mPostMap, screenTarget());
+	/*
+	{
+		bool dof_enabled =
+			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+			RenderDepthOfField &&
+			!gCubeSnapshot;
+
+		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
+
+		gViewerWindow->setup3DViewport();
+
+		if (dof_enabled)
 		{
-            // at this point we should pointed at the backbuffer (or a snapshot render target)
-            llassert(gSnapshot || LLRenderTarget::sCurFBO == 0);
+			LL_PROFILE_GPU_ZONE("dof");
+			LLGLSLShader* shader = &gDeferredPostProgram;
+			LLGLDisable blend(GL_BLEND);
+
+			// depth of field focal plane calculations
+			static F32 current_distance = 16.f;
+			static F32 start_distance = 16.f;
+			static F32 transition_time = 1.f;
 
-            LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+			LLVector3 focus_point;
 
-			shader->bind();
+			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+			if (obj && obj->mDrawable && obj->isSelected())
+			{ // focus on selected media object
+				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+				if (obj && obj->mDrawable)
+				{
+					LLFace* face = obj->mDrawable->getFace(face_idx);
+					if (face)
+					{
+						focus_point = face->getPositionAgent();
+					}
+				}
+			}
+
+			if (focus_point.isExactlyZero())
+			{
+				if (LLViewerJoystick::getInstance()->getOverrideCamera())
+				{ // focus on point under cursor
+					focus_point.set(gDebugRaycastIntersection.getF32ptr());
+				}
+				else if (gAgentCamera.cameraMouselook())
+				{ // focus on point under mouselook crosshairs
+					LLVector4a result;
+					result.clear();
 
-			shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mPostMap);
-			shader->bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
-			shader->bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
+					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
 
-			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+					focus_point.set(result.getF32ptr());
+				}
+				else
+				{
+					// focus on alt-zoom target
+					LLViewerRegion* region = gAgent.getRegion();
+					if (region)
+					{
+						focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+					}
+				}
+			}
 
-            mScreenTriangleVB->setBuffer();
-            mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+			F32 target_distance = 16.f;
+			if (!focus_point.isExactlyZero())
+			{
+				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+			}
 
-			gGL.flush();
-			shader->unbind();
+			if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
+			{ // large shift happened, interpolate smoothly to new target distance
+				transition_time = 0.f;
+				start_distance = current_distance;
+			}
+			else if (transition_time < 1.f)
+			{ // currently in a transition, continue interpolating
+				transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
+				transition_time = llmin(transition_time, 1.f);
+
+				F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
+				current_distance = start_distance + (target_distance - start_distance) * t;
+			}
+			else
+			{ // small or no change, just snap to target distance
+				current_distance = target_distance;
+			}
+
+			// convert to mm
+			F32 subject_distance = current_distance * 1000.f;
+			F32 fnumber = CameraFNumber;
+			F32 default_focal_length = CameraFocalLength;
+
+			F32 fov = LLViewerCamera::getInstance()->getView();
+
+			const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
+
+			// F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
+
+			F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
+
+			F32 focal_length = dv / (2 * tanf(fov / 2.f));
+
+			// F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+
+			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+			// where	 N = fnumber
+			//			 s2 = dot distance
+			//			 s1 = subject distance
+			//			 f = focal length
+			//
+
+			F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
+			blur_constant /= 1000.f; // convert to meters for shader
+			F32 magnification = focal_length / (subject_distance - focal_length);
+
+			{ // build diffuse+bloom+CoF
+				mRT->deferredLight.bindTarget();
+				shader = &gDeferredCoFProgram;
+
+				bindDeferredShader(*shader);
+
+				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+				if (channel > -1)
+				{
+					mRT->screen.bindTexture(0, channel);
+				}
+
+				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+
+				mScreenTriangleVB->setBuffer();
+				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+				unbindDeferredShader(*shader);
+				mRT->deferredLight.flush();
+			}
+
+			U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
+			U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
+
+			{ // perform DoF sampling at half-res (preserve alpha channel)
+				mRT->screen.bindTarget();
+				glViewport(0, 0, dof_width, dof_height);
+				gGL.setColorMask(true, false);
+
+				shader = &gDeferredPostProgram;
+				bindDeferredShader(*shader);
+				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
+				if (channel > -1)
+				{
+					mRT->deferredLight.bindTexture(0, channel);
+				}
+
+				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+
+				mScreenTriangleVB->setBuffer();
+				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+				unbindDeferredShader(*shader);
+				mRT->screen.flush();
+				gGL.setColorMask(true, true);
+			}
+
+			{ // combine result based on alpha
+				if (multisample)
+				{
+					mRT->deferredLight.bindTarget();
+					glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight());
+				}
+				else
+				{
+					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+				}
+
+				shader = &gDeferredDoFCombineProgram;
+				bindDeferredShader(*shader);
+
+				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+				if (channel > -1)
+				{
+					mRT->screen.bindTexture(0, channel);
+				}
+
+				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+				shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth());
+				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight());
+
+				mScreenTriangleVB->setBuffer();
+				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+				unbindDeferredShader(*shader);
+
+				if (multisample)
+				{
+					mRT->deferredLight.flush();
+				}
+			}
 		}
+		else
+		{
+			LL_PROFILE_GPU_ZONE("no dof");
+			if (multisample)
+			{
+				mRT->deferredLight.bindTarget();
+			}
+			LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
+
+			bindDeferredShader(*shader);
+
+			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+			if (channel > -1)
+			{
+				mRT->screen.bindTexture(0, channel);
+			}
+
+			mScreenTriangleVB->setBuffer();
+			mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+			unbindDeferredShader(*shader);
+
+			if (multisample)
+			{
+				mRT->deferredLight.flush();
+			}
+		}
+	}*/
+
+	//applyFXAA(screenTarget(), screenTarget());
+
+	// Present the screen target.
+
+	gDeferredPostNoDoFProgram.bind();
+
+	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
+	if (channel > -1)
+	{
+		screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+	}
+
+	{
+		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 	}
 
+	gDeferredPostNoDoFProgram.unbind();
+
     gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
     if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index a231084e5c..3ed9ed73a8 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -135,6 +135,12 @@ public:
 	void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false);
 	void bindScreenToTexture();
 	void renderFinalize();
+	void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
+	void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
+	void generateExposure(LLRenderTarget* src, LLRenderTarget* dst);
+	void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
+	void renderGlow(LLRenderTarget* src, LLRenderTarget* dst);
+	void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
 	void renderPostProcess();
 	LLRenderTarget* screenTarget();
 
-- 
cgit v1.2.3


From 5bfae438fda23d287898238ad7cbedafd81fb33a Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Sat, 8 Apr 2023 20:18:15 -0700
Subject: Start scrapping screenTarget().

Makes our binding flow _far more_ predictable and makes way more sense.

DRTVWR-559
SL-19524
SL-19513
---
 .../shaders/class1/interface/glowcombineFXAAF.glsl |  3 +-
 indra/newview/pipeline.cpp                         | 43 +++++++++++++++++-----
 2 files changed, 34 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
index 6cc83138a2..c50548d528 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
@@ -30,7 +30,6 @@
 out vec4 frag_color;
 
 uniform sampler2D diffuseRect;
-uniform sampler2D emissiveRect;
 
 uniform vec2 screen_res;
 
@@ -38,7 +37,7 @@ in vec2 vary_tc;
 
 void main() 
 {
-    vec3 col = texture(diffuseRect, vary_tc).rgb + texture(emissiveRect, vary_tc).rgb;
+    vec3 col = texture(diffuseRect, vary_tc).rgb;
    
     frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));
 }
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a1183ccb0f..15c827ffca 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7230,10 +7230,10 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
 			// bake out texture2D with RGBL for FXAA shader
 			mRT->fxaaBuffer.bindTarget();
 
-			shader = &gDeferredPostNoDoFProgram;
+			shader = &gGlowCombineFXAAProgram;
 			shader->bind();
 
-			S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
 			if (channel > -1)
 			{
 				src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
@@ -7270,7 +7270,6 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
 				2.f / width * scale_x, 2.f / height * scale_y);
 
 			{
-				// at this point we should pointed at the backbuffer (or a snapshot render target)
 				LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
 				S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
 				gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
@@ -7282,6 +7281,28 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
 			shader->unbind();
 			dst->flush();
 		}
+		else {
+			// Just copy directly into the destination.
+			dst->bindTarget();
+
+			gDeferredPostNoDoFProgram.bind();
+
+			S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+			if (channel > -1)
+			{
+				src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+			}
+
+			{
+				LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+				mScreenTriangleVB->setBuffer();
+				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+			}
+
+			gDeferredPostNoDoFProgram.unbind();
+
+			dst->flush();
+		}
 	}
 }
 
@@ -7310,18 +7331,19 @@ void LLPipeline::renderFinalize()
     if (!gCubeSnapshot)
     {
 
-		copyScreenSpaceReflections(&mSceneMap, screenTarget());
+		copyScreenSpaceReflections(&mSceneMap, &mRT->screen);
 
-		generateLuminance(screenTarget(), &mLuminanceMap);
+		generateLuminance(&mRT->screen, &mLuminanceMap);
 
 		generateExposure(&mLuminanceMap, &mExposureMap);
 
-		gammaCorrect(screenTarget(), &mPostMap);
+		gammaCorrect(&mRT->screen, &mPostMap);
 
         LLVertexBuffer::unbind();
     }
 
-	renderGlow(&mPostMap, screenTarget());
+	renderGlow(&mPostMap, &mRT->screen);
+
 	/*
 	{
 		bool dof_enabled =
@@ -7561,16 +7583,17 @@ void LLPipeline::renderFinalize()
 		}
 	}*/
 
-	//applyFXAA(screenTarget(), screenTarget());
+	applyFXAA(&mRT->screen, &mPostMap);
 
 	// Present the screen target.
 
 	gDeferredPostNoDoFProgram.bind();
 
-	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
+	// Whatever is last in the above post processing chain should _always_ be rendered directly here.  If not, expect problems.
+	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage());
 	if (channel > -1)
 	{
-		screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+		mPostMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
 	}
 
 	{
-- 
cgit v1.2.3


From 635037ea30cfbd259c0678a04bd1d6574f5d37b4 Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Sat, 8 Apr 2023 23:18:34 -0700
Subject: Fix SSR.

DRTVWR-559
SL-19524
SL-19513
---
 indra/newview/pipeline.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 15c827ffca..dccbd46c8c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7331,7 +7331,7 @@ void LLPipeline::renderFinalize()
     if (!gCubeSnapshot)
     {
 
-		copyScreenSpaceReflections(&mSceneMap, &mRT->screen);
+		copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
 
 		generateLuminance(&mRT->screen, &mLuminanceMap);
 
-- 
cgit v1.2.3


From 1d316c8a25bfe057032582f89b6be7d461475e55 Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Mon, 10 Apr 2023 10:56:31 -0700
Subject: Get DoF moved into its own method

Still broken, figuring out what's up with depth.

DRTVWR-559
SL-19524
SL-19513
---
 indra/newview/pipeline.cpp | 172 +++++++++++++++++++--------------------------
 indra/newview/pipeline.h   |   2 +
 2 files changed, 74 insertions(+), 100 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dccbd46c8c..64f9c519d2 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7282,77 +7282,40 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
 			dst->flush();
 		}
 		else {
-			// Just copy directly into the destination.
-			dst->bindTarget();
-
-			gDeferredPostNoDoFProgram.bind();
-
-			S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
-			if (channel > -1)
-			{
-				src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
-			}
-
-			{
-				LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
-				mScreenTriangleVB->setBuffer();
-				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-			}
-
-			gDeferredPostNoDoFProgram.unbind();
-
-			dst->flush();
+			copyRenderTarget(src, dst);
 		}
 	}
 }
 
-void LLPipeline::renderFinalize()
-{
-    LLVertexBuffer::unbind();
-    LLGLState::checkStates();
-
-    assertInitialized();
-
-    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
-    LL_PROFILE_GPU_ZONE("renderFinalize");
-
-    gGL.color4f(1, 1, 1, 1);
-    LLGLDepthTest depth(GL_FALSE);
-    LLGLDisable blend(GL_BLEND);
-    LLGLDisable cull(GL_CULL_FACE);
-
-    enableLightsFullbright();
-
-    LLGLDisable test(GL_ALPHA_TEST);
-
-    gGL.setColorMask(true, true);
-    glClearColor(0, 0, 0, 0);
-
-    if (!gCubeSnapshot)
-    {
-
-		copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
+void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
+	dst->bindTarget();
 
-		generateLuminance(&mRT->screen, &mLuminanceMap);
+	gDeferredPostNoDoFProgram.bind();
 
-		generateExposure(&mLuminanceMap, &mExposureMap);
+	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+	if (channel > -1)
+	{
+		src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+	}
 
-		gammaCorrect(&mRT->screen, &mPostMap);
+	{
+		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+	}
 
-        LLVertexBuffer::unbind();
-    }
+	gDeferredPostNoDoFProgram.unbind();
 
-	renderGlow(&mPostMap, &mRT->screen);
+	dst->flush();
+}
 
-	/*
+void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
 	{
 		bool dof_enabled =
 			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
 			RenderDepthOfField &&
 			!gCubeSnapshot;
 
-		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
-
 		gViewerWindow->setup3DViewport();
 
 		if (dof_enabled)
@@ -7467,10 +7430,10 @@ void LLPipeline::renderFinalize()
 
 				bindDeferredShader(*shader);
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
 				if (channel > -1)
 				{
-					mRT->screen.bindTexture(0, channel);
+					src->bindTexture(0, channel);
 				}
 
 				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
@@ -7491,7 +7454,7 @@ void LLPipeline::renderFinalize()
 			U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
 
 			{ // perform DoF sampling at half-res (preserve alpha channel)
-				mRT->screen.bindTarget();
+				src->bindTarget();
 				glViewport(0, 0, dof_width, dof_height);
 				gGL.setColorMask(true, false);
 
@@ -7510,90 +7473,99 @@ void LLPipeline::renderFinalize()
 				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
 				unbindDeferredShader(*shader);
-				mRT->screen.flush();
+				src->flush();
 				gGL.setColorMask(true, true);
 			}
 
 			{ // combine result based on alpha
-				if (multisample)
-				{
-					mRT->deferredLight.bindTarget();
-					glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight());
-				}
-				else
+				
 				{
-					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
-					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
-					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
-					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
-					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+					dst->bindTarget();
+					glViewport(0, 0, dst->getWidth(), dst->getHeight());
 				}
 
 				shader = &gDeferredDoFCombineProgram;
 				bindDeferredShader(*shader);
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
 				if (channel > -1)
 				{
-					mRT->screen.bindTexture(0, channel);
+					src->bindTexture(0, channel);
 				}
 
 				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
 				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-				shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth());
-				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight());
+				shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth());
+				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight());
 
 				mScreenTriangleVB->setBuffer();
 				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
 				unbindDeferredShader(*shader);
 
-				if (multisample)
 				{
-					mRT->deferredLight.flush();
+					dst->flush();
 				}
 			}
 		}
 		else
 		{
-			LL_PROFILE_GPU_ZONE("no dof");
-			if (multisample)
-			{
-				mRT->deferredLight.bindTarget();
-			}
-			LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
+			copyRenderTarget(src, dst);
+		}
+	}
+}
 
-			bindDeferredShader(*shader);
+void LLPipeline::renderFinalize()
+{
+    LLVertexBuffer::unbind();
+    LLGLState::checkStates();
 
-			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
-			if (channel > -1)
-			{
-				mRT->screen.bindTexture(0, channel);
-			}
+    assertInitialized();
 
-			mScreenTriangleVB->setBuffer();
-			mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+    LL_PROFILE_GPU_ZONE("renderFinalize");
 
-			unbindDeferredShader(*shader);
+    gGL.color4f(1, 1, 1, 1);
+    LLGLDepthTest depth(GL_FALSE);
+    LLGLDisable blend(GL_BLEND);
+    LLGLDisable cull(GL_CULL_FACE);
 
-			if (multisample)
-			{
-				mRT->deferredLight.flush();
-			}
-		}
-	}*/
+    enableLightsFullbright();
+
+    LLGLDisable test(GL_ALPHA_TEST);
+
+    gGL.setColorMask(true, true);
+    glClearColor(0, 0, 0, 0);
+
+    if (!gCubeSnapshot)
+    {
+
+		copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
+
+		generateLuminance(&mRT->screen, &mLuminanceMap);
+
+		generateExposure(&mLuminanceMap, &mExposureMap);
+
+		gammaCorrect(&mRT->screen, &mPostMap);
+
+        LLVertexBuffer::unbind();
+    }
+
+	renderGlow(&mPostMap, &mRT->screen);
+
+	renderDoF(&mRT->screen, &mPostMap);
 
-	applyFXAA(&mRT->screen, &mPostMap);
+	applyFXAA(&mPostMap, &mRT->screen);
 
 	// Present the screen target.
 
 	gDeferredPostNoDoFProgram.bind();
 
 	// Whatever is last in the above post processing chain should _always_ be rendered directly here.  If not, expect problems.
-	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage());
+	S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
 	if (channel > -1)
 	{
-		mPostMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+		mRT->screen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
 	}
 
 	{
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 3ed9ed73a8..3be908bdf7 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -141,6 +141,8 @@ public:
 	void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
 	void renderGlow(LLRenderTarget* src, LLRenderTarget* dst);
 	void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
+	void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
+	void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
 	void renderPostProcess();
 	LLRenderTarget* screenTarget();
 
-- 
cgit v1.2.3


From 56b21054eb974c21c31aed0b6239f5d1a24b467f Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Mon, 10 Apr 2023 11:29:50 -0700
Subject: Get DoF working

Need to fix up bloom.

DRTVWR-559
SL-19524
SL-19513
---
 indra/llrender/llglslshader.cpp |  4 ++--
 indra/newview/pipeline.cpp      | 28 ++++++++++++++--------------
 2 files changed, 16 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 61a17e5f52..8f06ef4a42 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -1091,7 +1091,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth,
 
     if (uniform < 0 || uniform >= (S32)mTexture.size())
     {
-        LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
+        //LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
         return -1;
     }
 
@@ -1099,7 +1099,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth,
 
     if (uniform > -1)
     {
-        gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(0));
+        gGL.getTexUnit(uniform)->bind(texture, depth);
 
 
         gGL.getTexUnit(uniform)->setTextureFilteringOption(mode);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 64f9c519d2..a6364ff092 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7426,27 +7426,27 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
 
 			{ // build diffuse+bloom+CoF
 				mRT->deferredLight.bindTarget();
-				shader = &gDeferredCoFProgram;
 
-				bindDeferredShader(*shader);
+				gDeferredCoFProgram.bind();
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
-				if (channel > -1)
-				{
-					src->bindTexture(0, channel);
-				}
+				S32 channel = gDeferredCoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+				gDeferredCoFProgram.bindTexture(channel, src);
 
-				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
-				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
-				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
-				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+				channel = gDeferredCoFProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mRT->deferredScreen.getUsage());
+				gDeferredCoFProgram.bindTexture(channel, &mRT->deferredScreen, true);
+
+				gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
 
 				mScreenTriangleVB->setBuffer();
 				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-				unbindDeferredShader(*shader);
+				gDeferredCoFProgram.unbind();
 				mRT->deferredLight.flush();
 			}
 
-- 
cgit v1.2.3


From d839bfe43a8a35c64906551c8ac7de3e42cd86f5 Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Wed, 12 Apr 2023 13:01:53 -0700
Subject: Combine glow in a separate shader.

DRTVWR-559
SL-19524
SL-19513
---
 indra/newview/pipeline.cpp | 51 +++++++++++++++++++++++++---------------------
 indra/newview/pipeline.h   |  1 +
 2 files changed, 29 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a6364ff092..572d388b15 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7193,25 +7193,6 @@ void LLPipeline::renderGlow(LLRenderTarget* src, LLRenderTarget* dst) {
 		mGlow[1].clear();
 		mGlow[1].flush();
 	}
-
-	// Go ahead and do our glow combine here in our destination.  We blit this later into the front buffer.
-
-	dst->bindTarget();
-
-	{
-		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
-
-		gGlowCombineProgram.bind();
-
-		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
-		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
-		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
-
-		mScreenTriangleVB->setBuffer();
-		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-	}
-
-	dst->flush();
 }
 
 void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
@@ -7288,6 +7269,8 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
 }
 
 void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
+
+	LL_PROFILE_GPU_ZONE("copyRenderTarget");
 	dst->bindTarget();
 
 	gDeferredPostNoDoFProgram.bind();
@@ -7309,6 +7292,27 @@ void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
 	dst->flush();
 }
 
+void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) {
+	// Go ahead and do our glow combine here in our destination.  We blit this later into the front buffer.
+
+	dst->bindTarget();
+
+	{
+		LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+		gGlowCombineProgram.bind();
+
+		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
+		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+		gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
+
+		mScreenTriangleVB->setBuffer();
+		mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+	}
+
+	dst->flush();
+}
+
 void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
 	{
 		bool dof_enabled =
@@ -7539,7 +7543,6 @@ void LLPipeline::renderFinalize()
 
     if (!gCubeSnapshot)
     {
-
 		copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
 
 		generateLuminance(&mRT->screen, &mLuminanceMap);
@@ -7551,11 +7554,13 @@ void LLPipeline::renderFinalize()
         LLVertexBuffer::unbind();
     }
 
-	renderGlow(&mPostMap, &mRT->screen);
+	renderGlow(&mPostMap, &mRT->screen); // We don't actually write to the screen buffer here.  Should probably pass in mGlow[2] as our destination.
+
+	renderDoF(&mPostMap, &mRT->screen);
 
-	renderDoF(&mRT->screen, &mPostMap);
+	applyFXAA(&mRT->screen, &mPostMap);
 
-	applyFXAA(&mPostMap, &mRT->screen);
+	combineGlow(&mPostMap, &mRT->screen);
 
 	// Present the screen target.
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 3be908bdf7..072ae2bf14 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -143,6 +143,7 @@ public:
 	void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
 	void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
 	void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
+	void combineGlow(LLRenderTarget* src, LLRenderTarget* dst);
 	void renderPostProcess();
 	LLRenderTarget* screenTarget();
 
-- 
cgit v1.2.3


From 58df456675f37146d9a6cdaaf75c0f2b93f234c6 Mon Sep 17 00:00:00 2001
From: "Jonathan \"Geenz\" Goodman" <geenz@geenzo.com>
Date: Wed, 12 Apr 2023 14:50:14 -0700
Subject: Fixed DoF

---
 indra/llrender/llglslshader.cpp |  1 -
 indra/newview/pipeline.cpp      | 71 +++++++++++++++++------------------------
 indra/newview/pipeline.h        |  2 +-
 3 files changed, 30 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 8f06ef4a42..d213aa05ed 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -1091,7 +1091,6 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth,
 
     if (uniform < 0 || uniform >= (S32)mTexture.size())
     {
-        //LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
         return -1;
     }
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 572d388b15..db477f64e3 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7098,7 +7098,7 @@ void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget*
 	}
 }
 
-void LLPipeline::renderGlow(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::generateGlow(LLRenderTarget* src) {
 	if (sRenderGlow)
 	{
 		LL_PROFILE_GPU_ZONE("glow");
@@ -7325,7 +7325,6 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
 		if (dof_enabled)
 		{
 			LL_PROFILE_GPU_ZONE("dof");
-			LLGLSLShader* shader = &gDeferredPostProgram;
 			LLGLDisable blend(GL_BLEND);
 
 			// depth of field focal plane calculations
@@ -7433,12 +7432,11 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
 
 				gDeferredCoFProgram.bind();
 
-				S32 channel = gDeferredCoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
-				gDeferredCoFProgram.bindTexture(channel, src);
-
-				channel = gDeferredCoFProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mRT->deferredScreen.getUsage());
-				gDeferredCoFProgram.bindTexture(channel, &mRT->deferredScreen, true);
+				gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+				gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
 
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
+				gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
 				gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
 				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
 				gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
@@ -7449,7 +7447,6 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
 
 				mScreenTriangleVB->setBuffer();
 				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
 				gDeferredCoFProgram.unbind();
 				mRT->deferredLight.flush();
 			}
@@ -7462,54 +7459,43 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
 				glViewport(0, 0, dof_width, dof_height);
 				gGL.setColorMask(true, false);
 
-				shader = &gDeferredPostProgram;
-				bindDeferredShader(*shader);
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
-				if (channel > -1)
-				{
-					mRT->deferredLight.bindTexture(0, channel);
-				}
+				gDeferredPostProgram.bind();
+				gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT);
 
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+				gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+				gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+				gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
 
 				mScreenTriangleVB->setBuffer();
 				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-				unbindDeferredShader(*shader);
+				gDeferredPostProgram.unbind();
+
 				src->flush();
 				gGL.setColorMask(true, true);
 			}
 
 			{ // combine result based on alpha
 				
-				{
-					dst->bindTarget();
-					glViewport(0, 0, dst->getWidth(), dst->getHeight());
-				}
+				dst->bindTarget();
+				glViewport(0, 0, dst->getWidth(), dst->getHeight());
 
-				shader = &gDeferredDoFCombineProgram;
-				bindDeferredShader(*shader);
+				gDeferredDoFCombineProgram.bind();	
+				gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+				gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT);
 
-				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
-				if (channel > -1)
-				{
-					src->bindTexture(0, channel);
-				}
-
-				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
-				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-				shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth());
-				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight());
+				gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth());
+				gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight());
 
 				mScreenTriangleVB->setBuffer();
 				mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
-				unbindDeferredShader(*shader);
+				gDeferredDoFCombineProgram.unbind();
 
-				{
-					dst->flush();
-				}
+				dst->flush();
 			}
 		}
 		else
@@ -7554,13 +7540,14 @@ void LLPipeline::renderFinalize()
         LLVertexBuffer::unbind();
     }
 
-	renderGlow(&mPostMap, &mRT->screen); // We don't actually write to the screen buffer here.  Should probably pass in mGlow[2] as our destination.
+	generateGlow(&mPostMap);
 
-	renderDoF(&mPostMap, &mRT->screen);
+	combineGlow(&mPostMap, &mRT->screen);
 
-	applyFXAA(&mRT->screen, &mPostMap);
+	renderDoF(&mRT->screen, &mPostMap);
+
+	applyFXAA(&mPostMap, &mRT->screen);
 
-	combineGlow(&mPostMap, &mRT->screen);
 
 	// Present the screen target.
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 072ae2bf14..ed9e2dc452 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -139,7 +139,7 @@ public:
 	void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
 	void generateExposure(LLRenderTarget* src, LLRenderTarget* dst);
 	void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
-	void renderGlow(LLRenderTarget* src, LLRenderTarget* dst);
+	void generateGlow(LLRenderTarget* src);
 	void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
 	void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
 	void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
-- 
cgit v1.2.3