diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 3ca1e021f7b988ef82c6bc23101bcc0ba7214ea2..e3084f4568a5d7c877203d97999d887e778c5a4c 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -246,7 +246,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 			return FALSE;
 		}
 	}
-
+#if !LL_DARWIN
 	if (features->hasLPM)
 	{
         if (!shader->attachFragmentObject("alchemy/LPMUtil.glsl"))
@@ -254,7 +254,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 			return FALSE;
 		}
 	}
-
+#endif
 	if (features->hasGamma || features->isDeferred)
 	{
         if (!shader->attachFragmentObject("windlight/gammaF.glsl"))
diff --git a/indra/newview/alrenderutils.cpp b/indra/newview/alrenderutils.cpp
index 89ca4e7f85975144639653eccc6880508b3e0388..69577ddbab27ae398a9eccb4f0c027ee96d6a504 100644
--- a/indra/newview/alrenderutils.cpp
+++ b/indra/newview/alrenderutils.cpp
@@ -43,6 +43,7 @@
 #include "llviewershadermgr.h"
 #include "pipeline.h"
 
+#if !LL_DARWIN
 uint32_t LPM_CONTROL_BLOCK[24 * 4] = {}; // Upload this to a uint4[24] part of a constant buffer (for example 'constant.lpm[24]').
 
 #ifndef LL_WINDOWS
@@ -52,6 +53,7 @@ uint32_t LPM_CONTROL_BLOCK[24 * 4] = {}; // Upload this to a uint4[24] part of a
 #define A_CPU 1
 #include "app_settings/shaders/class1/alchemy/LPMUtil.glsl"
 #include "app_settings/shaders/class1/alchemy/CASF.glsl"
+#endif
 
 const U32 ALRENDER_BUFFER_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
 
@@ -352,6 +354,7 @@ bool ALRenderUtil::setupTonemap()
 		mToneUnchartedParamB = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicShoulderLen"), gSavedSettings.getF32("AlchemyToneMapFilmicShoulderAngle"), gSavedSettings.getF32("AlchemyToneMapFilmicGamma"));
 		mToneUnchartedParamC = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicWhitePoint"), 2.0, 0.0);
 
+#if !LL_DARWIN
 		static LLCachedControl<F32> amd_hdrmax(gSavedSettings, "AlchemyToneMapAMDHDRMax", 256.f);
 		static LLCachedControl<F32> amd_exposure(gSavedSettings, "AlchemyToneMapAMDExposure", 8.0f);
 		static LLCachedControl<F32> amd_contrast(gSavedSettings, "AlchemyToneMapAMDContrast", 0.25f);
@@ -374,7 +377,7 @@ bool ALRenderUtil::setupTonemap()
 			amd_contrast, // contrast
 			amd_sh_contrast ? amd_sh_contrast_range : 1.0, // shoulder contrast
 			saturation, crosstalk);
-
+#endif
 	}
 	return true;
 }
@@ -384,7 +387,40 @@ void ALRenderUtil::renderTonemap(LLRenderTarget* src, LLRenderTarget* exposure,
 	dst->bindTarget();
 
 	static LLCachedControl<bool> no_post(gSavedSettings, "RenderDisablePostProcessing", false);
-	LLGLSLShader* tone_shader = no_post && gFloaterTools->isAvailable() ? &gDeferredPostTonemapProgram[0] : &gDeferredPostTonemapProgram[mTonemapType];
+	LLGLSLShader* tone_shader = nullptr;
+	if (no_post && gFloaterTools->isAvailable())
+	{
+		tone_shader = &gDeferredPostTonemapProgram;
+	}
+	else
+	{
+		switch (mTonemapType)
+		{
+		default:
+		case ALTonemap::TONEMAP_ACES_HILL:
+		{
+			tone_shader = &gDeferredPostTonemapACESProgram;
+			break;
+		}
+		case ALTonemap::TONEMAP_UCHIMURA:
+		{
+			tone_shader = &gDeferredPostTonemapUchiProgram;
+			break;
+		}
+#if !LL_DARWIN
+		case ALTonemap::TONEMAP_AMD:
+		{
+			tone_shader = &gDeferredPostTonemapLPMProgram;
+			break;
+		}
+#endif
+		case ALTonemap::TONEMAP_UNCHARTED:
+		{
+			tone_shader = &gDeferredPostTonemapHableProgram;
+			break;
+		}
+		}
+	}
 
 	tone_shader->bind();
 
@@ -404,6 +440,7 @@ void ALRenderUtil::renderTonemap(LLRenderTarget* src, LLRenderTarget* exposure,
 		tone_shader->uniform3fv(tone_uchimura_b, 1, mToneUchimuraParamB.mV);
 		break;
 	}
+#if !LL_DARWIN
 	case ALTonemap::TONEMAP_AMD:
 	{
 		static LLCachedControl<bool> amd_sh_contrast(gSavedSettings, "AlchemyToneMapAMDShoulderContrast", false);
@@ -411,6 +448,7 @@ void ALRenderUtil::renderTonemap(LLRenderTarget* src, LLRenderTarget* exposure,
 		tone_shader->uniform1i(tonemap_amd_params_shoulder, amd_sh_contrast);
 		break;
 	}
+#endif
 	case ALTonemap::TONEMAP_UNCHARTED:
 	{
 		tone_shader->uniform3fv(tone_uncharted_a, 1, mToneUnchartedParamA.mV);
@@ -685,11 +723,6 @@ bool ALRenderUtil::setupSharpen()
 		LLGLSLShader* sharpen_shader = nullptr;
 		switch (mSharpenMethod)
 		{
-		case ALSharpen::SHARPEN_CAS:
-		{
-			sharpen_shader = &gDeferredPostCASProgram;
-			break;
-		}
 		case ALSharpen::SHARPEN_DLS:
 		{
 			sharpen_shader = &gDeferredPostDLSProgram;
@@ -720,26 +753,34 @@ void ALRenderUtil::renderSharpen(LLRenderTarget* src, LLRenderTarget* dst)
 		return;
 	}
 
-	dst->bindTarget();
-
 	LLGLSLShader* sharpen_shader = nullptr;
 	switch (mSharpenMethod)
 	{
+#if !LL_DARWIN
 	case ALSharpen::SHARPEN_CAS:
 	{
 		sharpen_shader = &gDeferredPostCASProgram;
 		break;
 	}
+#endif
 	case ALSharpen::SHARPEN_DLS:
+	{
 		sharpen_shader = &gDeferredPostDLSProgram;
 		break;
+	}
 	default:
 	case ALSharpen::SHARPEN_NONE:
-		break;
+	{
+		gPipeline.copyRenderTarget(src, dst);
+		return;
+	}
 	}
 
 	// Bind setup:
+	dst->bindTarget();
+
 	sharpen_shader->bind();
+#if !LL_DARWIN
 	if (mSharpenMethod == ALSharpen::SHARPEN_CAS)
 	{
 		static LLCachedControl<F32> cas_sharpness(gSavedSettings, "RenderSharpenCASSharpness", 0.6f);
@@ -759,6 +800,7 @@ void ALRenderUtil::renderSharpen(LLRenderTarget* src, LLRenderTarget* dst)
 		
 		sharpen_shader->uniform2f(out_screen_res, dst->getWidth(), dst->getHeight());
 	}
+#endif
 
 	sharpen_shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
 
diff --git a/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl b/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl
index 80fa8f3d4d55a34d95d98459a1e9a5bf7b11f808..5f266c2901cb5988372fcf37aec07bc1c6dea1b8 100644
--- a/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl
+++ b/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl
@@ -34,7 +34,10 @@ uniform float exposure;
 
 vec3 srgb_to_linear(vec3 cl);
 vec3 linear_to_srgb(vec3 cl);
+
+#if TONEMAP_METHOD == 3
 void RunLPMFilter(inout vec3 diff);
+#endif
 
 // ACES filmic tone map approximation
 // see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
@@ -149,8 +152,7 @@ void main()
 #elif TONEMAP_METHOD == 2 // Uchimura's Gran Turismo method
     diff.rgb = uchimura(diff.rgb);
 #elif TONEMAP_METHOD == 3 // AMD Tonemapper
-    RunLPMFilter(diff.rgb);// LpmFilter(diff.r,diff.g,diff.b,false,LPM_CONFIG_709_709); // <-- Using the LPM_CONFIG_ prefab to make inputs easier.
-    //diff.rgb = AMDTonemapper(diff.rgb);
+    RunLPMFilter(diff.rgb);
 #elif TONEMAP_METHOD == 4 // Uncharted
     diff.rgb = uncharted2(diff.rgb);
 #endif
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 7c73cb1a3e9f31428cc96f44ecf0314b40389219..2de9c12f28477f1c36fc7b0a45143a9ef21dbbf6 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -212,7 +212,11 @@ LLGLSLShader            gDeferredGenBrdfLutProgram;
 LLGLSLShader            gDeferredBufferVisualProgram;
 LLGLSLShader            gDeferredPostCASProgram;
 LLGLSLShader			gDeferredPostDLSProgram;
-LLGLSLShader			gDeferredPostTonemapProgram[ALRenderUtil::TONEMAP_COUNT];
+LLGLSLShader			gDeferredPostTonemapProgram;
+LLGLSLShader			gDeferredPostTonemapACESProgram;
+LLGLSLShader			gDeferredPostTonemapUchiProgram;
+LLGLSLShader			gDeferredPostTonemapLPMProgram;
+LLGLSLShader			gDeferredPostTonemapHableProgram;
 LLGLSLShader			gDeferredPostColorCorrectProgram[3];
 LLGLSLShader			gDeferredPostColorCorrectLUTProgram[3];
 // [RLVa:KB] - @setsphere
@@ -589,10 +593,11 @@ void LLViewerShaderMgr::unloadShaders()
 	
 	gDeferredPostCASProgram.unload();
 	gDeferredPostDLSProgram.unload();
-	for (U32 i = 0; i < ALRenderUtil::TONEMAP_COUNT; ++i)
-	{
-		gDeferredPostTonemapProgram[i].unload();
-	}
+	gDeferredPostTonemapProgram.unload();
+	gDeferredPostTonemapACESProgram.unload();
+	gDeferredPostTonemapUchiProgram.unload();
+	gDeferredPostTonemapLPMProgram.unload();
+	gDeferredPostTonemapHableProgram.unload();
 
 	for (U32 i = 0; i < 3; ++i)
 	{
@@ -763,7 +768,9 @@ std::string LLViewerShaderMgr::loadBasicShaders()
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/deferredUtil.glsl",                    1) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/shadowUtil.glsl",                      1) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/aoUtil.glsl",                          1) );
+#if !LL_DARWIN
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "alchemy/LPMUtil.glsl",                    1) );
+#endif
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl",                has_reflection_probes ? 3 : 2) );
     index_channels.push_back(-1);    shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl",             ssr ? 3 : 1) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",                    mShaderLevel[SHADER_LIGHTING] ) );
@@ -1071,10 +1078,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 
 		gDeferredPostCASProgram.unload();
 		gDeferredPostDLSProgram.unload();
-		for (U32 i = 0; i < ALRenderUtil::TONEMAP_COUNT; ++i)
-		{
-			gDeferredPostTonemapProgram[i].unload();
-		}
+		gDeferredPostTonemapProgram.unload();
+		gDeferredPostTonemapACESProgram.unload();
+		gDeferredPostTonemapUchiProgram.unload();
+		gDeferredPostTonemapLPMProgram.unload();
+		gDeferredPostTonemapHableProgram.unload();
 		for (U32 i = 0; i < 3; ++i)
 		{
 			gDeferredPostColorCorrectProgram[i].unload();
@@ -2907,6 +2915,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredBufferVisualProgram.createShader(NULL, NULL);
 	}
 
+#if !LL_DARWIN
 	if (success)
 	{
 		gDeferredPostCASProgram.mName = "Contrast Adaptive Sharpen Shader";
@@ -2917,6 +2926,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredPostCASProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
 		success = gDeferredPostCASProgram.createShader(NULL, NULL);
 	}
+#endif
 
 	if (success)
 	{
@@ -2929,23 +2939,76 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredPostDLSProgram.createShader(NULL, NULL);
 	}
 
-	for (U32 i = 0; i < ALRenderUtil::TONEMAP_COUNT; ++i)
+	if (success)
+	{
+		gDeferredPostTonemapProgram.mName = "Tonemapping Shader None";
+		gDeferredPostTonemapProgram.mFeatures.hasSrgb = true;
+		gDeferredPostTonemapProgram.mFeatures.hasLPM = false;
+		gDeferredPostTonemapProgram.mShaderFiles.clear();
+		gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
+		gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
+		gDeferredPostTonemapProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+		gDeferredPostTonemapProgram.clearPermutations();
+		gDeferredPostTonemapProgram.addPermutation("TONEMAP_METHOD", std::to_string(ALRenderUtil::TONEMAP_NONE));
+		success = gDeferredPostTonemapProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
 	{
-		if (success)
-		{
-			gDeferredPostTonemapProgram[i].mName = "Tonemapping Shader " + std::to_string(i);
-			gDeferredPostTonemapProgram[i].mFeatures.hasSrgb = true;
-			gDeferredPostTonemapProgram[i].mFeatures.hasLPM = true;
-			gDeferredPostTonemapProgram[i].mShaderFiles.clear();
-			gDeferredPostTonemapProgram[i].mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
-			gDeferredPostTonemapProgram[i].mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
-			gDeferredPostTonemapProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
-			gDeferredPostTonemapProgram[i].clearPermutations();
-			gDeferredPostTonemapProgram[i].addPermutation("TONEMAP_METHOD", std::to_string(i));
-
-			success = gDeferredPostTonemapProgram[i].createShader(NULL, NULL);
-		}
+		gDeferredPostTonemapACESProgram.mName = "Tonemapping Shader ACES";
+		gDeferredPostTonemapACESProgram.mFeatures.hasSrgb = true;
+		gDeferredPostTonemapACESProgram.mFeatures.hasLPM = false;
+		gDeferredPostTonemapACESProgram.mShaderFiles.clear();
+		gDeferredPostTonemapACESProgram.mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
+		gDeferredPostTonemapACESProgram.mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
+		gDeferredPostTonemapACESProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+		gDeferredPostTonemapACESProgram.clearPermutations();
+		gDeferredPostTonemapACESProgram.addPermutation("TONEMAP_METHOD", std::to_string(ALRenderUtil::TONEMAP_ACES_HILL));
+		success = gDeferredPostTonemapACESProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gDeferredPostTonemapUchiProgram.mName = "Tonemapping Shader Uchimura";
+		gDeferredPostTonemapUchiProgram.mFeatures.hasSrgb = true;
+		gDeferredPostTonemapUchiProgram.mFeatures.hasLPM = false;
+		gDeferredPostTonemapUchiProgram.mShaderFiles.clear();
+		gDeferredPostTonemapUchiProgram.mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
+		gDeferredPostTonemapUchiProgram.mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
+		gDeferredPostTonemapUchiProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+		gDeferredPostTonemapUchiProgram.clearPermutations();
+		gDeferredPostTonemapUchiProgram.addPermutation("TONEMAP_METHOD", std::to_string(ALRenderUtil::TONEMAP_UCHIMURA));
+		success = gDeferredPostTonemapUchiProgram.createShader(NULL, NULL);
+	}
+
+#if !LL_DARWIN
+	if (success)
+	{
+		gDeferredPostTonemapLPMProgram.mName = "Tonemapping Shader LPM";
+		gDeferredPostTonemapLPMProgram.mFeatures.hasSrgb = true;
+		gDeferredPostTonemapLPMProgram.mFeatures.hasLPM = true;
+		gDeferredPostTonemapLPMProgram.mShaderFiles.clear();
+		gDeferredPostTonemapLPMProgram.mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
+		gDeferredPostTonemapLPMProgram.mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
+		gDeferredPostTonemapLPMProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+		gDeferredPostTonemapLPMProgram.clearPermutations();
+		gDeferredPostTonemapLPMProgram.addPermutation("TONEMAP_METHOD", std::to_string(ALRenderUtil::TONEMAP_AMD));
+		success = gDeferredPostTonemapLPMProgram.createShader(NULL, NULL);
+	}
+#endif
+
+	if (success)
+	{
+		gDeferredPostTonemapHableProgram.mName = "Tonemapping Shader Uncharted";
+		gDeferredPostTonemapHableProgram.mFeatures.hasSrgb = true;
+		gDeferredPostTonemapHableProgram.mFeatures.hasLPM = false;
+		gDeferredPostTonemapHableProgram.mShaderFiles.clear();
+		gDeferredPostTonemapHableProgram.mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
+		gDeferredPostTonemapHableProgram.mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
+		gDeferredPostTonemapHableProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+		gDeferredPostTonemapHableProgram.clearPermutations();
+		gDeferredPostTonemapHableProgram.addPermutation("TONEMAP_METHOD", std::to_string(ALRenderUtil::TONEMAP_UNCHARTED));
+		success = gDeferredPostTonemapHableProgram.createShader(NULL, NULL);
 	}
 
 	if (success)
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 78cad4d998997059124454d8af191b99d86e9f90..90cff9f97b00598923b51e253de8e81129972230 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -276,7 +276,11 @@ extern LLGLSLShader         gDeferredGenBrdfLutProgram;
 extern LLGLSLShader			gDeferredBufferVisualProgram;
 extern LLGLSLShader         gDeferredPostCASProgram;
 extern LLGLSLShader			gDeferredPostDLSProgram;
-extern LLGLSLShader			gDeferredPostTonemapProgram[ALRenderUtil::TONEMAP_COUNT];
+extern LLGLSLShader			gDeferredPostTonemapProgram;
+extern LLGLSLShader			gDeferredPostTonemapACESProgram;
+extern LLGLSLShader			gDeferredPostTonemapUchiProgram;
+extern LLGLSLShader			gDeferredPostTonemapLPMProgram;
+extern LLGLSLShader			gDeferredPostTonemapHableProgram;
 extern LLGLSLShader			gDeferredPostColorCorrectProgram[3];
 extern LLGLSLShader			gDeferredPostColorCorrectLUTProgram[3];
 // [RLVa:KB] - @setsphere