diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/lldrawpool.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/lldrawpool.h | 5 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolpbropaque.cpp | 31 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolpbropaque.h | 16 | ||||
| -rw-r--r-- | indra/newview/llreflectionmap.cpp | 81 | ||||
| -rw-r--r-- | indra/newview/llreflectionmap.h | 11 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 54 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.h | 3 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 42 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 2 | 
10 files changed, 210 insertions, 38 deletions
| diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 56377069bb..c61618c056 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -116,6 +116,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)  		break;  	case POOL_GLTF_PBR:  		poolp = new LLDrawPoolGLTFPBR(); +        break; +    case POOL_GLTF_PBR_ALPHA_MASK: +        poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);  		break;  	default:  		LL_ERRS() << "Unknown draw pool type!" << LL_ENDL; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 2c5e31f579..5e741b2b95 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -58,8 +58,9 @@ public:  		POOL_BUMP,  		POOL_TERRAIN,          POOL_MATERIALS, -        POOL_GRASS,          POOL_GLTF_PBR, +        POOL_GRASS, +        POOL_GLTF_PBR_ALPHA_MASK,  		POOL_TREE,  		POOL_ALPHA_MASK,  		POOL_FULLBRIGHT_ALPHA_MASK, @@ -109,7 +110,7 @@ public:      virtual void render(S32 pass = 0) {};      virtual void prerender() {}; -	virtual U32 getVertexDataMask() = 0; +    virtual U32 getVertexDataMask() { return 0; } // DEPRECATED -- draw pool doesn't actually determine vertex data mask any more  	virtual BOOL verify() const { return TRUE; }		// Verify that all data in the draw pool is correct!  	virtual S32 getShaderLevel() const { return mShaderLevel; } diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp index d30fc22393..b75c83e73a 100644 --- a/indra/newview/lldrawpoolpbropaque.cpp +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -33,9 +33,17 @@  static const U32 gltf_render_types[] = { LLPipeline::RENDER_TYPE_PASS_GLTF_PBR, LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK }; -LLDrawPoolGLTFPBR::LLDrawPoolGLTFPBR() : -    LLRenderPass(POOL_GLTF_PBR) +LLDrawPoolGLTFPBR::LLDrawPoolGLTFPBR(U32 type) : +    LLRenderPass(type)  { +    if (type == LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK) +    { +        mRenderType = LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK; +    } +    else +    { +        mRenderType = LLPipeline::RENDER_TYPE_PASS_GLTF_PBR; +    }  }  S32 LLDrawPoolGLTFPBR::getNumDeferredPasses() @@ -47,14 +55,11 @@ void LLDrawPoolGLTFPBR::renderDeferred(S32 pass)  {      llassert(!LLPipeline::sRenderingHUDs); -    for (U32 type : gltf_render_types) -    { -        gDeferredPBROpaqueProgram.bind(); -        pushGLTFBatches(type); +    gDeferredPBROpaqueProgram.bind(); +    pushGLTFBatches(mRenderType); -        gDeferredPBROpaqueProgram.bind(true); -        pushRiggedGLTFBatches(type + 1); -    } +    gDeferredPBROpaqueProgram.bind(true); +    pushRiggedGLTFBatches(mRenderType + 1);  }  S32 LLDrawPoolGLTFPBR::getNumPostDeferredPasses() @@ -67,12 +72,9 @@ void LLDrawPoolGLTFPBR::renderPostDeferred(S32 pass)      if (LLPipeline::sRenderingHUDs)      {          gHUDPBROpaqueProgram.bind(); -        for (U32 type : gltf_render_types) -        { -            pushGLTFBatches(type); -        } +        pushGLTFBatches(mRenderType);      } -    else +    else if (mRenderType == LLPipeline::RENDER_TYPE_PASS_GLTF_PBR) // HACK -- don't render glow except for the non-alpha masked implementation      {          gGL.setColorMask(false, true);          gPBRGlowProgram.bind(); @@ -85,4 +87,3 @@ void LLDrawPoolGLTFPBR::renderPostDeferred(S32 pass)      }  } - diff --git a/indra/newview/lldrawpoolpbropaque.h b/indra/newview/lldrawpoolpbropaque.h index 69e063b322..c8a28461fa 100644 --- a/indra/newview/lldrawpoolpbropaque.h +++ b/indra/newview/lldrawpoolpbropaque.h @@ -32,21 +32,9 @@  class LLDrawPoolGLTFPBR final : public LLRenderPass  {  public: -    enum -    { -        // See: DEFERRED_VB_MASK -        VERTEX_DATA_MASK = 0 -                         | LLVertexBuffer::MAP_VERTEX -                         | LLVertexBuffer::MAP_NORMAL -                         | LLVertexBuffer::MAP_TEXCOORD0 // Diffuse -                         | LLVertexBuffer::MAP_TEXCOORD1 // Normal -                         | LLVertexBuffer::MAP_TEXCOORD2 // Spec <-- ORM Occlusion Roughness Metal -                         | LLVertexBuffer::MAP_TANGENT -                         | LLVertexBuffer::MAP_COLOR -    }; -    U32 getVertexDataMask() override { return VERTEX_DATA_MASK; } +    LLDrawPoolGLTFPBR(U32 type = LLDrawPool::POOL_GLTF_PBR); -    LLDrawPoolGLTFPBR(); +    U32 mRenderType = 0;      S32 getNumDeferredPasses() override;      void renderDeferred(S32 pass) override; diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 394596feea..9fcc6ae902 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -31,9 +31,12 @@  #include "llviewerwindow.h"  #include "llviewerregion.h"  #include "llworld.h" +#include "llshadermgr.h"  extern F32SecondsImplicit gFrameTimeSeconds; +extern U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); +  LLReflectionMap::LLReflectionMap()  {  } @@ -245,3 +248,81 @@ bool LLReflectionMap::getBox(LLMatrix4& box)      return false;  } + +bool LLReflectionMap::isActive() +{ +    return mCubeIndex != -1; +} + +void LLReflectionMap::doOcclusion(const LLVector4a& eye) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +#if 1 +    // super sloppy, but we're doing an occlusion cull against a bounding cube of +    // a bounding sphere, pad radius so we assume if the eye is within +    // the bounding sphere of the bounding cube, the node is not culled +    F32 dist = mRadius * F_SQRT3 + 1.f; + +    LLVector4a o; +    o.setSub(mOrigin, eye); + +    bool do_query = false; + +    if (o.getLength3().getF32() < dist) +    { // eye is inside radius, don't attempt to occlude +        mOccluded = false; +        if (mViewerObject) +        { +            mViewerObject->setDebugText("Camera Non-Occluded"); +        } +        return; +    } +     +    if (mOcclusionQuery == 0) +    { // no query was previously issued, allocate one and issue +        glGenQueries(1, &mOcclusionQuery); +        do_query = true; +    } +    else +    { // query was previously issued, check it and only issue a new query +        // if previous query is available +        GLuint result = (GLuint) 0xFFFFFFFF; +        glGetQueryObjectuiv(mOcclusionQuery, GL_QUERY_RESULT_NO_WAIT, &result); + +        if (result != (GLuint) 0xFFFFFFFF) +        { +            do_query = true; +            mOccluded = result == 0; +            mOcclusionPendingFrames = 0; +        } +        else +        { +            mOcclusionPendingFrames++; +            if (mViewerObject) +            { +                mViewerObject->setDebugText(llformat("Query Pending - %d", mOcclusionPendingFrames)); +            } +        } +    } + +    if (do_query) +    { +        glBeginQuery(GL_ANY_SAMPLES_PASSED, mOcclusionQuery); + +        LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + +        shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mOrigin.getF32ptr()); +        F32 r = mRadius + 0.25f; // pad by 1/4m for near clip plane etc +        shader->uniform3f(LLShaderMgr::BOX_SIZE, mRadius, mRadius, mRadius); + +        gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(LLViewerCamera::getInstance(), mOrigin)); + +        glEndQuery(GL_ANY_SAMPLES_PASSED); + +        if (mViewerObject) +        { +            mViewerObject->setDebugText(llformat("Query Issued - %.2f, %.2f, %.2f", o.getLength3().getF32(), dist, mRadius)); +        } +    } +#endif +} diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 04bc8d824c..0405d06eb5 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -64,6 +64,12 @@ public:      // return false if no bounding box (treat as sphere influence volume)      bool getBox(LLMatrix4& box); +    // return true if this probe is active for rendering +    bool isActive(); + +    // perform occlusion query/readback +    void doOcclusion(const LLVector4a& eye); +      // point at which environment map was last generated from (in agent space)      LLVector4a mOrigin; @@ -101,5 +107,10 @@ public:      // 0 - automatic probe      // 1 - manual probe      U32 mPriority = 0; + +    // occlusion culling state +    GLuint mOcclusionQuery = 0; +    bool mOccluded = false; +    U32 mOcclusionPendingFrames = 0;  }; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index e760bc794c..bfc8b595c2 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -157,6 +157,7 @@ void LLReflectionMapManager::update()      LLReflectionMap* closestDynamic = nullptr;      LLReflectionMap* oldestProbe = nullptr; +    LLReflectionMap* oldestOccluded = nullptr;      if (mUpdatingProbe != nullptr)      { @@ -179,12 +180,27 @@ void LLReflectionMapManager::update()          probe->mProbeIndex = i;          LLVector4a d; -         -        if (!did_update &&  -            i < mReflectionProbeCount && -            (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) + +        if (probe->mOccluded)          { -            oldestProbe = probe; +            if (oldestOccluded == nullptr) +            { +                oldestOccluded = probe; +            } +            else if (probe->mLastUpdateTime < oldestOccluded->mLastUpdateTime) +            { +                oldestOccluded = probe; +            } +        } +        else +        { +            if (!did_update && +                i < mReflectionProbeCount && +                (oldestProbe == nullptr || +                    probe->mLastUpdateTime < oldestProbe->mLastUpdateTime)) +            { +               oldestProbe = probe; +            }          }          if (realtime &&  @@ -240,6 +256,13 @@ void LLReflectionMapManager::update()          doProbeUpdate();      } +    if (oldestOccluded) +    { +        // as far as this occluded probe is concerned, an origin/radius update is as good as a full update +        oldestOccluded->autoAdjustOrigin(); +        oldestOccluded->mLastUpdateTime = gFrameTimeSeconds; +    } +      // update distance to camera for all probes      std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance());  } @@ -277,8 +300,11 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma          mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested          if (mProbes[i]->mCubeIndex != -1)          { -            mProbes[i]->mProbeIndex = count; -            maps[count++] = mProbes[i]; +            if (!mProbes[i]->mOccluded) +            { +                mProbes[i]->mProbeIndex = count; +                maps[count++] = mProbes[i]; +            }          }          else          { @@ -1038,3 +1064,17 @@ void LLReflectionMapManager::cleanup()      // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state      initCubeFree();  } + +void LLReflectionMapManager::doOcclusion() +{ +    LLVector4a eye; +    eye.load3(LLViewerCamera::instance().getOrigin().mV); + +    for (auto& probe : mProbes) +    { +        if (probe != nullptr) +        { +            probe->doOcclusion(eye); +        } +    } +} diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 85f428d75b..fef308541d 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -96,6 +96,9 @@ public:      // True if currently updating a radiance map, false if currently updating an irradiance map      bool isRadiancePass() { return mRadiancePass; } +    // perform occlusion culling on all active reflection probes +    void doOcclusion(); +  private:      friend class LLPipeline; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 69b149f82d..d0688d26a9 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -432,6 +432,7 @@ void LLPipeline::init()  	getPool(LLDrawPool::POOL_MATERIALS);  	getPool(LLDrawPool::POOL_GLOW);  	getPool(LLDrawPool::POOL_GLTF_PBR); +    getPool(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);  	resetFrameStats(); @@ -1545,6 +1546,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)  	case LLDrawPool::POOL_GLTF_PBR:  		poolp = mPBROpaquePool;  		break; +    case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK: +        poolp = mPBRAlphaMaskPool; +        break;  	default:  		llassert(0); @@ -2432,6 +2436,26 @@ void LLPipeline::doOcclusion(LLCamera& camera)      LL_PROFILE_GPU_ZONE("doOcclusion");      llassert(!gCubeSnapshot); +    if (sReflectionProbesEnabled && sUseOcclusion > 1 && !LLPipeline::sShadowRender && !gCubeSnapshot) +    { +        gGL.setColorMask(false, false); +        LLGLDepthTest depth(GL_TRUE, GL_FALSE); +        LLGLDisable cull(GL_CULL_FACE); + +        gOcclusionCubeProgram.bind(); + +        if (mCubeVB.isNull()) +        { //cube VB will be used for issuing occlusion queries +            mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); +        } +        mCubeVB->setBuffer(); + +        mReflectionMapManager.doOcclusion(); +        gOcclusionCubeProgram.unbind(); + +        gGL.setColorMask(true, true); +    } +      if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&  		(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))  	{ @@ -5192,6 +5216,19 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )          }          break; +    case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK: +        if (mPBRAlphaMaskPool) +        { +            llassert(0); +            LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Alpha Mask Pool" << LL_ENDL; +        } +        else +        { +            mPBRAlphaMaskPool = new_poolp; +        } +        break; + +  	default:  		llassert(0);  		LL_WARNS() << "Invalid Pool Type in  LLPipeline::addPool()" << LL_ENDL; @@ -5308,6 +5345,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )          mPBROpaquePool = NULL;          break; +    case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK: +        llassert(poolp == mPBRAlphaMaskPool); +        mPBRAlphaMaskPool = NULL; +        break; +  	default:  		llassert(0);  		LL_WARNS() << "Invalid Pool Type in  LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 85878dd21d..29dd42e4ec 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -895,6 +895,8 @@ protected:  	LLDrawPool*					mMaterialsPool = nullptr;  	LLDrawPool*					mWLSkyPool = nullptr;  	LLDrawPool*					mPBROpaquePool = nullptr; +    LLDrawPool*                 mPBRAlphaMaskPool = nullptr; +  	// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar  public: | 
