summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r--indra/newview/pipeline.cpp432
1 files changed, 369 insertions, 63 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index cda9fcad9e..91ade0eef1 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -29,6 +29,7 @@
#include "pipeline.h"
// library includes
+#include "llimagepng.h"
#include "llaudioengine.h" // For debugging.
#include "llerror.h"
#include "llviewercontrol.h"
@@ -117,6 +118,9 @@
#include "llenvironment.h"
#include "llsettingsvo.h"
+#include "SMAAAreaTex.h"
+#include "SMAASearchTex.h"
+
#ifndef LL_WINDOWS
#define A_GCC 1
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -135,7 +139,7 @@ bool gShiftFrame = false;
bool LLPipeline::WindLightUseAtmosShaders;
bool LLPipeline::RenderDeferred;
F32 LLPipeline::RenderDeferredSunWash;
-U32 LLPipeline::RenderFSAASamples;
+U32 LLPipeline::RenderFSAAType;
U32 LLPipeline::RenderResolutionDivisor;
bool LLPipeline::RenderUIBuffer;
S32 LLPipeline::RenderShadowDetail;
@@ -280,6 +284,7 @@ static LLStaticHashedString sDelta("delta");
static LLStaticHashedString sDistFactor("dist_factor");
static LLStaticHashedString sKern("kern");
static LLStaticHashedString sKernScale("kern_scale");
+static LLStaticHashedString sSmaaRTMetrics("SMAA_RT_METRICS");
//----------------------------------------
@@ -498,7 +503,7 @@ void LLPipeline::init()
// DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
// DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred");
connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
- connectRefreshCachedSettingsSafe("RenderFSAASamples");
+ connectRefreshCachedSettingsSafe("RenderFSAAType");
connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
connectRefreshCachedSettingsSafe("RenderUIBuffer");
connectRefreshCachedSettingsSafe("RenderShadowDetail");
@@ -736,40 +741,26 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
// refresh cached settings here to protect against inconsistent event handling order
refreshCachedSettings();
- U32 samples = RenderFSAASamples;
-
eFBOStatus ret = FBO_SUCCESS_FULLRES;
- if (!allocateScreenBuffer(resX, resY, samples))
+ if (!allocateScreenBufferInternal(resX, resY))
{
//failed to allocate at requested specification, return false
ret = FBO_FAILURE;
releaseScreenBuffers();
- //reduce number of samples
- while (samples > 0)
- {
- samples /= 2;
- if (allocateScreenBuffer(resX, resY, samples))
- { //success
- return FBO_SUCCESS_LOWRES;
- }
- releaseScreenBuffers();
- }
-
- samples = 0;
//reduce resolution
while (resY > 0 && resX > 0)
{
resY /= 2;
- if (allocateScreenBuffer(resX, resY, samples))
+ if (allocateScreenBufferInternal(resX, resY))
{
return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
resX /= 2;
- if (allocateScreenBuffer(resX, resY, samples))
+ if (allocateScreenBufferInternal(resX, resY))
{
return FBO_SUCCESS_LOWRES;
}
@@ -782,7 +773,7 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
return ret;
}
-bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
+bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (mRT == &mMainRT)
@@ -797,14 +788,14 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mRT = &mAuxillaryRT;
U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled
- allocateScreenBuffer(res, res, samples);
+ allocateScreenBufferInternal(res, res);
if (RenderMirrors)
{
mHeroProbeManager.initReflectionMaps();
res = mHeroProbeManager.mProbeResolution; // We also scale the hero probe RT to the probe res since we don't super sample it.
mRT = &mHeroProbeRT;
- allocateScreenBuffer(res, res, samples);
+ allocateScreenBufferInternal(res, res);
}
mRT = &mMainRT;
@@ -836,8 +827,8 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mRT->deferredScreen.shareDepthBuffer(mRT->screen);
- if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
- { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
+ if (shadow_detail > 0 || ssao || RenderDepthOfField)
+ { //only need mRT->deferredLight for shadows OR ssao OR dof
if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false;
}
else
@@ -857,13 +848,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
}
- if (samples > 0)
+ if (RenderFSAAType > 0)
{
if (!mFXAAMap.allocate(resX, resY, GL_RGBA)) return false;
+ if (RenderFSAAType == 2)
+ {
+ if (!mSMAABlendBuffer.allocate(resX, resY, GL_RGBA, false)) return false;
+ }
}
else
{
mFXAAMap.release();
+ mSMAABlendBuffer.release();
}
//water reflection texture (always needed as scratch space whether or not transparent water is enabled)
@@ -878,9 +874,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mSceneMap.release();
}
- const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR");
- const U32 post_color_fmt = post_hdr ? GL_RGBA16F : GL_RGBA;
- mPostMap.allocate(resX, resY, post_color_fmt);
+ mPostMap.allocate(resX, resY, GL_RGBA16F);
// used to scale down textures
// See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown
@@ -1015,7 +1009,7 @@ void LLPipeline::refreshCachedSettings()
WindLightUseAtmosShaders = true; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders");
RenderDeferred = true; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
- RenderFSAASamples = LLFeatureManager::getInstance()->isFeatureAvailable("RenderFSAASamples") ? gSavedSettings.getU32("RenderFSAASamples") : 0;
+ RenderFSAAType = gSavedSettings.getU32("RenderFSAAType");
RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
@@ -1119,6 +1113,18 @@ void LLPipeline::releaseGLBuffers()
mTrueNoiseMap = 0;
}
+ if (mSMAAAreaMap)
+ {
+ LLImageGL::deleteTextures(1, &mSMAAAreaMap);
+ mSMAAAreaMap = 0;
+ }
+
+ if (mSMAASearchMap)
+ {
+ LLImageGL::deleteTextures(1, &mSMAASearchMap);
+ mSMAASearchMap = 0;
+ }
+
releaseLUTBuffers();
mWaterDis.release();
@@ -1268,6 +1274,77 @@ void LLPipeline::createGLBuffers()
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
+ if (!mSMAAAreaMap)
+ {
+ std::vector<U8> tempBuffer(AREATEX_SIZE);
+ for (U32 y = 0; y < AREATEX_HEIGHT; y++)
+ {
+ U32 srcY = AREATEX_HEIGHT - 1 - y;
+ // unsigned int srcY = y;
+ memcpy(&tempBuffer[y * AREATEX_PITCH], areaTexBytes + srcY * AREATEX_PITCH, AREATEX_PITCH);
+ }
+
+ LLImageGL::generateTextures(1, &mSMAAAreaMap);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mSMAAAreaMap);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG,
+ GL_UNSIGNED_BYTE, tempBuffer.data(), false);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+
+ if (!mSMAASearchMap)
+ {
+ std::vector<U8> tempBuffer(SEARCHTEX_SIZE);
+ for (U32 y = 0; y < SEARCHTEX_HEIGHT; y++)
+ {
+ U32 srcY = SEARCHTEX_HEIGHT - 1 - y;
+ // unsigned int srcY = y;
+ memcpy(&tempBuffer[y * SEARCHTEX_PITCH], searchTexBytes + srcY * SEARCHTEX_PITCH, SEARCHTEX_PITCH);
+ }
+
+ LLImageGL::generateTextures(1, &mSMAASearchMap);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mSMAASearchMap);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT,
+ GL_RED, GL_UNSIGNED_BYTE, tempBuffer.data(), false);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+
+ if (!mSMAASampleMap)
+ {
+ LLPointer<LLImageRaw> raw_image = new LLImageRaw;
+ LLPointer<LLImagePNG> png_image = new LLImagePNG;
+ static LLCachedControl<std::string> sample_path(gSavedSettings, "SamplePath", "");
+ if (gDirUtilp->fileExists(sample_path()) && png_image->load(sample_path()) && png_image->decode(raw_image, 0.0f))
+ {
+ U32 format = 0;
+ switch (raw_image->getComponents())
+ {
+ case 1:
+ format = GL_RED;
+ break;
+ case 2:
+ format = GL_RG;
+ break;
+ case 3:
+ format = GL_RGB;
+ break;
+ case 4:
+ format = GL_RGBA;
+ break;
+ default:
+ return;
+ };
+ LLImageGL::generateTextures(1, &mSMAASampleMap);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mSMAASampleMap);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB, raw_image->getWidth(),
+ raw_image->getHeight(), format, GL_UNSIGNED_BYTE, raw_image->getData(), false);
+ stop_glerror();
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ }
+
createLUTBuffers();
gBumpImageList.restoreGL();
@@ -6975,11 +7052,12 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool
extern LLPointer<LLImageGL> gEXRImage;
-void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst)
+{
dst->bindTarget();
// gamma correct lighting
{
- LL_PROFILE_GPU_ZONE("gamma correct");
+ LL_PROFILE_GPU_ZONE("tonemap");
static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false);
@@ -6992,9 +7070,7 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable());
- LLGLSLShader& shader = no_post ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
- psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram :
- gDeferredPostGammaCorrectProgram;
+ LLGLSLShader& shader = no_post ? gNoPostTonemapProgram : gDeferredPostTonemapProgram;
shader.bind();
@@ -7025,6 +7101,34 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
dst->flush();
}
+void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ dst->bindTarget();
+ // gamma correct lighting
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false);
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ LLGLSLShader& shader = psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram :
+ gDeferredPostGammaCorrectProgram;
+
+ shader.bind();
+ shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
+ shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight());
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ shader.unbind();
+ }
+ dst->flush();
+}
+
void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst)
{
@@ -7211,18 +7315,19 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
{
{
llassert(!gCubeSnapshot);
- bool multisample = RenderFSAASamples > 1 && mFXAAMap.isComplete();
+ bool multisample = RenderFSAAType == 1 && mFXAAMap.isComplete();
LLGLSLShader* shader = &gGlowCombineProgram;
- S32 width = dst->getWidth();
- S32 height = dst->getHeight();
-
// Present everything.
if (multisample)
{
LL_PROFILE_GPU_ZONE("aa");
+ S32 width = dst->getWidth();
+ S32 height = dst->getHeight();
+
// bake out texture2D with RGBL for FXAA shader
mFXAAMap.bindTarget();
+ mFXAAMap.clear(GL_COLOR_BUFFER_BIT);
shader = &gGlowCombineFXAAProgram;
shader->bind();
@@ -7245,7 +7350,11 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
mFXAAMap.flush();
dst->bindTarget();
- shader = &gFXAAProgram;
+
+ static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U);
+ U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U);
+
+ shader = &gFXAAProgram[fsaa_quality];
shader->bind();
channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAAMap.getUsage());
@@ -7288,6 +7397,187 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
}
}
+void LLPipeline::generateSMAABuffers(LLRenderTarget* src)
+{
+ llassert(!gCubeSnapshot);
+ bool multisample = RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete();
+
+ // Present everything.
+ if (multisample)
+ {
+ LL_PROFILE_GPU_ZONE("aa");
+ static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U);
+ U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U);
+
+ S32 width = src->getWidth();
+ S32 height = src->getHeight();
+
+ float rt_metrics[] = { 1.f / width, 1.f / height, (float)width, (float)height };
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ static LLCachedControl<bool> use_sample(gSavedSettings, "RenderSMAAUseSample", false);
+ //static LLCachedControl<bool> use_stencil(gSavedSettings, "RenderSMAAUseStencil", true);
+ {
+ //LLGLState stencil(GL_STENCIL_TEST, use_stencil);
+
+ // Bind setup:
+ LLRenderTarget& dest = mFXAAMap;
+ LLGLSLShader& edge_shader = gSMAAEdgeDetectProgram[fsaa_quality];
+
+ dest.bindTarget();
+ dest.clear(GL_COLOR_BUFFER_BIT);
+
+ edge_shader.bind();
+ edge_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics);
+
+ S32 channel = edge_shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ if (channel > -1)
+ {
+ if (!use_sample)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ else
+ {
+ gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mSMAASampleMap);
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ }
+
+ //if (use_stencil)
+ //{
+ // glStencilFunc(GL_ALWAYS, 1, 0xFF);
+ // glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ // glStencilMask(0xFF);
+ //}
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ edge_shader.unbind();
+ dest.flush();
+
+ gGL.getTexUnit(channel)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+
+ {
+ //LLGLState stencil(GL_STENCIL_TEST, use_stencil);
+
+ // Bind setup:
+ LLRenderTarget& dest = mSMAABlendBuffer;
+ LLGLSLShader& blend_weights_shader = gSMAABlendWeightsProgram[fsaa_quality];
+
+ dest.bindTarget();
+ dest.clear(GL_COLOR_BUFFER_BIT);
+
+ blend_weights_shader.bind();
+ blend_weights_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics);
+
+ S32 edge_tex_channel = blend_weights_shader.enableTexture(LLShaderMgr::SMAA_EDGE_TEX, mFXAAMap.getUsage());
+ if (edge_tex_channel > -1)
+ {
+ mFXAAMap.bindTexture(0, edge_tex_channel, LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(edge_tex_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ S32 area_tex_channel = blend_weights_shader.enableTexture(LLShaderMgr::SMAA_AREA_TEX, LLTexUnit::TT_TEXTURE);
+ if (area_tex_channel > -1)
+ {
+ gGL.getTexUnit(area_tex_channel)->bindManual(LLTexUnit::TT_TEXTURE, mSMAAAreaMap);
+ gGL.getTexUnit(area_tex_channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(area_tex_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+ S32 search_tex_channel = blend_weights_shader.enableTexture(LLShaderMgr::SMAA_SEARCH_TEX, LLTexUnit::TT_TEXTURE);
+ if (search_tex_channel > -1)
+ {
+ gGL.getTexUnit(search_tex_channel)->bindManual(LLTexUnit::TT_TEXTURE, mSMAASearchMap);
+ gGL.getTexUnit(search_tex_channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(search_tex_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+
+ //if (use_stencil)
+ //{
+ // glStencilFunc(GL_EQUAL, 1, 0xFF);
+ // glStencilMask(0x00);
+ //}
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ //if (use_stencil)
+ //{
+ // glStencilFunc(GL_ALWAYS, 0, 0xFF);
+ //}
+ blend_weights_shader.unbind();
+ dest.flush();
+ gGL.getTexUnit(edge_tex_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(area_tex_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(search_tex_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+ }
+}
+
+void LLPipeline::applySMAA(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ llassert(!gCubeSnapshot);
+ bool multisample = RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete();
+
+ // Present everything.
+ if (multisample)
+ {
+ LL_PROFILE_GPU_ZONE("aa");
+ static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U);
+ U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U);
+
+ S32 width = src->getWidth();
+ S32 height = src->getHeight();
+
+ float rt_metrics[] = { 1.f / width, 1.f / height, (float)width, (float)height };
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ static LLCachedControl<bool> use_sample(gSavedSettings, "RenderSMAAUseSample", false);
+ //static LLCachedControl<bool> use_stencil(gSavedSettings, "RenderSMAAUseStencil", true);
+
+ {
+ //LLGLDisable stencil(GL_STENCIL_TEST);
+
+ // Bind setup:
+ LLRenderTarget* bound_target = dst;
+ LLGLSLShader& blend_shader = gSMAANeighborhoodBlendProgram[fsaa_quality];
+
+ bound_target->bindTarget();
+ bound_target->clear(GL_COLOR_BUFFER_BIT);
+
+ blend_shader.bind();
+ blend_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics);
+
+ S32 diffuse_channel = blend_shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
+ if(diffuse_channel > -1)
+ {
+ src->bindTexture(0, diffuse_channel, LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+
+ S32 blend_channel = blend_shader.enableTexture(LLShaderMgr::SMAA_BLEND_TEX);
+ if (blend_channel > -1)
+ {
+ mSMAABlendBuffer.bindTexture(0, blend_channel, LLTexUnit::TFO_BILINEAR);
+ }
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ bound_target->flush();
+ blend_shader.unbind();
+ gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(blend_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ else
+ {
+ copyRenderTarget(src, dst);
+ }
+}
+
void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst)
{
@@ -7496,18 +7786,7 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst)
{ // combine result based on alpha
dst->bindTarget();
- if (RenderFSAASamples > 1 && mFXAAMap.isComplete())
- {
- glViewport(0, 0, dst->getWidth(), dst->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]);
- }
+ glViewport(0, 0, dst->getWidth(), dst->getHeight());
gDeferredDoFCombineProgram.bind();
gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
@@ -7555,20 +7834,27 @@ void LLPipeline::renderFinalize()
gGL.setColorMask(true, true);
glClearColor(0, 0, 0, 0);
-
copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
generateLuminance(&mRT->screen, &mLuminanceMap);
generateExposure(&mLuminanceMap, &mExposureMap);
+ tonemap(&mRT->screen, &mPostMap);
+
+ applyCAS(&mPostMap, &mRT->screen);
+
+ generateSMAABuffers(&mRT->screen);
+
gammaCorrect(&mRT->screen, &mPostMap);
LLVertexBuffer::unbind();
- generateGlow(&mPostMap);
+ applySMAA(&mPostMap, &mRT->screen);
- combineGlow(&mPostMap, &mRT->screen);
+ generateGlow(&mRT->screen);
+
+ combineGlow(&mRT->screen, &mPostMap);
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
@@ -7576,15 +7862,19 @@ void LLPipeline::renderFinalize()
gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- applyCAS(&mRT->screen, &mPostMap);
-
renderDoF(&mPostMap, &mRT->screen);
- applyFXAA(&mRT->screen, &mPostMap);
- LLRenderTarget* finalBuffer = &mPostMap;
+ LLRenderTarget* finalBuffer = &mRT->screen;
+ static LLCachedControl<U32> aa_type(gSavedSettings, "RenderFSAAType", 2U);
+ if (RenderFSAAType == 1)
+ {
+ applyFXAA(&mRT->screen, &mPostMap);
+ finalBuffer = &mPostMap;
+ }
+
if (RenderBufferVisualization > -1)
{
- finalBuffer = &mRT->screen;
+ finalBuffer = &mPostMap;
switch (RenderBufferVisualization)
{
case 0:
@@ -7595,6 +7885,22 @@ void LLPipeline::renderFinalize()
break;
case 4:
visualizeBuffers(&mLuminanceMap, finalBuffer, 0);
+ case 5:
+ {
+ if (RenderFSAAType > 0)
+ {
+ visualizeBuffers(&mFXAAMap, finalBuffer, 0);
+ }
+ break;
+ }
+ case 6:
+ {
+ if (RenderFSAAType == 2)
+ {
+ visualizeBuffers(&mSMAABlendBuffer, finalBuffer, 0);
+ }
+ break;
+ }
default:
break;
}
@@ -7602,11 +7908,11 @@ void LLPipeline::renderFinalize()
// Present the screen target.
- gDeferredPostNoDoFProgram.bind();
+ gDeferredPostNoDoFNoiseProgram.bind(); // Add noise as part of final render to screen pass to avoid damaging other post effects
// Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems.
- gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer);
- gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+ gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer);
+ gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
{
LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
@@ -7614,7 +7920,7 @@ void LLPipeline::renderFinalize()
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
- gDeferredPostNoDoFProgram.unbind();
+ gDeferredPostNoDoFNoiseProgram.unbind();
gGL.setSceneBlendType(LLRender::BT_ALPHA);