summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llrender/llglslshader.cpp4
-rw-r--r--indra/llrender/llglslshader.h2
-rw-r--r--indra/llrender/llrender.h7
-rw-r--r--indra/llrender/llrendertarget.cpp15
-rw-r--r--indra/llrender/llrendertarget.h4
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl47
-rw-r--r--indra/newview/llviewershadermgr.cpp11
-rw-r--r--indra/newview/llviewershadermgr.h1
-rw-r--r--indra/newview/pipeline.cpp96
-rw-r--r--indra/newview/pipeline.h4
11 files changed, 137 insertions, 65 deletions
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index b12de563e4..04ac2476a7 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -1085,7 +1085,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextu
return uniform;
}
-S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth, LLTexUnit::eTextureFilterOptions mode)
+S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth, LLTexUnit::eTextureFilterOptions mode, U32 index)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -1103,7 +1103,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth,
}
else {
bool has_mips = mode == LLTexUnit::TFO_TRILINEAR || mode == LLTexUnit::TFO_ANISOTROPIC;
- gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(0), has_mips);
+ gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(index), has_mips);
}
gGL.getTexUnit(uniform)->setTextureFilteringOption(mode);
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 37f86acd4e..9d187c972c 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -244,7 +244,7 @@ public:
S32 bindTexture(const std::string& uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 bindTexture(const std::string& uniform, LLRenderTarget* texture, bool depth = false, LLTexUnit::eTextureFilterOptions mode = LLTexUnit::TFO_BILINEAR);
- S32 bindTexture(S32 uniform, LLRenderTarget* texture, bool depth = false, LLTexUnit::eTextureFilterOptions mode = LLTexUnit::TFO_BILINEAR);
+ S32 bindTexture(S32 uniform, LLRenderTarget* texture, bool depth = false, LLTexUnit::eTextureFilterOptions mode = LLTexUnit::TFO_BILINEAR, U32 index = 0);
S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 6f61627235..909a1de2b3 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -87,6 +87,13 @@ public:
TFO_ANISOTROPIC // Equal to: min=anisotropic, max=anisotropic, mip=linear.
} eTextureFilterOptions;
+ typedef enum
+ {
+ TMG_NONE = 0, // Mipmaps are not automatically generated for this texture.
+ TMG_AUTO, // Mipmaps are automatically generated for this texture.
+ TMG_MANUAL // Mipmaps are manually generated for this texture.
+ } eTextureMipGeneration;
+
typedef enum
{
TB_REPLACE = 0,
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 7f507a0b58..629664b76d 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -102,7 +102,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
}
-bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLTexUnit::eTextureType usage)
+bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLTexUnit::eTextureType usage, LLTexUnit::eTextureMipGeneration generateMipMaps)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
llassert(usage == LLTexUnit::TT_TEXTURE);
@@ -118,6 +118,13 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
mUsage = usage;
mUseDepth = depth;
+
+ mGenerateMipMaps = generateMipMaps;
+
+ if (mGenerateMipMaps != LLTexUnit::TMG_NONE) {
+ // Calculate the number of mip levels based upon resolution that we should have.
+ mMipLevels = 1 + floor(log10((float)llmax(mResX, mResY))/log10(2.0));
+ }
if (depth)
{
@@ -512,6 +519,12 @@ void LLRenderTarget::flush()
llassert(sCurFBO == mFBO);
llassert(sBoundTarget == this);
+ if (mGenerateMipMaps == LLTexUnit::TMG_AUTO) {
+ LL_PROFILE_GPU_ZONE("rt generate mipmaps");
+ bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+
if (mPreviousRT)
{
// a bit hacky -- pop the RT stack back two frames and push
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 71727bf09d..9fcea35e3d 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -80,7 +80,7 @@ public:
// color_fmt - GL color format (e.g. GL_RGB)
// depth - if true, allocate a depth buffer
// usage - deprecated, should always be TT_TEXTURE
- bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth = false, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE);
+ bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth = false, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureMipGeneration generateMipMaps = LLTexUnit::TMG_NONE);
//resize existing attachments to use new resolution and color format
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
@@ -179,6 +179,8 @@ protected:
U32 mDepth;
bool mUseDepth;
+ LLTexUnit::eTextureMipGeneration mGenerateMipMaps;
+ U32 mMipLevels;
LLTexUnit::eTextureType mUsage;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a057933009..b489e2eb77 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8942,6 +8942,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>RenderBufferVisualization</key>
+ <map>
+ <key>Comment</key>
+ <string>Outputs a selected buffer to the screen. -1 = final render buffer. 0 = Albedo, 1 = Specular/ORM, 2 = Normal, 3 = Emissive, 4 = Eye luminance</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>-1</integer>
+ </map>
<key>RenderCompressTextures</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl
new file mode 100644
index 0000000000..f75b8e2658
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl
@@ -0,0 +1,47 @@
+/**
+ * @file postDeferredNoDoFF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseRect;
+uniform float mipLevel;
+
+VARYING vec2 vary_fragcoord;
+
+void main()
+{
+ vec4 diff = textureLod(diffuseRect, vary_fragcoord.xy, mipLevel);
+
+ frag_color = diff;
+}
+
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index cc40028be8..63cc7ba623 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -205,6 +205,7 @@ LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskAlphaProgram;
LLGLSLShader gNormalMapGenProgram;
LLGLSLShader gDeferredGenBrdfLutProgram;
+LLGLSLShader gDeferredBufferVisualProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
@@ -1026,6 +1027,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gNormalMapGenProgram.unload();
gDeferredGenBrdfLutProgram.unload();
+ gDeferredBufferVisualProgram.unload();
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
@@ -2715,6 +2717,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gPostScreenSpaceReflectionProgram.createShader(NULL, NULL);
}
+ if (success) {
+ gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader";
+ gDeferredBufferVisualProgram.mShaderFiles.clear();
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredBufferVisualProgram.createShader(NULL, NULL);
+ }
+
return success;
}
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 0a23c33b78..129802aca5 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -265,6 +265,7 @@ extern LLGLSLShader gDeferredFullbrightShinyProgram;
extern LLGLSLShader gHUDFullbrightShinyProgram;
extern LLGLSLShader gNormalMapGenProgram;
extern LLGLSLShader gDeferredGenBrdfLutProgram;
+extern LLGLSLShader gDeferredBufferVisualProgram;
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dc500465e2..60d19bf1d6 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -190,6 +190,7 @@ F32 LLPipeline::CameraMaxCoF;
F32 LLPipeline::CameraDoFResScale;
F32 LLPipeline::RenderAutoHideSurfaceAreaLimit;
bool LLPipeline::RenderScreenSpaceReflections;
+S32 LLPipeline::RenderBufferVisualization;
LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
@@ -542,6 +543,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("CameraDoFResScale");
connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
connectRefreshCachedSettingsSafe("RenderScreenSpaceReflections");
+ connectRefreshCachedSettingsSafe("RenderBufferVisualization");
gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
}
@@ -1025,6 +1027,7 @@ void LLPipeline::refreshCachedSettings()
CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
RenderScreenSpaceReflections = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
+ RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization");
sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
RenderSpotLight = nullptr;
@@ -1267,7 +1270,7 @@ void LLPipeline::createLUTBuffers()
mExposureMap.clear();
mExposureMap.flush();
- mLuminanceMap.allocate(256, 256, GL_R16F);
+ mLuminanceMap.allocate(256, 256, GL_R16F, false, LLTexUnit::TT_TEXTURE, LLTexUnit::TMG_AUTO);
mLastExposure.allocate(1, 1, GL_R16F);
}
@@ -6909,58 +6912,21 @@ void LLPipeline::bindScreenToTexture()
static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
-void LLPipeline::renderPostProcess()
-{
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
-
- assertInitialized();
-
- LLVector2 tc1(0, 0);
- LLVector2 tc2((F32)mRT->screen.getWidth() * 2, (F32)mRT->screen.getHeight() * 2);
-
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
- LL_PROFILE_GPU_ZONE("renderPostProcess");
-
- 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);
-
- 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]);
-
- tc2.setVec((F32)mRT->screen.getWidth(), (F32)mRT->screen.getHeight());
-
- gGL.flush();
-
- LLVertexBuffer::unbind();
-
-
-}
-
-LLRenderTarget* LLPipeline::screenTarget() {
-
- bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
- (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField &&
- !gCubeSnapshot;
+void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex) {
+ dst->bindTarget();
+ gDeferredBufferVisualProgram.bind();
+ gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex);
- bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
+ static LLStaticHashedString mipLevel("mipLevel");
+ if (RenderBufferVisualization != 4)
+ gDeferredBufferVisualProgram.uniform1f(mipLevel, 0);
+ else
+ gDeferredBufferVisualProgram.uniform1f(mipLevel, 8);
- if (multisample || dof_enabled)
- return &mRT->deferredLight;
-
- return &mRT->screen;
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gDeferredBufferVisualProgram.unbind();
+ dst->flush();
}
void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) {
@@ -6991,9 +6957,6 @@ void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) {
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
dst->flush();
- dst->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();
@@ -7049,7 +7012,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
+ gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
gExposureProgram.unbind();
dst->flush();
}
@@ -7220,8 +7183,8 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
LLGLSLShader* shader = &gGlowCombineProgram;
- S32 width = screenTarget()->getWidth();
- S32 height = screenTarget()->getHeight();
+ S32 width = dst->getWidth();
+ S32 height = dst->getHeight();
// Present everything.
if (multisample)
@@ -7583,13 +7546,30 @@ void LLPipeline::renderFinalize()
renderDoF(&mRT->screen, &mPostMap);
applyFXAA(&mPostMap, &mRT->screen);
+ LLRenderTarget* finalBuffer = &mRT->screen;
+ if (RenderBufferVisualization > -1) {
+ finalBuffer = &mPostMap;
+ switch (RenderBufferVisualization)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization);
+ break;
+ case 4:
+ visualizeBuffers(&mLuminanceMap, finalBuffer, 0);
+ default:
+ break;
+ }
+ }
// 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.
- gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->screen);
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer);
gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
{
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index b8f8cf49df..a7ae290f9c 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -144,8 +144,7 @@ public:
void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
void combineGlow(LLRenderTarget* src, LLRenderTarget* dst);
- void renderPostProcess();
- LLRenderTarget* screenTarget();
+ void visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex);
void init();
void cleanup();
@@ -1024,6 +1023,7 @@ public:
static F32 CameraDoFResScale;
static F32 RenderAutoHideSurfaceAreaLimit;
static bool RenderScreenSpaceReflections;
+ static S32 RenderBufferVisualization;
};
void render_bbox(const LLVector3 &min, const LLVector3 &max);