diff options
author | Jonathan "Geenz" Goodman <geenz@lindenlab.com> | 2023-04-20 15:33:07 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-20 15:33:07 -0700 |
commit | d07eaf930269c71e0e3e19c8b61bcf0acbaa6fb6 (patch) | |
tree | ca8a7a04cc74f8f1c0722604a7d809f1be50a3c2 | |
parent | 4b224286fe97de7399d0b72066d7646c65faabb6 (diff) | |
parent | 972a85270f8806d6a094f87c3689303f8e2e8a84 (diff) |
Merge pull request #172 from secondlife/DRTVWR-583
Add buffer visulization
-rw-r--r-- | indra/llrender/llglslshader.cpp | 4 | ||||
-rw-r--r-- | indra/llrender/llglslshader.h | 2 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 7 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.cpp | 15 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.h | 4 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl | 47 | ||||
-rw-r--r-- | indra/newview/llviewershadermgr.cpp | 11 | ||||
-rw-r--r-- | indra/newview/llviewershadermgr.h | 1 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 96 | ||||
-rw-r--r-- | indra/newview/pipeline.h | 4 |
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); |