diff options
Diffstat (limited to 'indra/newview/llreflectionmapmanager.cpp')
| -rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 319 | 
1 files changed, 235 insertions, 84 deletions
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index c6fa64753c..aa48035aa8 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -54,6 +54,7 @@  #endif  LLPointer<LLImageGL> gEXRImage; +//LLTrace::BlockTimerStatHandle FTM_RENDER_RADIANCE("Render Radiance");  void load_exr(const std::string& filename)  { @@ -223,6 +224,24 @@ void LLReflectionMapManager::update()          resume();      } +    static LLCachedControl<F32> sProbeUpdateSlowDown(gSavedSettings, "MPRenderProbeSlowDown", 0.05); + +    bool realtime = mRenderReflectionProbeDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; + +    if(sProbeUpdateSlowDown > 0.0) +    { +        if ( mLastUpdate > 0.f ) +        { +            F32 elapsed = gFrameTimeSeconds - mLastUpdate; +            if (elapsed > 0.0 && elapsed < sProbeUpdateSlowDown) +            { +                return; +            } +        } +    } + +    mLastUpdate = gFrameTimeSeconds; +      mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f);      { @@ -271,10 +290,17 @@ void LLReflectionMapManager::update()      initReflectionMaps();      static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); +    static LLCachedControl<U32> MPColorPrecision(gSavedSettings, "MPColorPrecision", 0); + +    U32 color_fmt = render_hdr ? GL_R11F_G11F_B10F : GL_RGB8; + +    if(MPColorPrecision == 1) +    { +        color_fmt = GL_RGB8; +    }      if (!mRenderTarget.isComplete())      { -        U32 color_fmt = render_hdr ? GL_R11F_G11F_B10F : GL_RGB8;          U32 targetRes = mProbeResolution * 4; // super sample          mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);      } @@ -287,7 +313,7 @@ void LLReflectionMapManager::update()          mMipChain.resize(count);          for (U32 i = 0; i < count; ++i)          { -            mMipChain[i].allocate(res, res, render_hdr ? GL_R11F_G11F_B10F : GL_RGB8); +            mMipChain[i].allocate(res, res, color_fmt);              res /= 2;          }      } @@ -325,8 +351,6 @@ void LLReflectionMapManager::update()      bool did_update = false; -    bool realtime = mRenderReflectionProbeDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; -      LLReflectionMap* closestDynamic = nullptr;      LLReflectionMap* oldestProbe = nullptr; @@ -359,6 +383,9 @@ void LLReflectionMapManager::update()              probe->mCubeArray = nullptr;              probe->mCubeIndex = -1;              probe->mComplete = false; +            probe->mCompletedCount = 0; +            probe->mLastUpdateTime = 0.0; +            probe->mNextUpdateTime = 0.0;              probe->mFadeIn = 0;          }      } @@ -382,6 +409,8 @@ void LLReflectionMapManager::update()      mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); +    static LLCachedControl<F32> sDefaultUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.0); +      for (unsigned int i = 0; i < mProbes.size(); ++i)      {          LLReflectionMap* probe = mProbes[i]; @@ -398,6 +427,8 @@ void LLReflectionMapManager::update()              continue;          } +        // Calculating distance +          LLVector4a d;          if (probe != mDefaultProbe) @@ -409,13 +440,14 @@ void LLReflectionMapManager::update()              d.setSub(camera_pos, probe->mOrigin);              probe->mDistance = d.getLength3().getF32() - probe->mRadius;          } -        else if (probe->mComplete) +        else if (mDefaultProbe->mComplete)          {              // make default probe have a distance of 64m for the purposes of prioritization (if it's already been generated once)              probe->mDistance = 64.f;          }          else          { +            probe->mNextUpdateTime = 0.f;              probe->mDistance = -4096.f; //boost priority of default probe when it's not complete          } @@ -424,8 +456,13 @@ void LLReflectionMapManager::update()              probe->autoAdjustOrigin();              probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f);          } + +        // Guess oldest probe +          if (probe->mOccluded && probe->mComplete)          { +            // occluded probe +              if (oldestOccluded == nullptr)              {                  oldestOccluded = probe; @@ -462,6 +499,8 @@ void LLReflectionMapManager::update()          }      } +    // realtime +      if (realtime && closestDynamic != nullptr)      {          LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime"); @@ -477,15 +516,17 @@ void LLReflectionMapManager::update()          {              updateProbeFace(closestDynamic, i);          } +        if(mRealtimeRadiancePass) updateProbeRadiance(closestDynamic); +        else updateProbeIrradiance(closestDynamic);          mRealtimeRadiancePass = !mRealtimeRadiancePass;          // restore "isRadiancePass"          mRadiancePass = radiance_pass;      } -    static LLCachedControl<F32> sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); -    if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) +    if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sDefaultUpdatePeriod)      { +//      if (sLevel == 0 && mDefaultProbe->mComplete)          if (mRenderReflectionProbeLevel == 0)          { // when probes are disabled don't update the default probe more often than the prescribed update period              oldestProbe = nullptr; @@ -502,11 +543,21 @@ void LLReflectionMapManager::update()          LLReflectionMap* probe = oldestProbe;          llassert(probe->mCubeIndex != -1); +        bool shouldUpdate = true; + +        if( probe->mNextUpdateTime > 0.f && gFrameTimeSeconds < probe->mNextUpdateTime) +        { +            shouldUpdate = false; +        } + +        if(shouldUpdate) +        {          probe->autoAdjustOrigin();          sUpdateCount++;          mUpdatingProbe = probe;          doProbeUpdate(); +        }      }      if (oldestOccluded) @@ -722,11 +773,19 @@ void LLReflectionMapManager::doProbeUpdate()      LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;      llassert(mUpdatingProbe != nullptr); -    updateProbeFace(mUpdatingProbe, mUpdatingFace); +    if(mUpdatingFace < 6) +    { +        updateProbeFace(mUpdatingProbe, mUpdatingFace); +    } +    else +    { +        if(isRadiancePass()) updateProbeRadiance(mUpdatingProbe); +        else updateProbeIrradiance(mUpdatingProbe); +    }      bool debug_updates = gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PROBE_UPDATES) && mUpdatingProbe->mViewerObject; -    if (++mUpdatingFace == 6) +    if (mUpdatingFace == 6)      {          if (debug_updates)          { @@ -736,7 +795,23 @@ void LLReflectionMapManager::doProbeUpdate()          mUpdatingFace = 0;          if (isRadiancePass())          { +            static LLCachedControl<F32> sMPUpdatePeriod(gSavedSettings, "MPRenderProbeUpdatePeriod", 15.0); +              mUpdatingProbe->mComplete = true; +            mUpdatingProbe->mCompletedCount++; + +            LL_WARNS() << "Probe updated (" << mUpdatingProbe->mCompletedCount << ")" << LL_ENDL; + +            if(mUpdatingProbe->mCompletedCount < 5) +            { +                //probe->mNextUpdateTime = gFrameTimeSeconds + fmax( ((F32)sMPUpdatePeriod / 2.0), 0.25); +                mUpdatingProbe->mNextUpdateTime = gFrameTimeSeconds + 1.0; +            } +            else +            { +                mUpdatingProbe->mNextUpdateTime = gFrameTimeSeconds + fmax( (F32)sMPUpdatePeriod, 0.10); +            } +              mUpdatingProbe = nullptr;              mRadiancePass = false;          } @@ -745,9 +820,14 @@ void LLReflectionMapManager::doProbeUpdate()              mRadiancePass = true;          }      } -    else if (debug_updates) +    else      { +        ++mUpdatingFace; + +        if (debug_updates) +        {          mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 0, 1)); +        }      }  } @@ -802,7 +882,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)          sourceIdx += 1;      } -    gGL.setColorMask(true, true); +    gGL.setColorMask(true, false);      LLGLDepthTest depth(GL_FALSE, GL_FALSE);      LLGLDisable cull(GL_CULL_FACE);      LLGLDisable blend(GL_BLEND); @@ -836,7 +916,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)              // horizontal              gGaussianProgram.uniform2f(direction, 1.f, 0.f);              gGL.getTexUnit(diffuseChannel)->bind(screen_rt); -            mRenderTarget.bindTarget(); +            mRenderTarget.bindTarget("", 1); +            mRenderTarget.clear(0);              gPipeline.mScreenTriangleVB->setBuffer();              gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);              mRenderTarget.flush(); @@ -844,7 +925,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)              // vertical              gGaussianProgram.uniform2f(direction, 0.f, 1.f);              gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget); -            screen_rt->bindTarget(); +            screen_rt->bindTarget("", 1); +            screen_rt->clear(0);              gPipeline.mScreenTriangleVB->setBuffer();              gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);              screen_rt->flush(); @@ -859,7 +941,10 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)          for (int i = 0; i < mMipChain.size(); ++i)          {              LL_PROFILE_GPU_ZONE("probe mip"); -            mMipChain[i].bindTarget(); + +            mMipChain[i].bindTarget("probe face ", 0); +            mMipChain[i].clear(0); +              if (i == 0)              {                  gGL.getTexUnit(diffuseChannel)->bind(screen_rt); @@ -884,7 +969,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)                  LL_PROFILE_GPU_ZONE("probe mip copy");                  mTexture->bind(0);                  //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); +#if GL_VERSION_4_0                  glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); +#endif                  //if (i == 0)                  //{                      //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); @@ -901,39 +988,139 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)          gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE);          gReflectionMipProgram.unbind();      } +} -    if (face == 5) -    { -        mMipChain[0].bindTarget(); -        static LLStaticHashedString sSourceIdx("sourceIdx"); +// ===================== IRRADIANCE ================================ -        if (isRadiancePass()) +void LLReflectionMapManager::updateProbeIrradiance(LLReflectionMap* probe) +{ +    LL_PROFILE_GPU_ZONE("probe irradiance gen"); + +    static LLStaticHashedString sMipLevel("mipLevel"); +    static LLStaticHashedString sRoughness("roughness"); +    static LLStaticHashedString sWidth("u_width"); + +    S32 sourceIdx = mReflectionProbeCount; + +    if (probe != mUpdatingProbe) +    { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel +        sourceIdx += 1; +    } + +    gGL.setColorMask(true, false); +    LLGLDepthTest depth(GL_FALSE, GL_FALSE); +    LLGLDisable cull(GL_CULL_FACE); +    LLGLDisable blend(GL_BLEND); + +    static LLStaticHashedString sSourceIdx("sourceIdx"); + + +    mMipChain[0].bindTarget("irradiance", 0); +    mMipChain[0].clear(); + +    gIrradianceGenProgram.bind(); + +#if GL_VERSION_4_0 +    S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); +    mTexture->bind(channel); +#endif + +    gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); +    gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); + +    mVertexBuffer->setBuffer(); + +    int start_mip = 0; +    // find the mip target to start with based on irradiance map resolution +    for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) +    { +        if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION)          { -            //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map) -            gRadianceGenProgram.bind(); -            mVertexBuffer->setBuffer(); +            break; +        } +    } + +    int i = start_mip; + +    //LL_PROFILE_GPU_ZONE("probe irradiance gen"); + +    glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); + +    for (int cf = 0; cf < 6; ++cf) +    { +        LLCoordFrame frame; +        frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); + +        F32 mat[16]; +        frame.getOpenGLRotation(mat); +        gGL.loadMatrix(mat); + +        mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); + +        S32 res = mMipChain[i].getWidth(); +#if GL_VERSION_4_0 +        mIrradianceMaps->bind(channel); +        glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); +        mTexture->bind(channel); +#endif +        //mMipChain[0].clear(0); +    } + +    mMipChain[0].flush(); +    gIrradianceGenProgram.unbind(); +} + +// ==================== RADIANCE =========================== + +void LLReflectionMapManager::updateProbeRadiance(LLReflectionMap* probe) +{ +    LL_PROFILE_GPU_ZONE("probe radiance gen"); +    static LLStaticHashedString sMipLevel("mipLevel"); +    static LLStaticHashedString sRoughness("roughness"); +    static LLStaticHashedString sWidth("u_width"); + +    S32 sourceIdx = mReflectionProbeCount; + +    if (probe != mUpdatingProbe) +    { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel +        sourceIdx += 1; +    } +    gGL.setColorMask(true, false); +    LLGLDepthTest depth(GL_FALSE, GL_FALSE); +    LLGLDisable cull(GL_CULL_FACE); +    LLGLDisable blend(GL_BLEND); + +    static LLStaticHashedString sSourceIdx("sourceIdx"); + +    //LL_RECORD_BLOCK_TIME(FTM_RENDER_RADIANCE); + +    mMipChain[0].bindTarget("radiance", 0); +    mMipChain[0].clear(); + +    gRadianceGenProgram.bind(); +    mVertexBuffer->setBuffer(); + +#if GL_VERSION_4_0              S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);              mTexture->bind(channel); +#endif              gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx);              gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);              gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_STRENGTH, 1.f); +            gRadianceGenProgram.uniform1i(sWidth, mProbeResolution);              U32 res = mMipChain[0].getWidth();              for (int i = 0; i < mMipChain.size(); ++i)              { -                LL_PROFILE_GPU_ZONE("probe radiance gen"); -                static LLStaticHashedString sMipLevel("mipLevel"); -                static LLStaticHashedString sRoughness("roughness"); -                static LLStaticHashedString sWidth("u_width"); +                glViewport(0, 0, res, res); -                gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));                  gRadianceGenProgram.uniform1f(sMipLevel, (GLfloat)i); -                gRadianceGenProgram.uniform1i(sWidth, mProbeResolution); +                gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));                  for (int cf = 0; cf < 6; ++cf) -                { // for each cube face +                {                      LLCoordFrame frame;                      frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); @@ -943,67 +1130,21 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)                      mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); +#if GL_VERSION_4_0                      glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); +#endif +                    LOG_GLERROR("glCopyTexSubImage3D");                  }                  if (i != mMipChain.size() - 1)                  {                      res /= 2; -                    glViewport(0, 0, res, res);                  } -            } +    }              gRadianceGenProgram.unbind(); -        } -        else -        { -            //generate irradiance map -            gIrradianceGenProgram.bind(); -            S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); -            mTexture->bind(channel); - -            gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); -            gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); - -            mVertexBuffer->setBuffer(); -            int start_mip = 0; -            // find the mip target to start with based on irradiance map resolution -            for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) -            { -                if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION) -                { -                    break; -                } -            } - -            //for (int i = start_mip; i < mMipChain.size(); ++i) -            { -                int i = start_mip; -                LL_PROFILE_GPU_ZONE("probe irradiance gen"); -                glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); -                for (int cf = 0; cf < 6; ++cf) -                { // for each cube face -                    LLCoordFrame frame; -                    frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]); - -                    F32 mat[16]; -                    frame.getOpenGLRotation(mat); -                    gGL.loadMatrix(mat); - -                    mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4); - -                    S32 res = mMipChain[i].getWidth(); -                    mIrradianceMaps->bind(channel); -                    glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); -                    mTexture->bind(channel); -                } -            } - -            gIrradianceGenProgram.unbind(); -        } - -        mMipChain[0].flush(); -    } +    mMipChain[0].flush(); +    //mTexture->unbind();  }  void LLReflectionMapManager::reset() @@ -1424,8 +1565,13 @@ void LLReflectionMapManager::initReflectionMaps()  {      static LLCachedControl<U32> ref_probe_res(gSavedSettings, "RenderReflectionProbeResolution", 128U);      U32 probe_resolution = nhpo2(llclamp(ref_probe_res(), (U32)64, (U32)512)); -    if (mTexture.isNull() || mReflectionProbeCount != mDynamicProbeCount || mProbeResolution != probe_resolution || mReset) + +    bool shouldInit = mTexture.isNull() || mReflectionProbeCount != mDynamicProbeCount || mProbeResolution != probe_resolution || mReset; + +    if (shouldInit)      { +        //LL_WARNS() << "====== initReflectionMaps() =======" << LL_ENDL; +          if(mProbeResolution != probe_resolution)          {              mRenderTarget.release(); @@ -1442,6 +1588,8 @@ void LLReflectionMapManager::initReflectionMaps()              mTexture->getWidth() != mProbeResolution ||              mReflectionProbeCount + 2 != mTexture->getCount())          { +            static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); +              if (mTexture)              {                  mTexture = new LLCubeMapArray(*mTexture, mProbeResolution, mReflectionProbeCount + 2); @@ -1452,8 +1600,6 @@ void LLReflectionMapManager::initReflectionMaps()              {                  mTexture = new LLCubeMapArray(); -                static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true); -                  // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation                  // source)                  mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); @@ -1475,7 +1621,9 @@ void LLReflectionMapManager::initReflectionMaps()          for (auto& probe : mProbes)          {              probe->mLastUpdateTime = 0.f; +            probe->mNextUpdateTime = 0.f;              probe->mComplete = false; +            probe->mCompletedCount = 0;              probe->mProbeIndex = -1;              probe->mCubeArray = nullptr;              probe->mCubeIndex = -1; @@ -1501,6 +1649,9 @@ void LLReflectionMapManager::initReflectionMaps()          mDefaultProbe->mRadius = 4096.f;          mDefaultProbe->mProbeIndex = 0;          mDefaultProbe->mComplete = default_complete; +        mDefaultProbe->mCompletedCount = 0; +        mDefaultProbe->mLastUpdateTime = 0.f; +        mDefaultProbe->mNextUpdateTime = 0.f;          touch_default_probe(mDefaultProbe);      }  | 
