diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 1227 |
1 files changed, 735 insertions, 492 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 54e6c6fc6e..91d276c8df 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -227,6 +227,7 @@ extern S32 gBoxFrame; //extern BOOL gHideSelectedObjects; extern BOOL gDisplaySwapBuffers; extern BOOL gDebugGL; +extern BOOL gCubeSnapshot; bool gAvatarBacklight = false; @@ -280,29 +281,33 @@ static LLStaticHashedString sKern("kern"); static LLStaticHashedString sKernScale("kern_scale"); //---------------------------------------- -std::string gPoolNames[] = +#if 0 +std::string gPoolNames[LLDrawPool::NUM_POOL_TYPES] = { // Correspond to LLDrawpool enum render type - "NONE", - "POOL_SIMPLE", - "POOL_GROUND", - "POOL_FULLBRIGHT", - "POOL_BUMP", - "POOL_MATERIALS", - "POOL_TERRAIN," - "POOL_SKY", - "POOL_WL_SKY", - "POOL_TREE", - "POOL_ALPHA_MASK", - "POOL_FULLBRIGHT_ALPHA_MASK", - "POOL_GRASS", - "POOL_INVISIBLE", - "POOL_AVATAR", - "POOL_VOIDWATER", - "POOL_WATER", - "POOL_GLOW", - "POOL_ALPHA" + "NONE" + , "POOL_SIMPLE" + , "POOL_GROUND" + , "POOL_FULLBRIGHT" + , "POOL_BUMP" + , "POOL_MATERIALS" + , "POOL_TERRAIN" + , "POOL_SKY" + , "POOL_WL_SKY" + , "POOL_TREE" + , "POOL_ALPHA_MASK" + , "POOL_FULLBRIGHT_ALPHA_MASK" + , "POOL_GRASS" + , "POOL_INVISIBLE" + , "POOL_AVATAR" + , "POOL_CONTROL_AV" // Animesh + , "POOL_VOIDWATER" + , "POOL_WATER" + , "POOL_GLOW" + , "POOL_ALPHA" + , "POOL_PBR_OPAQUE" }; +#endif void drawBox(const LLVector4a& c, const LLVector4a& r); void drawBoxOutline(const LLVector3& pos, const LLVector3& size); @@ -350,6 +355,7 @@ bool LLPipeline::sRenderFrameTest = false; bool LLPipeline::sRenderAttachedLights = true; bool LLPipeline::sRenderAttachedParticles = true; bool LLPipeline::sRenderDeferred = false; +bool LLPipeline::sRenderPBR = false; S32 LLPipeline::sVisibleLightCount = 0; bool LLPipeline::sRenderingHUDs; F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f; @@ -366,8 +372,12 @@ void validate_framebuffer_object(); // for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions) bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false) { - return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular - target.addColorAttachment(GL_RGB10_A2); //normal+z + bool pbr = gSavedSettings.getBOOL("RenderPBR"); + bool valid = true + && target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) // frag-data[1] specular or PBR sRGB Emissive + && target.addColorAttachment(GL_RGB10_A2) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight + && (pbr ? target.addColorAttachment(GL_RGBA) : true); // frag_data[3] PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl + return valid; } LLPipeline::LLPipeline() : @@ -405,9 +415,7 @@ LLPipeline::LLPipeline() : mWLSkyPool(NULL), mLightMask(0), mLightMovingMask(0), - mLightingDetail(0), - mScreenWidth(0), - mScreenHeight(0) + mLightingDetail(0) { mNoiseMap = 0; mTrueNoiseMap = 0; @@ -434,12 +442,15 @@ void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name) void LLPipeline::init() { + LL_WARNS() << "Begin pipeline initialization" << LL_ENDL; // TODO: Remove after testing refreshCachedSettings(); + mRT = &mMainRT; + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); - sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); @@ -450,6 +461,7 @@ void LLPipeline::init() mInitialized = true; stop_glerror(); + LL_WARNS() << "No GL errors yet. Pipeline initialization will continue." << LL_ENDL; // TODO: Remove after testing //create render pass pools getPool(LLDrawPool::POOL_ALPHA); @@ -462,6 +474,7 @@ void LLPipeline::init() getPool(LLDrawPool::POOL_BUMP); getPool(LLDrawPool::POOL_MATERIALS); getPool(LLDrawPool::POOL_GLOW); + getPool(LLDrawPool::POOL_PBR_OPAQUE); resetFrameStats(); @@ -510,7 +523,9 @@ void LLPipeline::init() // Enable features + LL_WARNS() << "Shader initialization start" << LL_ENDL; // TODO: Remove after testing LLViewerShaderMgr::instance()->setShaders(); + LL_WARNS() << "Shader initialization end" << LL_ENDL; // TODO: Remove after testing stop_glerror(); @@ -537,8 +552,9 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors"); connectRefreshCachedSettingsSafe("RenderDelayVBUpdate"); connectRefreshCachedSettingsSafe("UseOcclusion"); - connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); - connectRefreshCachedSettingsSafe("RenderDeferred"); + // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); + // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred"); + connectRefreshCachedSettingsSafe("RenderPBR"); connectRefreshCachedSettingsSafe("RenderDeferredSunWash"); connectRefreshCachedSettingsSafe("RenderFSAASamples"); connectRefreshCachedSettingsSafe("RenderResolutionDivisor"); @@ -732,8 +748,9 @@ void LLPipeline::requestResizeShadowTexture() void LLPipeline::resizeShadowTexture() { - releaseShadowTargets(); - allocateShadowBuffer(mScreenWidth, mScreenHeight); + releaseSunShadowTargets(); + releaseSpotShadowTargets(); + allocateShadowBuffer(mRT->width, mRT->height); gResizeShadowTexture = FALSE; } @@ -744,10 +761,11 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - if (gResizeScreenTexture || (resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) + if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight())) { releaseScreenBuffers(); - releaseShadowTargets(); + releaseSunShadowTargets(); + releaseSpotShadowTargets(); allocateScreenBuffer(resX,resY); gResizeScreenTexture = FALSE; } @@ -767,42 +785,16 @@ void LLPipeline::allocatePhysicsBuffer() bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { - refreshCachedSettings(); - - bool save_settings = sRenderDeferred; - if (save_settings) - { - // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets - gSavedSettings.setBOOL("RenderInitError", TRUE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - } - + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; eFBOStatus ret = doAllocateScreenBuffer(resX, resY); - if (save_settings) - { - // don't disable shaders on next session - gSavedSettings.setBOOL("RenderInitError", FALSE); - gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); - } - - if (ret == FBO_FAILURE) - { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled - //NOTE: if the session closes successfully after this call, deferred rendering will be - // disabled on future sessions - if (LLPipeline::sRenderDeferred) - { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - LLPipeline::refreshCachedSettings(); - } - } - return ret == FBO_SUCCESS_FULLRES; } LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; // try to allocate screen buffers at requested resolution and samples // - on failure, shrink number of samples and try again // - if not multisampled, shrink resolution and try again (favor X resolution over Y) @@ -856,11 +848,20 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) { - refreshCachedSettings(); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + if (mRT == &mMainRT) + { // hacky -- allocate auxillary buffer + gCubeSnapshot = TRUE; + mRT = &mAuxillaryRT; + U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2; + allocateScreenBuffer(res, res, samples); + mRT = &mMainRT; + gCubeSnapshot = FALSE; + } // remember these dimensions - mScreenWidth = resX; - mScreenHeight = resY; + mRT->width = resX; + mRT->height = resY; U32 res_mod = RenderResolutionDivisor; @@ -872,7 +873,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (RenderUIBuffer) { - if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) + if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) { return false; } @@ -886,10 +887,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) const U32 occlusion_divisor = 3; //allocate deferred rendering color buffers - if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; - if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; - if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; - if (!addDeferredAttachments(mDeferredScreen)) return false; + if (!mRT->deferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (!addDeferredAttachments(mRT->deferredScreen)) return false; GLuint screenFormat = GL_RGBA16; if (gGLManager.mIsAMD) @@ -902,23 +903,23 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) screenFormat = GL_RGBA16F_ARB; } - if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (samples > 0) { - if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; } else { - mFXAABuffer.release(); + mRT->fxaaBuffer.release(); } if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) - { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa - if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; + { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa + if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; } else { - mDeferredLight.release(); + mRT->deferredLight.release(); } allocateShadowBuffer(resX, resY); @@ -931,22 +932,23 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } else { - mDeferredLight.release(); + mRT->deferredLight.release(); - releaseShadowTargets(); + releaseSunShadowTargets(); + releaseSpotShadowTargets(); - mFXAABuffer.release(); - mScreen.release(); - mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first - mDeferredDepth.release(); - mOcclusionDepth.release(); + mRT->fxaaBuffer.release(); + mRT->screen.release(); + mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first + mRT->deferredDepth.release(); + mRT->occlusionDepth.release(); - if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; + if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; } if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets - mDeferredScreen.shareDepthBuffer(mScreen); + mRT->deferredScreen.shareDepthBuffer(mRT->screen); } gGL.getTexUnit(0)->disable(); @@ -961,68 +963,67 @@ inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0 bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) { - refreshCachedSettings(); - - if (LLPipeline::sRenderDeferred) - { - S32 shadow_detail = RenderShadowDetail; + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + if (LLPipeline::sRenderDeferred) + { + S32 shadow_detail = RenderShadowDetail; - const U32 occlusion_divisor = 3; + const U32 occlusion_divisor = 3; - F32 scale = llmax(0.f,RenderShadowResolutionScale); - U32 sun_shadow_map_width = BlurHappySize(resX, scale); - U32 sun_shadow_map_height = BlurHappySize(resY, scale); + F32 scale = llmax(0.f, RenderShadowResolutionScale); + U32 sun_shadow_map_width = BlurHappySize(resX, scale); + U32 sun_shadow_map_height = BlurHappySize(resY, scale); - if (shadow_detail > 0) - { //allocate 4 sun shadow maps - for (U32 i = 0; i < 4; i++) - { - if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) + if (shadow_detail > 0) + { //allocate 4 sun shadow maps + for (U32 i = 0; i < 4; i++) + { + if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) { return false; } - if (!mShadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) + if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) { return false; } - } - } - else - { - for (U32 i = 0; i < 4; i++) - { - releaseShadowTarget(i); - } - } - - U32 width = (U32) (resX*scale); - U32 height = width; + } + } + else + { + for (U32 i = 0; i < 4; i++) + { + releaseSunShadowTarget(i); + } + } - if (shadow_detail > 1) - { //allocate two spot shadow maps - U32 spot_shadow_map_width = width; - U32 spot_shadow_map_height = height; - for (U32 i = 4; i < 6; i++) - { - if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) - { - return false; - } - if (!mShadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE)) - { - return false; - } - } + if (!gCubeSnapshot) // hack to not allocate spot shadow maps during ReflectionMapManager init + { + U32 width = (U32)(resX * scale); + U32 height = width; + + if (shadow_detail > 1) + { //allocate two spot shadow maps + U32 spot_shadow_map_width = width; + U32 spot_shadow_map_height = height; + for (U32 i = 0; i < 2; i++) + { + if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) + { + return false; + } + if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE)) + { + return false; + } + } + } + else + { + releaseSpotShadowTargets(); + } } - else - { - for (U32 i = 4; i < 6; i++) - { - releaseShadowTarget(i); - } - } - } + } return true; } @@ -1036,7 +1037,7 @@ void LLPipeline::updateRenderTransparentWater() //static void LLPipeline::updateRenderBump() { - sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump"); } // static @@ -1046,13 +1047,14 @@ void LLPipeline::updateRenderDeferred() RenderDeferred && LLRenderTarget::sUseFBO && LLPipeline::sRenderBump && - WindLightUseAtmosShaders && - (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); + WindLightUseAtmosShaders; + sRenderPBR = sRenderDeferred && gSavedSettings.getBOOL("RenderPBR"); } // static void LLPipeline::refreshCachedSettings() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); @@ -1066,8 +1068,8 @@ void LLPipeline::refreshCachedSettings() && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; - WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); - RenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); + WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders"); + RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred"); RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); @@ -1194,36 +1196,50 @@ void LLPipeline::releaseLUTBuffers() void LLPipeline::releaseShadowBuffers() { - releaseShadowTargets(); + releaseSunShadowTargets(); + releaseSpotShadowTargets(); } void LLPipeline::releaseScreenBuffers() { - mUIScreen.release(); - mScreen.release(); - mFXAABuffer.release(); + mRT->uiScreen.release(); + mRT->screen.release(); + mRT->fxaaBuffer.release(); mPhysicsDisplay.release(); - mDeferredScreen.release(); - mDeferredDepth.release(); - mDeferredLight.release(); - mOcclusionDepth.release(); + mRT->deferredScreen.release(); + mRT->deferredDepth.release(); + mRT->deferredLight.release(); + mRT->occlusionDepth.release(); } -void LLPipeline::releaseShadowTarget(U32 index) +void LLPipeline::releaseSunShadowTarget(U32 index) { - mShadow[index].release(); - mShadowOcclusion[index].release(); + llassert(index < 4); + mRT->shadow[index].release(); + mRT->shadowOcclusion[index].release(); } -void LLPipeline::releaseShadowTargets() +void LLPipeline::releaseSunShadowTargets() { - for (U32 i = 0; i < 6; i++) + for (U32 i = 0; i < 4; i++) { - releaseShadowTarget(i); + releaseSunShadowTarget(i); } } +void LLPipeline::releaseSpotShadowTargets() +{ + if (!gCubeSnapshot) // hack to avoid freeing spot shadows during ReflectionMapManager init + { + for (U32 i = 0; i < 2; i++) + { + mSpotShadow[i].release(); + mSpotShadowOcclusion[i].release(); + } + } +} + void LLPipeline::createGLBuffers() { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -1256,8 +1272,8 @@ void LLPipeline::createGLBuffers() } allocateScreenBuffer(resX, resY); - mScreenWidth = 0; - mScreenHeight = 0; + mRT->width = 0; + mRT->height = 0; if (sRenderDeferred) { @@ -1597,6 +1613,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) poolp = mWLSkyPool; break; + case LLDrawPool::POOL_PBR_OPAQUE: + poolp = mPBROpaquePool; + break; + default: llassert(0); LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL; @@ -1638,6 +1658,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima } LLMaterial* mat = te->getMaterialParams().get(); + LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); bool color_alpha = te->getColor().mV[3] < 0.999f; bool alpha = color_alpha; @@ -1671,6 +1692,10 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima { return LLDrawPool::POOL_BUMP; } + else if (gltf_mat && !alpha) + { + return LLDrawPool::POOL_PBR_OPAQUE; + } else if (mat && !alpha) { return LLDrawPool::POOL_MATERIALS; @@ -2028,6 +2053,7 @@ void LLPipeline::updateMove() //static F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera) { + llassert(!gCubeSnapshot); // shouldn't be doing ANY of this during cube snap shots LLVector3 lookAt = center - camera.getOrigin(); F32 dist = lookAt.length(); @@ -2353,11 +2379,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla { if (LLPipeline::sRenderDeferred && can_use_occlusion) { - mOcclusionDepth.bindTarget(); + mRT->occlusionDepth.bindTarget(); } else { - mScreen.bindTarget(); + mRT->screen.bindTarget(); } } @@ -2479,11 +2505,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla { if (LLPipeline::sRenderDeferred && can_use_occlusion) { - mOcclusionDepth.flush(); + mRT->occlusionDepth.flush(); } else { - mScreen.flush(); + mRT->screen.flush(); } } } @@ -2497,7 +2523,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) group->setVisible(); - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) { group->updateDistance(camera); } @@ -2603,6 +2629,8 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + llassert(!gCubeSnapshot); downsampleDepthBuffer(source, dest, scratch_space); dest.bindTarget(); doOcclusion(camera); @@ -2612,6 +2640,7 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT void LLPipeline::doOcclusion(LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("doOcclusion"); if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) { @@ -2845,7 +2874,7 @@ void LLPipeline::rebuildPriorityGroups() void LLPipeline::rebuildGroups() { - if (mGroupQ2.empty()) + if (mGroupQ2.empty() || gCubeSnapshot) { return; } @@ -2895,6 +2924,10 @@ void LLPipeline::updateGeom(F32 max_dtime) LLPointer<LLDrawable> drawablep; LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE); + if (gCubeSnapshot) + { + return; + } assertInitialized(); @@ -3134,6 +3167,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) } } + mReflectionMapManager.shift(offseta); + LLHUDText::shiftAll(offset); LLHUDNameTag::shiftAll(offset); @@ -3314,7 +3349,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) { LLSpatialGroup* last_group = NULL; BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged(); @@ -3396,7 +3431,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) stateSort(drawablep, camera); } - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) { //avoid redundant stateSort calls group->mLastUpdateDistance = group->mDistance; } @@ -3465,7 +3500,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) { //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here { @@ -3714,7 +3749,7 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize) if (tex) { LLImageGL* gl_tex = tex->getGLTexture(); - if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) + if (gl_tex && gl_tex->updateBindStats()) { tex->setActive(); tex->addTextureStats(vsize); @@ -3734,6 +3769,7 @@ void LLPipeline::touchTextures(LLDrawInfo* info) touchTexture(info->mTexture, info->mVSize); touchTexture(info->mSpecularMap, info->mVSize); touchTexture(info->mNormalMap, info->mVSize); + touchTexture(info->mEmissiveMap, info->mVSize); } void LLPipeline::postSort(LLCamera& camera) @@ -3743,21 +3779,26 @@ void LLPipeline::postSort(LLCamera& camera) assertInitialized(); LL_PUSH_CALLSTACKS(); - //rebuild drawable geometry - for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) - { - LLSpatialGroup* group = *i; - if (!sUseOcclusion || - !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - group->rebuildGeom(); - } - } - LL_PUSH_CALLSTACKS(); - //rebuild groups - sCull->assertDrawMapsEmpty(); - rebuildPriorityGroups(); + if (!gCubeSnapshot) + { + //rebuild drawable geometry + for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) + { + LLSpatialGroup* group = *i; + if (!sUseOcclusion || + !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + group->rebuildGeom(); + } + } + LL_PUSH_CALLSTACKS(); + //rebuild groups + sCull->assertDrawMapsEmpty(); + + rebuildPriorityGroups(); + } + LL_PUSH_CALLSTACKS(); @@ -3773,30 +3814,52 @@ void LLPipeline::postSort(LLCamera& camera) continue; } - if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY)) + if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY) && !gCubeSnapshot) { //no way this group is going to be drawable without a rebuild group->rebuildGeom(); } - for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) - { - LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - if (!hasRenderType(j->first)) - { - continue; - } - - for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) - { + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) + { + LLSpatialGroup::drawmap_elem_t& src_vec = j->second; + if (!hasRenderType(j->first)) + { + continue; + } + + // DEBUG -- force a texture virtual size update every frame + /*if (group->getSpatialPartition()->mDrawableType == LLPipeline::RENDER_TYPE_VOLUME) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("plps - update vsize"); + auto& entries = group->getData(); + for (auto& entry : entries) + { + if (entry) + { + auto* data = entry->getDrawable(); + if (data) + { + LLVOVolume* volume = ((LLDrawable*)data)->getVOVolume(); + if (volume) + { + volume->updateTextureVirtualSize(true); + } + } + } + } + }*/ + + for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) + { LLDrawInfo* info = *k; - - sCull->pushDrawInfo(j->first, info); - if (!sShadowRender && !sReflectionRender) + + sCull->pushDrawInfo(j->first, info); + if (!sShadowRender && !sReflectionRender && !gCubeSnapshot) { touchTextures(info); addTrianglesDrawn(info->mCount, info->mDrawMode); } - } + } } if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) @@ -3806,7 +3869,7 @@ void LLPipeline::postSort(LLCamera& camera) if (alpha != group->mDrawMap.end()) { //store alpha groups for sorting LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot) { if (bridge) { @@ -4262,7 +4325,7 @@ U32 LLPipeline::sCurRenderPoolType = 0 ; void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); - + LL_PROFILE_GPU_ZONE("renderGeom"); assertInitialized(); F32 saved_modelview[16]; @@ -4437,7 +4500,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) gGL.loadMatrix(gGLModelView); if (occlude) - { + { // catch uncommon condition where pools at drawpool grass and later are disabled occlude = false; gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); @@ -4512,14 +4575,10 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) void LLPipeline::renderGeomDeferred(LLCamera& camera) { LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); + LL_PROFILE_GPU_ZONE("renderGeomDeferred"); + { - // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function. - // Solutions are: - // 1. Use a new scope - // 2. Use named zones - // 3. Use transient zones LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS); LLGLEnable cull(GL_CULL_FACE); @@ -4540,6 +4599,12 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) LLGLState::checkStates(); LLGLState::checkTextureChannels(); + if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1) + { + //update reflection probe uniform + mReflectionMapManager.updateUniforms(); + } + U32 cur_type = 0; gGL.setColorMask(true, true); @@ -4611,6 +4676,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS); + LL_PROFILE_GPU_ZONE("renderGeomPostDeferred"); + U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -4633,11 +4700,12 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) if (occlude && cur_type >= LLDrawPool::POOL_GRASS) { + llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots occlude = false; gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); LLGLSLShader::bindNoShader(); - doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth); + doOcclusion(camera, mRT->screen, mRT->occlusionDepth, &mRT->deferredDepth); gGL.setColorMask(true, false); } @@ -4706,6 +4774,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) void LLPipeline::renderGeomShadow(LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("renderGeomShadow"); U32 cur_type = 0; LLGLEnable cull(GL_CULL_FACE); @@ -5160,7 +5229,6 @@ void LLPipeline::renderDebug() glPointSize(1.f); } - // Debug stuff. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5214,6 +5282,12 @@ void LLPipeline::renderDebug() visible_selected_groups.clear(); + //draw reflection probes and links between them + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only) + { + mReflectionMapManager.renderDebug(); + } + gUIProgram.bind(); if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only) @@ -5702,6 +5776,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) } break; + case LLDrawPool::POOL_PBR_OPAQUE: + if( mPBROpaquePool ) + { + llassert(0); + LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Opaque Pool" << LL_ENDL; + } + else + { + mPBROpaquePool = new_poolp; + } + break; + default: llassert(0); LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL; @@ -5818,6 +5904,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) mGroundPool = NULL; break; + case LLDrawPool::POOL_PBR_OPAQUE: + llassert( poolp == mPBROpaquePool ); + mPBROpaquePool = NULL; + break; + default: llassert(0); LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL; @@ -5934,6 +6025,7 @@ void LLPipeline::setupAvatarLights(bool for_edit) static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; F32 inten = light->getLightIntensity(); if (inten < .001f) { @@ -5957,9 +6049,10 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ void LLPipeline::calcNearbyLights(LLCamera& camera) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; assertInitialized(); - if (LLPipeline::sReflectionRender) + if (LLPipeline::sReflectionRender || gCubeSnapshot) { return; } @@ -6142,6 +6235,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) void LLPipeline::setupHWLights(LLDrawPool* pool) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; assertInitialized(); LLEnvironment& environment = LLEnvironment::instance(); @@ -6703,15 +6797,6 @@ void LLPipeline::toggleRenderType(U32 type) //static void LLPipeline::toggleRenderTypeControl(U32 type) { - U32 bit = (1<<type); - if (gPipeline.hasRenderType(type)) - { - LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL; - } - else - { - LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL; - } gPipeline.toggleRenderType(type); } @@ -6957,7 +7042,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE); if (part && hasRenderType(part->mDrawableType)) { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL); + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, face_hit, &position, NULL, NULL, NULL); if (hit) { drawable = hit; @@ -6985,6 +7070,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end, bool pick_transparent, bool pick_rigged, + bool pick_unselectable, S32* face_hit, LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point @@ -7018,7 +7104,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, LLSpatialPartition* part = region->getSpatialPartition(j); if (part && hasRenderType(part->mDrawableType)) { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, face_hit, &position, tex_coord, normal, tangent); if (hit) { drawable = hit; @@ -7075,7 +7161,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR); if (part && hasRenderType(part->mDrawableType)) { - LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); + LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, face_hit, &position, tex_coord, normal, tangent); if (hit) { LLVector4a delta; @@ -7163,7 +7249,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, c LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD); if (part) { - LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, face_hit, intersection, tex_coord, normal, tangent); + LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, face_hit, intersection, tex_coord, normal, tangent); if (hit) { drawable = hit; @@ -7464,9 +7550,11 @@ void LLPipeline::renderFinalize() } LLVector2 tc1(0, 0); - LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2); + LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2); LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); + LL_PROFILE_GPU_ZONE("renderFinalize"); + gGL.color4f(1, 1, 1, 1); LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -7488,6 +7576,7 @@ void LLPipeline::renderFinalize() if (sRenderGlow) { + LL_PROFILE_GPU_ZONE("glow"); mGlow[2].bindTarget(); mGlow[2].clear(); @@ -7512,7 +7601,7 @@ void LLPipeline::renderFinalize() gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); + mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT); gGL.color4f(1, 1, 1, 1); gPipeline.enableLightsFullbright(); @@ -7528,7 +7617,7 @@ void LLPipeline::renderFinalize() gGL.end(); - gGL.getTexUnit(0)->unbind(mScreen.getUsage()); + gGL.getTexUnit(0)->unbind(mRT->screen.getUsage()); mGlow[2].flush(); @@ -7606,7 +7695,7 @@ void LLPipeline::renderFinalize() gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight()); + tc2.setVec((F32) mRT->screen.getWidth(), (F32) mRT->screen.getHeight()); gGL.flush(); @@ -7614,17 +7703,18 @@ void LLPipeline::renderFinalize() if (LLPipeline::sRenderDeferred) { - bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField; + RenderDepthOfField && + !gCubeSnapshot; - bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); + bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete(); gViewerWindow->setup3DViewport(); if (dof_enabled) { + LL_PROFILE_GPU_ZONE("dof"); LLGLSLShader *shader = &gDeferredPostProgram; LLGLDisable blend(GL_BLEND); @@ -7660,7 +7750,7 @@ void LLPipeline::renderFinalize() LLVector4a result; result.clear(); - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result); + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); focus_point.set(result.getF32ptr()); } @@ -7709,7 +7799,7 @@ void LLPipeline::renderFinalize() const F32 default_fov = CameraFieldOfView * F_PI / 180.f; - // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); + // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); @@ -7729,15 +7819,15 @@ void LLPipeline::renderFinalize() F32 magnification = focal_length / (subject_distance - focal_length); { // build diffuse+bloom+CoF - mDeferredLight.bindTarget(); + mRT->deferredLight.bindTarget(); shader = &gDeferredCoFProgram; bindDeferredShader(*shader); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); if (channel > -1) { - mScreen.bindTexture(0, channel); + mRT->screen.bindTexture(0, channel); } shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); @@ -7760,23 +7850,23 @@ void LLPipeline::renderFinalize() gGL.end(); unbindDeferredShader(*shader); - mDeferredLight.flush(); + mRT->deferredLight.flush(); } - U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale); - U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale); + U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); + U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); { // perform DoF sampling at half-res (preserve alpha channel) - mScreen.bindTarget(); + mRT->screen.bindTarget(); glViewport(0, 0, dof_width, dof_height); gGL.setColorMask(true, false); shader = &gDeferredPostProgram; bindDeferredShader(*shader); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); if (channel > -1) { - mDeferredLight.bindTexture(0, channel); + mRT->deferredLight.bindTexture(0, channel); } shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -7795,15 +7885,15 @@ void LLPipeline::renderFinalize() gGL.end(); unbindDeferredShader(*shader); - mScreen.flush(); + mRT->screen.flush(); gGL.setColorMask(true, true); } { // combine result based on alpha if (multisample) { - mDeferredLight.bindTarget(); - glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); + mRT->deferredLight.bindTarget(); + glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight()); } else { @@ -7817,10 +7907,10 @@ void LLPipeline::renderFinalize() shader = &gDeferredDoFCombineProgram; bindDeferredShader(*shader); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); if (channel > -1) { - mScreen.bindTexture(0, channel); + mRT->screen.bindTexture(0, channel); } shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -7844,24 +7934,25 @@ void LLPipeline::renderFinalize() if (multisample) { - mDeferredLight.flush(); + mRT->deferredLight.flush(); } } } else { + LL_PROFILE_GPU_ZONE("no dof"); if (multisample) { - mDeferredLight.bindTarget(); + mRT->deferredLight.bindTarget(); } LLGLSLShader *shader = &gDeferredPostNoDoFProgram; bindDeferredShader(*shader); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); if (channel > -1) { - mScreen.bindTexture(0, channel); + mRT->screen.bindTexture(0, channel); } gGL.begin(LLRender::TRIANGLE_STRIP); @@ -7880,17 +7971,18 @@ void LLPipeline::renderFinalize() if (multisample) { - mDeferredLight.flush(); + mRT->deferredLight.flush(); } } if (multisample) { + LL_PROFILE_GPU_ZONE("aa"); // bake out texture2D with RGBL for FXAA shader - mFXAABuffer.bindTarget(); + mRT->fxaaBuffer.bindTarget(); - S32 width = mScreen.getWidth(); - S32 height = mScreen.getHeight(); + S32 width = mRT->screen.getWidth(); + S32 height = mRT->screen.getHeight(); glViewport(0, 0, width, height); LLGLSLShader *shader = &gGlowCombineFXAAProgram; @@ -7898,10 +7990,10 @@ void LLPipeline::renderFinalize() shader->bind(); shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); if (channel > -1) { - mDeferredLight.bindTexture(0, channel); + mRT->deferredLight.bindTexture(0, channel); } gGL.begin(LLRender::TRIANGLE_STRIP); @@ -7912,18 +8004,18 @@ void LLPipeline::renderFinalize() gGL.flush(); - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); shader->unbind(); - mFXAABuffer.flush(); + mRT->fxaaBuffer.flush(); shader = &gFXAAProgram; shader->bind(); - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage()); if (channel > -1) { - mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); } gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; @@ -7932,8 +8024,8 @@ void LLPipeline::renderFinalize() gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - F32 scale_x = (F32) width / mFXAABuffer.getWidth(); - F32 scale_y = (F32) height / mFXAABuffer.getHeight(); + F32 scale_x = (F32) width / mRT->fxaaBuffer.getWidth(); + F32 scale_y = (F32) height / mRT->fxaaBuffer.getHeight(); shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, @@ -7984,7 +8076,7 @@ void LLPipeline::renderFinalize() gGlowCombineProgram.bind(); gGL.getTexUnit(0)->bind(&mGlow[1]); - gGL.getTexUnit(1)->bind(&mScreen); + gGL.getTexUnit(1)->bind(&mRT->screen); LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); @@ -8027,10 +8119,10 @@ void LLPipeline::renderFinalize() gSplatTextureRectProgram.unbind(); } - if (LLRenderTarget::sUseFBO) - { // copy depth buffer from mScreen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0, - mScreen.getWidth(), mScreen.getHeight(), + if (LLRenderTarget::sUseFBO && !gCubeSnapshot) + { // copy depth buffer from mRT->screen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0, + mRT->screen.getWidth(), mRT->screen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); } @@ -8048,31 +8140,39 @@ void LLPipeline::renderFinalize() void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - - LLRenderTarget* deferred_target = &mDeferredScreen; - LLRenderTarget* deferred_depth_target = &mDeferredDepth; - LLRenderTarget* deferred_light_target = &mDeferredLight; + LL_PROFILE_GPU_ZONE("bindDeferredShader"); + LLRenderTarget* deferred_target = &mRT->deferredScreen; + LLRenderTarget* deferred_depth_target = &mRT->deferredDepth; + LLRenderTarget* deferred_light_target = &mRT->deferredLight; shader.bind(); S32 channel = 0; channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); if (channel > -1) { - deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); + deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); // frag_data[0] } + // NOTE: PBR sRGB Emissive -- See: C++: addDeferredAttachments(), GLSL: pbropaqueF.glsl channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); if (channel > -1) { - deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); + deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); // frag_data[1] } channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); if (channel > -1) { - deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); + deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); // frag_data[2] } + // NOTE: PBR linear packed Occlusion, Roughness, Metal -- See: C++: addDeferredAttachments(), GLSL: pbropaqueF.glsl + channel = shader.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage()); + if (channel > -1) + { + deferred_target->bindTexture(3, channel, LLTexUnit::TFO_POINT); // frag_data[3] + } + channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); if (channel > -1) { @@ -8133,7 +8233,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ for (U32 i = 0; i < 4; i++) { - LLRenderTarget* shadow_target = getShadowTarget(i); + LLRenderTarget* shadow_target = getSunShadowTarget(i); if (shadow_target) { channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE); @@ -8141,7 +8241,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ if (channel > -1) { stop_glerror(); - gGL.getTexUnit(channel)->bind(getShadowTarget(i), TRUE); + gGL.getTexUnit(channel)->bind(getSunShadowTarget(i), TRUE); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC); gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); @@ -8153,27 +8253,27 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ } } - for (U32 i = 4; i < 6; i++) - { - channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i); - stop_glerror(); - if (channel > -1) - { - stop_glerror(); - LLRenderTarget* shadow_target = getShadowTarget(i); - if (shadow_target) - { - gGL.getTexUnit(channel)->bind(shadow_target, TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - stop_glerror(); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); - stop_glerror(); - } - } - } + for (U32 i = 4; i < 6; i++) + { + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0 + i); + stop_glerror(); + if (channel > -1) + { + stop_glerror(); + LLRenderTarget* shadow_target = getSpotShadowTarget(i-4); + if (shadow_target) + { + gGL.getTexUnit(channel)->bind(shadow_target, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + stop_glerror(); + } + } + } stop_glerror(); @@ -8200,16 +8300,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ { cube_map->enable(channel); cube_map->bind(); - F32* m = gGLModelView; - - F32 mat[] = { m[0], m[1], m[2], - m[4], m[5], m[6], - m[8], m[9], m[10] }; - - shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); } + + F32* m = gGLModelView; + + F32 mat[] = { m[0], m[1], m[2], + m[4], m[5], m[6], + m[8], m[9], m[10] }; + + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); } + bindReflectionProbes(shader); + if (gAtmosphere) { // bind precomputed textures necessary for calculating sun and sky luminance @@ -8238,7 +8341,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ } } - shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV); + /*if (gCubeSnapshot) + { // we only really care about the first two values, but the shader needs increasing separation between clip planes + shader.uniform4f(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1.f, 64.f, 128.f, 256.f); + } + else*/ + { + shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV); + } shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash); shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise); shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize); @@ -8273,8 +8383,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV); shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV); - shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight()); - shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight()); + shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight()); + shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight()); shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); @@ -8310,14 +8420,15 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f) void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("renderDeferredLighting"); if (!sCull) { return; } - LLRenderTarget *deferred_target = &mDeferredScreen; - LLRenderTarget *deferred_depth_target = &mDeferredDepth; - LLRenderTarget *deferred_light_target = &mDeferredLight; + LLRenderTarget *deferred_target = &mRT->deferredScreen; + LLRenderTarget *deferred_depth_target = &mRT->deferredDepth; + LLRenderTarget *deferred_light_target = &mRT->deferredLight; { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); @@ -8384,6 +8495,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) if (RenderDeferredSSAO || RenderShadowDetail > 0) { + LL_PROFILE_GPU_ZONE("sun program"); deferred_light_target->bindTarget(); { // paint shadow/SSAO light map (direct lighting lightmap) LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - sun shadow"); @@ -8431,66 +8543,79 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) } if (RenderDeferredSSAO) - { // soften direct lighting lightmap - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow"); - // blur lightmap - screen_target->bindTarget(); - glClearColor(1, 1, 1, 1); - screen_target->clear(GL_COLOR_BUFFER_BIT); - glClearColor(0, 0, 0, 0); - - bindDeferredShader(gDeferredBlurLightProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - LLVector3 go = RenderShadowGaussian; - const U32 kern_length = 4; - F32 blur_size = RenderShadowBlurSize; - F32 dist_factor = RenderShadowBlurDistFactor; - - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = 0.f; - - LLVector3 gauss[32]; // xweight, yweight, offset - - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; + { + /*if (gCubeSnapshot) + { // SSAO and shadows disabled in reflection maps + deferred_light_target->bindTarget(); + glClearColor(1, 1, 1, 1); + deferred_light_target->clear(); + glClearColor(0, 0, 0, 0); + deferred_light_target->flush(); } + else*/ + { + // soften direct lighting lightmap + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow"); + LL_PROFILE_GPU_ZONE("soften shadow"); + // blur lightmap + screen_target->bindTarget(); + glClearColor(1, 1, 1, 1); + screen_target->clear(GL_COLOR_BUFFER_BIT); + glClearColor(0, 0, 0, 0); - gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); - gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f)); + bindDeferredShader(gDeferredBlurLightProgram); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + LLVector3 go = RenderShadowGaussian; + const U32 kern_length = 4; + F32 blur_size = RenderShadowBlurSize; + F32 dist_factor = RenderShadowBlurDistFactor; - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); - } + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = 0.f; - screen_target->flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + LLVector3 gauss[32]; // xweight, yweight, offset - bindDeferredShader(gDeferredBlurLightProgram, screen_target); + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - deferred_light_target->bindTarget(); + gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); + gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); + gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f)); - gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); + } - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + screen_target->flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + + bindDeferredShader(gDeferredBlurLightProgram, screen_target); + + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + deferred_light_target->bindTarget(); + + gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); + } + deferred_light_target->flush(); + unbindDeferredShader(gDeferredBlurLightProgram); } - deferred_light_target->flush(); - unbindDeferredShader(gDeferredBlurLightProgram); } stop_glerror(); @@ -8511,12 +8636,19 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics"); + LL_PROFILE_GPU_ZONE("atmospherics"); bindDeferredShader(soften_shader); LLEnvironment &environment = LLEnvironment::instance(); soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); + if(LLPipeline::sRenderPBR) + { + LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis(); + soften_shader.uniform3fv(LLShaderMgr::DEFERRED_VIEW_DIR, 1, cameraAtAxis.mV); + } + { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -8557,7 +8689,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) gPipeline.popRenderTypeMask(); } - bool render_local = RenderLocalLights; + bool render_local = RenderLocalLights; // && !gCubeSnapshot; if (render_local) { @@ -8566,9 +8698,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) LLDrawable::drawable_list_t spot_lights; LLDrawable::drawable_list_t fullscreen_spot_lights; - for (U32 i = 0; i < 2; i++) + if (!gCubeSnapshot) { - mTargetShadowSpotLight[i] = NULL; + for (U32 i = 0; i < 2; i++) + { + mTargetShadowSpotLight[i] = NULL; + } } std::list<LLVector4> light_colors; @@ -8577,6 +8712,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - local lights"); + LL_PROFILE_GPU_ZONE("local lights"); bindDeferredShader(gDeferredLightProgram); if (mCubeVB.isNull()) @@ -8683,6 +8819,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) if (!spot_lights.empty()) { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - projectors"); + LL_PROFILE_GPU_ZONE("projectors"); LLGLDepthTest depth(GL_TRUE, GL_FALSE); bindDeferredShader(gDeferredSpotLightProgram); @@ -8729,7 +8866,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - fullscreen lights"); LLGLDepthTest depth(GL_FALSE); - + LL_PROFILE_GPU_ZONE("fullscreen lights"); // full screen blit gGL.pushMatrix(); gGL.loadIdentity(); @@ -8825,6 +8962,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) gGL.loadIdentity(); { + LL_PROFILE_GPU_ZONE("gamma correct"); LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLVector2 tc1(0, 0); @@ -8904,6 +9042,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) popRenderTypeMask(); } + if (!gCubeSnapshot) { // render highlights, etc. renderHighlights(); @@ -9015,6 +9154,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f); } + //if (!gCubeSnapshot) { LLDrawable* potential = drawablep; //determine if this is a good light for casting shadows @@ -9066,14 +9206,15 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { - LLRenderTarget* deferred_target = &mDeferredScreen; - LLRenderTarget* deferred_depth_target = &mDeferredDepth; - LLRenderTarget* deferred_light_target = &mDeferredLight; + LLRenderTarget* deferred_target = &mRT->deferredScreen; + LLRenderTarget* deferred_depth_target = &mRT->deferredDepth; + LLRenderTarget* deferred_light_target = &mRT->deferredLight; stop_glerror(); shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage()); shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage()); shader.disableTexture(LLShaderMgr::DIFFUSE_MAP); @@ -9107,11 +9248,59 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) cube_map->disable(); } } + + unbindReflectionProbes(shader); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->activate(); shader.unbind(); } +void LLPipeline::bindReflectionProbes(LLGLSLShader& shader) +{ + S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + bool bound = false; + if (channel > -1 && mReflectionMapManager.mTexture.notNull()) + { + mReflectionMapManager.mTexture->bind(channel); + bound = true; + } + + channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); + if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull()) + { + mReflectionMapManager.mIrradianceMaps->bind(channel); + bound = true; + } + + if (bound) + { + mReflectionMapManager.setUniforms(); + + F32* m = gGLModelView; + + F32 mat[] = { m[0], m[1], m[2], + m[4], m[5], m[6], + m[8], m[9], m[10] }; + + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); + } +} + +void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader) +{ + S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP); + if (channel > -1 && mReflectionMapManager.mTexture.notNull()) + { + mReflectionMapManager.mTexture->unbind(); + if (channel == 0) + { + gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE); + } + } +} + + inline float sgn(float a) { if (a > 0.0F) return (1.0F); @@ -9122,8 +9311,9 @@ inline float sgn(float a) void LLPipeline::generateWaterReflection(LLCamera& camera_in) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("generateWaterReflection"); - if (!assertInitialized()) + if (!assertInitialized() || gCubeSnapshot) { return; } @@ -9533,7 +9723,7 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbri void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); - + LL_PROFILE_GPU_ZONE("renderShadow"); //disable occlusion culling for shadow passes (save setting to restore later) S32 occlude = LLPipeline::sUseOcclusion; if (!use_occlusion) @@ -9556,6 +9746,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLRenderPass::PASS_NORMMAP_EMISSIVE, LLRenderPass::PASS_NORMSPEC, LLRenderPass::PASS_NORMSPEC_EMISSIVE, + LLRenderPass::PASS_PBR_OPAQUE, // NOTE: Assumes PASS_PBR_OPAQUE_RIGGED is consecutive + //LLRenderPass::PASS_PBR_OPAQUE_RIGGED, }; LLGLEnable cull(GL_CULL_FACE); @@ -9568,7 +9760,9 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gDeferredShadowCubeProgram.bind(); } - LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1]; + LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ? + mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] : + mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0]; occlusion_target.bindTarget(); updateCull(shadow_cam, result); @@ -9620,7 +9814,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera } LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); - + LL_PROFILE_GPU_ZONE("shadow simple"); gGL.getTexUnit(0)->disable(); for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i) { @@ -9653,7 +9847,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); - + LL_PROFILE_GPU_ZONE("shadow alpha"); for (int i = 0; i < 2; ++i) { bool rigged = i == 1; @@ -9712,9 +9906,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); - LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1]; + LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ? + mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] : + mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0]; - doOcclusion(shadow_cam, occlusion_source, occlusion_target); + if (occlude > 1) + { + doOcclusion(shadow_cam, occlusion_source, occlusion_target); + } if (use_shader) { @@ -9935,7 +10134,8 @@ void LLPipeline::generateHighlight(LLCamera& camera) { mHighlightSet.insert(HighlightItem(mHighlightObject)); } - + llassert(!gCubeSnapshot); + if (!mHighlightSet.empty()) { F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime; @@ -9983,9 +10183,16 @@ void LLPipeline::generateHighlight(LLCamera& camera) } } -LLRenderTarget* LLPipeline::getShadowTarget(U32 i) +LLRenderTarget* LLPipeline::getSunShadowTarget(U32 i) +{ + llassert(i < 4); + return &mRT->shadow[i]; +} + +LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i) { - return &mShadow[i]; + llassert(i < 2); + return &mSpotShadow[i]; } static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); @@ -9999,6 +10206,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); + LL_PROFILE_GPU_ZONE("generateSunShadow"); bool skip_avatar_update = false; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) @@ -10081,6 +10289,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED, LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED, LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED, + LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE, + LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE_RIGGED, END_RENDER_TYPES); gGL.setColorMask(false, false); @@ -10110,6 +10320,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera) clip = RenderShadowOrthoClipPlanes; mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); + //if (gCubeSnapshot) + { //always do a single 64m shadow in reflection maps + mSunClipPlanes.set(64.f, 128.f, 256.f); + mSunOrthoClipPlanes.set(64.f, 128.f, 256.f); + } + //currently used for amount to extrude frusta corners for constructing shadow frusta //LLVector3 n = RenderShadowNearDist; //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; @@ -10226,28 +10442,41 @@ void LLPipeline::generateSunShadow(LLCamera& camera) // convenience array of 4 near clip plane distances F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; - if (mSunDiffuse == LLColor4::black) - { //sun diffuse is totally black, shadows don't matter + { //sun diffuse is totally shadows don't matter LLGLDepthTest depth(GL_TRUE); for (S32 j = 0; j < 4; j++) { - mShadow[j].bindTarget(); - mShadow[j].clear(); - mShadow[j].flush(); + mRT->shadow[j].bindTarget(); + mRT->shadow[j].clear(); + mRT->shadow[j].flush(); } } else { - for (S32 j = 0; j < 4; j++) + /*if (gCubeSnapshot) + { + // do one shadow split for cube snapshots, clear the rest + mSunClipPlanes.set(64.f, 64.f, 64.f); + dist[1] = dist[2] = dist[3] = dist[4] = 64.f; + for (S32 j = 1; j < 4; j++) + { + mRT->shadow[j].bindTarget(); + mRT->shadow[j].clear(); + mRT->shadow[j].flush(); + } + }*/ + + //for (S32 j = 0; j < (gCubeSnapshot ? 1 : 4); j++) + for (S32 j = 0; j < 4; j++) { if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) { mShadowFrustPoints[j].clear(); } - LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j); + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j); //restore render matrices set_current_modelview(saved_view); @@ -10301,12 +10530,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowCamera[j+4] = shadow_cam; } - mShadow[j].bindTarget(); + mRT->shadow[j].bindTarget(); { LLGLDepthTest depth(GL_TRUE); - mShadow[j].clear(); + mRT->shadow[j].clear(); } - mShadow[j].flush(); + mRT->shadow[j].flush(); mShadowError.mV[j] = 0.f; mShadowFOV.mV[j] = 0.f; @@ -10593,18 +10822,18 @@ void LLPipeline::generateSunShadow(LLCamera& camera) stop_glerror(); - mShadow[j].bindTarget(); - mShadow[j].getViewport(gGLViewport); - mShadow[j].clear(); + mRT->shadow[j].bindTarget(); + mRT->shadow[j].getViewport(gGLViewport); + mRT->shadow[j].clear(); - U32 target_width = mShadow[j].getWidth(); + U32 target_width = mRT->shadow[j].getWidth(); { static LLCullResult result[4]; renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width); } - mShadow[j].flush(); + mRT->shadow[j].flush(); if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { @@ -10619,142 +10848,150 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (gen_shadow) { - LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); - F32 fade_amt = gFrameIntervalSeconds.value() - * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); + if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates + { + LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); + F32 fade_amt = gFrameIntervalSeconds.value() + * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); - //update shadow targets - for (U32 i = 0; i < 2; i++) - { //for each current shadow - LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i); + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i); + + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i] + fade_amt, 1.f); + } + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i] - fade_amt, 0.f); - if (mShadowSpotLight[i].notNull() && - (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || - mShadowSpotLight[i] == mTargetShadowSpotLight[1])) - { //keep this spotlight - mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); - } - else - { //fade out this light - mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); - - if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) - { //faded out, grab one of the pending spots (whichever one isn't already taken) - if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) - { - mShadowSpotLight[i] = mTargetShadowSpotLight[0]; - } - else - { - mShadowSpotLight[i] = mTargetShadowSpotLight[1]; - } - } - } - } + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i + 1) % 2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + } + } + } + } + } - for (S32 i = 0; i < 2; i++) - { - set_current_modelview(saved_view); - set_current_projection(saved_proj); + for (S32 i = 0; i < 2; i++) + { + set_current_modelview(saved_view); + set_current_projection(saved_proj); - if (mShadowSpotLight[i].isNull()) - { - continue; - } + if (mShadowSpotLight[i].isNull()) + { + continue; + } - LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); - if (!volume) - { - mShadowSpotLight[i] = NULL; - continue; - } + if (!volume) + { + mShadowSpotLight[i] = NULL; + continue; + } - LLDrawable* drawable = mShadowSpotLight[i]; + LLDrawable* drawable = mShadowSpotLight[i]; - LLVector3 params = volume->getSpotLightParams(); - F32 fov = params.mV[0]; + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; - //get agent->light space matrix (modelview) - LLVector3 center = drawable->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); - //get near clip plane - LLVector3 scale = volume->getScale(); - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0, 0, -scale.mV[2] * 0.5f); + at_axis *= quat; - LLVector3 np = center+at_axis; - at_axis.normVec(); + LLVector3 np = center + at_axis; + at_axis.normVec(); - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1] * 0.5f) / tanf(fov * 0.5f); - LLVector3 origin = np - at_axis*dist; + LLVector3 origin = np - at_axis * dist; - LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); - view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + view[i + 4] = glh::matrix4f((F32*)mat.mMatrix); - view[i+4] = view[i+4].inverse(); + view[i + 4] = view[i + 4].inverse(); - //get perspective matrix - F32 near_clip = dist+0.01f; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = dist+volume->getLightRadius()*1.5f; + //get perspective matrix + F32 near_clip = dist + 0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist + volume->getLightRadius() * 1.5f; - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; - - proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width / height; - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + proj[i + 4] = gl_perspective(fovy, aspect, near_clip, far_clip); - set_current_modelview(view[i+4]); - set_current_projection(proj[i+4]); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - - for (U32 j = 0; j < 16; j++) - { - gGLLastModelView[j] = mShadowModelview[i+4].m[j]; - gGLLastProjection[j] = mShadowProjection[i+4].m[j]; - } + set_current_modelview(view[i + 4]); + set_current_projection(proj[i + 4]); - mShadowModelview[i+4] = view[i+4]; - mShadowProjection[i+4] = proj[i+4]; + mSunShadowMatrix[i + 4] = trans * proj[i + 4] * view[i + 4] * inv_view; - LLCamera shadow_cam = camera; - shadow_cam.setFar(far_clip); - shadow_cam.setOrigin(origin); + for (U32 j = 0; j < 16; j++) + { + gGLLastModelView[j] = mShadowModelview[i + 4].m[j]; + gGLLastProjection[j] = mShadowProjection[i + 4].m[j]; + } - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + mShadowModelview[i + 4] = view[i + 4]; + mShadowProjection[i + 4] = proj[i + 4]; - stop_glerror(); + if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates + { + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); + + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + + stop_glerror(); - mShadow[i+4].bindTarget(); - mShadow[i+4].getViewport(gGLViewport); - mShadow[i+4].clear(); + // + + mSpotShadow[i].bindTarget(); + mSpotShadow[i].getViewport(gGLViewport); + mSpotShadow[i].clear(); - U32 target_width = mShadow[i+4].getWidth(); + U32 target_width = mSpotShadow[i].getWidth(); - static LLCullResult result[2]; + static LLCullResult result[2]; - LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i); - RenderSpotLight = drawable; + RenderSpotLight = drawable; - renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); + renderShadow(view[i + 4], proj[i + 4], shadow_cam, result[i], FALSE, FALSE, target_width); - RenderSpotLight = nullptr; + RenderSpotLight = nullptr; - mShadow[i+4].flush(); - } + mSpotShadow[i].flush(); + } + } } else { //no spotlight shadows @@ -10827,6 +11064,7 @@ static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor"); void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) { LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR); + LL_PROFILE_GPU_ZONE("generateImpostor"); LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -11095,7 +11333,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) if (LLPipeline::sRenderDeferred) { GLuint buff = GL_COLOR_ATTACHMENT0; - LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF ); glDrawBuffersARB(1, &buff); } @@ -11496,3 +11733,9 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id ) } } +void LLPipeline::overrideEnvironmentMap() +{ + //mReflectionMapManager.mProbes.clear(); + //mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin()); +} + |