summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r--indra/newview/pipeline.cpp388
1 files changed, 270 insertions, 118 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 283be64af4..327a51de85 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -43,6 +43,7 @@
#include "llui.h"
#include "llglheaders.h"
#include "llrender.h"
+#include "llstartup.h"
#include "llwindow.h" // swapBuffers()
// newview includes
@@ -127,6 +128,7 @@ U32 LLPipeline::RenderFSAASamples;
U32 LLPipeline::RenderResolutionDivisor;
bool LLPipeline::RenderUIBuffer;
S32 LLPipeline::RenderShadowDetail;
+S32 LLPipeline::RenderShadowSplits;
bool LLPipeline::RenderDeferredSSAO;
F32 LLPipeline::RenderShadowResolutionScale;
bool LLPipeline::RenderLocalLights;
@@ -200,6 +202,7 @@ LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
+const F32 ALPHA_BLEND_CUTOFF = 0.598f;
const F32 DEFERRED_LIGHT_FALLOFF = 0.5f;
const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
@@ -486,6 +489,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
connectRefreshCachedSettingsSafe("RenderUIBuffer");
connectRefreshCachedSettingsSafe("RenderShadowDetail");
+ connectRefreshCachedSettingsSafe("RenderShadowSplits");
connectRefreshCachedSettingsSafe("RenderDeferredSSAO");
connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");
connectRefreshCachedSettingsSafe("RenderLocalLights");
@@ -559,7 +563,6 @@ void LLPipeline::init()
LLPipeline::~LLPipeline()
{
-
}
void LLPipeline::cleanup()
@@ -971,10 +974,11 @@ void LLPipeline::refreshCachedSettings()
WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders");
RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
- RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
+ RenderFSAASamples = LLFeatureManager::getInstance()->isFeatureAvailable("RenderFSAASamples") ? gSavedSettings.getU32("RenderFSAASamples") : 0;
RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
+ RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits");
RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights");
@@ -2250,12 +2254,18 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
+// static
+bool LLPipeline::isWaterClip()
+{
+ return (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs;
+}
+
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
LL_PROFILE_GPU_ZONE("updateCull"); // should always be zero GPU time, but drop a timer to flush stuff out
- bool water_clip = !sRenderTransparentWater && !sRenderingHUDs;
+ bool water_clip = isWaterClip();
if (water_clip)
{
@@ -3027,18 +3037,6 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
{
if (drawablep && !drawablep->isDead() && assertInitialized())
{
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- LLVOVolume *vol_obj = drawablep->getVOVolume();
- if (vol_obj && vol_obj->isAnimatedObject() && vol_obj->isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", vol_obj);
- F32 est_tris = vol_obj->getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " markRebuild, tris " << est_tris
- << " priority " << (S32) priority << " flag " << std::hex << flag << LL_ENDL;
- }
- }
-
if (!drawablep->isState(LLDrawable::BUILT))
{
priority = true;
@@ -5492,7 +5490,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
LLDrawable* drawable = light->drawable;
const LLViewerObject *vobj = light->drawable->getVObj();
if(vobj && vobj->getAvatar()
- && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList())
+ && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlow())
)
{
drawable->clearState(LLDrawable::NEARBY_LIGHT);
@@ -5571,7 +5569,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
continue;
}
LLVOAvatar * av = light->getAvatar();
- if (av && (av->isTooComplex() || av->isInMuteList()))
+ if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlow()))
{
// avatars that are already in the list will be removed by removeMutedAVsLights
continue;
@@ -6776,6 +6774,8 @@ void LLPipeline::renderAlphaObjects(bool rigged)
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
+ S32 sun_up = LLEnvironment::instance().getIsSunUp() ? 1 : 0;
+ U32 target_width = LLRenderTarget::sCurResX;
U32 type = LLRenderPass::PASS_ALPHA;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
@@ -6798,10 +6798,18 @@ void LLPipeline::renderAlphaObjects(bool rigged)
{
if (pparams->mGLTFMaterial)
{
+ gDeferredShadowGLTFAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
mSimplePool->pushRiggedGLTFBatch(*pparams, lastAvatar, lastMeshId);
}
else
{
+ gDeferredShadowAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
mSimplePool->uploadMatrixPalette(*pparams);
@@ -6809,18 +6817,26 @@ void LLPipeline::renderAlphaObjects(bool rigged)
lastMeshId = pparams->mSkinInfo->mHash;
}
- mSimplePool->pushBatch(*pparams, true, true, true);
+ mSimplePool->pushBatch(*pparams, true, true);
}
}
else
{
if (pparams->mGLTFMaterial)
{
+ gDeferredShadowGLTFAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
mSimplePool->pushGLTFBatch(*pparams);
}
else
{
- mSimplePool->pushBatch(*pparams, true, true, true);
+ gDeferredShadowAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
+ mSimplePool->pushBatch(*pparams, true, true);
}
}
}
@@ -6837,11 +6853,11 @@ void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture,
gGLLastMatrix = NULL;
if (rigged)
{
- mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture, true);
+ mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture);
}
else
{
- mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture, true);
+ mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture);
}
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
@@ -6855,11 +6871,11 @@ void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batc
gGLLastMatrix = NULL;
if (rigged)
{
- mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture, true);
+ mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture);
}
else
{
- mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture, true);
+ mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture);
}
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
@@ -6927,7 +6943,8 @@ void LLPipeline::bindScreenToTexture()
static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
-void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex) {
+void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex)
+{
dst->bindTarget();
gDeferredBufferVisualProgram.bind();
gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex);
@@ -6944,7 +6961,8 @@ void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32
dst->flush();
}
-void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
+{
// luminance sample and mipmap generation
{
LL_PROFILE_GPU_ZONE("luminance sample");
@@ -7020,9 +7038,19 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f);
static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f);
+ F32 exposure_max = dynamic_exposure_max;
+ LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
+
+ if (sky->getReflectionProbeAmbiance() > 0.f)
+ { //not a legacy sky, use gamma as a boost to max exposure
+ exposure_max = llmax(exposure_max - 1.f, 0.f);
+ exposure_max *= sky->getGamma();
+ exposure_max += 1.f;
+ }
+
gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
- gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max);
+ gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, exposure_max);
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -7039,18 +7067,25 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
{
LL_PROFILE_GPU_ZONE("gamma correct");
+ static LLCachedControl<bool> no_post(gSavedSettings, "RenderDisablePostProcessing", false);
+
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
// Apply gamma correction to the frame here.
- gDeferredPostGammaCorrectProgram.bind();
+
+ LLGLSLShader& shader = no_post && gFloaterTools->isAvailable() ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
+ LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance() == 0.f ? gLegacyPostGammaCorrectProgram :
+ gDeferredPostGammaCorrectProgram;
+
+ shader.bind();
S32 channel = 0;
- gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
+ shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
- gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
+ shader.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight());
static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
@@ -7058,18 +7093,19 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
static LLStaticHashedString s_exposure("exposure");
- gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
+ shader.uniform1f(s_exposure, e);
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
gGL.getTexUnit(channel)->unbind(src->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
+ shader.unbind();
}
dst->flush();
}
-void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst)
+{
if (RenderScreenSpaceReflections && !gCubeSnapshot)
{
@@ -7095,7 +7131,8 @@ void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget*
}
}
-void LLPipeline::generateGlow(LLRenderTarget* src) {
+void LLPipeline::generateGlow(LLRenderTarget* src)
+{
if (sRenderGlow)
{
LL_PROFILE_GPU_ZONE("glow");
@@ -7192,7 +7229,8 @@ void LLPipeline::generateGlow(LLRenderTarget* src) {
}
}
-void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
+{
{
llassert(!gCubeSnapshot);
bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
@@ -7272,7 +7310,8 @@ void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
}
}
-void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst)
+{
LL_PROFILE_GPU_ZONE("copyRenderTarget");
dst->bindTarget();
@@ -7292,7 +7331,8 @@ void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
dst->flush();
}
-void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst)
+{
// Go ahead and do our glow combine here in our destination. We blit this later into the front buffer.
dst->bindTarget();
@@ -7311,7 +7351,8 @@ void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) {
dst->flush();
}
-void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
+void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst)
+{
{
bool dof_enabled =
(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
@@ -7477,10 +7518,12 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
{ // combine result based on alpha
dst->bindTarget();
- if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete()) {
+ if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete())
+ {
glViewport(0, 0, dst->getWidth(), dst->getHeight());
}
- else {
+ else
+ {
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
@@ -7515,6 +7558,7 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
void LLPipeline::renderFinalize()
{
+ llassert(!gCubeSnapshot);
LLVertexBuffer::unbind();
LLGLState::checkStates();
@@ -7535,22 +7579,20 @@ void LLPipeline::renderFinalize()
gGL.setColorMask(true, true);
glClearColor(0, 0, 0, 0);
- if (!gCubeSnapshot)
- {
- copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
+
+ copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
- generateLuminance(&mRT->screen, &mLuminanceMap);
+ generateLuminance(&mRT->screen, &mLuminanceMap);
- generateExposure(&mLuminanceMap, &mExposureMap);
+ generateExposure(&mLuminanceMap, &mExposureMap);
- gammaCorrect(&mRT->screen, &mPostMap);
+ gammaCorrect(&mRT->screen, &mPostMap);
- LLVertexBuffer::unbind();
- }
+ LLVertexBuffer::unbind();
- generateGlow(&mPostMap);
+ generateGlow(&mPostMap);
- combineGlow(&mPostMap, &mRT->screen);
+ combineGlow(&mPostMap, &mRT->screen);
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
@@ -7562,7 +7604,8 @@ void LLPipeline::renderFinalize()
applyFXAA(&mPostMap, &mRT->screen);
LLRenderTarget* finalBuffer = &mRT->screen;
- if (RenderBufferVisualization > -1) {
+ if (RenderBufferVisualization > -1)
+ {
finalBuffer = &mPostMap;
switch (RenderBufferVisualization)
{
@@ -7663,10 +7706,18 @@ void LLPipeline::bindShadowMaps(LLGLSLShader& shader)
void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader)
{
- shader.bind();
- bindLightFunc(shader);
- bindShadowMaps(shader);
- bindReflectionProbes(shader);
+ if (shader.mCanBindFast)
+ { // was previously fully bound, use fast path
+ shader.bind();
+ bindLightFunc(shader);
+ bindShadowMaps(shader);
+ bindReflectionProbes(shader);
+ }
+ else
+ { //wasn't previously bound, use slow path
+ bindDeferredShader(shader);
+ shader.mCanBindFast = true;
+ }
}
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
@@ -8826,8 +8877,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
stop_glerror();
- LLEnvironment& environment = LLEnvironment::instance();
-
struct CompareVertexBuffer
{
bool operator()(const LLDrawInfo* const& lhs, const LLDrawInfo* const& rhs)
@@ -8842,7 +8891,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
bool rigged = j == 1;
gDeferredShadowProgram.bind(rigged);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
gGL.diffuseColor4f(1, 1, 1, 1);
@@ -8887,27 +8935,25 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha");
LL_PROFILE_GPU_ZONE("shadow alpha");
-
+ const S32 sun_up = LLEnvironment::instance().getIsSunUp() ? 1 : 0;
U32 target_width = LLRenderTarget::sCurResX;
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
- gDeferredShadowAlphaMaskProgram.bind(rigged);
- LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
-
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked");
LL_PROFILE_GPU_ZONE("shadow alpha masked");
+ gDeferredShadowAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, true, true, rigged);
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend");
LL_PROFILE_GPU_ZONE("shadow alpha blend");
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
renderAlphaObjects(rigged);
}
@@ -8915,8 +8961,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked");
LL_PROFILE_GPU_ZONE("shadow alpha masked");
gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true, rigged);
}
@@ -8924,9 +8970,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass");
LL_PROFILE_GPU_ZONE("shadow alpha grass");
gDeferredTreeShadowProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
+
if (i == 0)
{
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, true);
}
@@ -8945,8 +8992,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
bool rigged = i == 1;
gDeferredShadowGLTFAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
@@ -9449,14 +9496,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (mSunDiffuse == LLColor4::black)
{ //sun diffuse is totally black shadows don't matter
- LLGLDepthTest depth(GL_TRUE);
-
- for (S32 j = 0; j < 4; j++)
- {
- mRT->shadow[j].bindTarget();
- mRT->shadow[j].clear();
- mRT->shadow[j].flush();
- }
+ skipRenderingShadows();
}
else
{
@@ -9512,7 +9552,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
std::vector<LLVector3> fp;
- if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
+ if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)
+ || j > RenderShadowSplits)
{
//no possible shadow receivers
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
@@ -10051,11 +10092,79 @@ void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture)
}
}
-static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");
+void LLPipeline::profileAvatar(LLVOAvatar* avatar, bool profile_attachments)
+{
+ if (gGLManager.mGLVersion < 3.25f)
+ { // profiling requires GL 3.3 or later
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+
+ // don't continue to profile an avatar that is known to be too slow
+ llassert(!avatar->isTooSlow());
+
+ LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ mRT->deferredScreen.bindTarget();
+ mRT->deferredScreen.clear();
+
+ if (!profile_attachments)
+ {
+ // profile entire avatar all at once and readback asynchronously
+ avatar->placeProfileQuery();
+
+ LLTimer cpu_timer;
+
+ generateImpostor(avatar, false, true);
+
+ avatar->mCPURenderTime = (F32)cpu_timer.getElapsedTimeF32() * 1000.f;
+
+ avatar->readProfileQuery(5); // allow up to 5 frames of latency
+ }
+ else
+ {
+ // profile attachments one at a time
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ for (iter = begin;
+ iter != end;
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ // use gDebugProgram to do the GPU queries
+ gDebugProgram.clearStats();
+ gDebugProgram.placeProfileQuery(true);
+
+ generateImpostor(avatar, false, true, attached_object);
+ gDebugProgram.readProfileQuery(true, true);
+
+ attached_object->mGPURenderTime = gDebugProgram.mTimeElapsed / 1000000.f;
+ }
+ }
+ }
+ }
+
+ mRT->deferredScreen.flush();
-void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
+ if (cur_shader)
+ {
+ cur_shader->bind();
+ }
+}
+
+void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool for_profile, LLViewerObject* specific_attachment)
{
- LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("generateImpostor");
LLGLState::checkStates();
@@ -10073,19 +10182,19 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
assertInitialized();
// previews can't be muted or impostered
- bool visually_muted = !preview_avatar && avatar->isVisuallyMuted();
+ bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( visually_muted ? "" : "not ") << "visually muted"
<< LL_ENDL;
- bool too_complex = !preview_avatar && avatar->isTooComplex();
+ bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( too_complex ? "" : "not ") << "too complex"
<< LL_ENDL;
- pushRenderTypeMask();
-
- if (visually_muted || too_complex)
- {
+ pushRenderTypeMask();
+
+ if (visually_muted || too_complex)
+ {
// only show jelly doll geometry
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV,
@@ -10103,6 +10212,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
RENDER_TYPE_TREE,
RENDER_TYPE_VOIDWATER,
RENDER_TYPE_WATER,
+ RENDER_TYPE_ALPHA_POST_WATER,
RENDER_TYPE_PASS_GRASS,
RENDER_TYPE_HUD,
RENDER_TYPE_PARTICLES,
@@ -10112,6 +10222,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
);
}
+ if (specific_attachment && specific_attachment->isHUDAttachment())
+ { //enable HUD rendering
+ setRenderTypeMask(RENDER_TYPE_HUD, END_RENDER_TYPES);
+ }
+
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
@@ -10168,20 +10283,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
}
else
{
- LLVOAvatar::attachment_map_t::iterator iter;
- for (iter = avatar->mAttachmentPoints.begin();
- iter != avatar->mAttachmentPoints.end();
- ++iter)
+ if (specific_attachment)
{
- LLViewerJointAttachment *attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ markVisible(specific_attachment->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ else
+ {
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ for (iter = begin;
+ iter != end;
+ ++iter)
{
- LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object)
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
}
}
}
@@ -10251,25 +10376,28 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
- if (!avatar->mImpostor.isComplete())
- {
- avatar->mImpostor.allocate(resX, resY, GL_RGBA, true);
+ if (!for_profile)
+ {
+ if (!avatar->mImpostor.isComplete())
+ {
+ avatar->mImpostor.allocate(resX, resY, GL_RGBA, true);
- if (LLPipeline::sRenderDeferred)
- {
- addDeferredAttachments(avatar->mImpostor, true);
- }
-
- gGL.getTexUnit(0)->bind(&avatar->mImpostor);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
- {
- avatar->mImpostor.resize(resX,resY);
- }
+ if (LLPipeline::sRenderDeferred)
+ {
+ addDeferredAttachments(avatar->mImpostor, true);
+ }
+
+ gGL.getTexUnit(0)->bind(&avatar->mImpostor);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ else if (resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
+ {
+ avatar->mImpostor.resize(resX, resY);
+ }
- avatar->mImpostor.bindTarget();
+ avatar->mImpostor.bindTarget();
+ }
}
F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
@@ -10279,9 +10407,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
LLDrawPoolAvatar::sMinimumAlpha = 0.f;
}
- if (preview_avatar)
+ if (preview_avatar || for_profile)
{
- // previews don't care about imposters
+ // previews and profiles don't care about imposters
renderGeomDeferred(camera);
renderGeomPostDeferred(camera);
}
@@ -10310,6 +10438,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+ if (!for_profile)
{ //create alpha mask based on depth buffer (grey out if muted)
if (LLPipeline::sRenderDeferred)
{
@@ -10371,7 +10500,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
gGL.popMatrix();
}
- if (!preview_avatar)
+ if (!preview_avatar && !for_profile)
{
avatar->mImpostor.flush();
avatar->setImpostorDim(tdim);
@@ -10388,7 +10517,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
- if (!preview_avatar)
+ if (!preview_avatar && !for_profile)
{
avatar->mNeedsImpostorUpdate = FALSE;
avatar->cacheImpostorValues();
@@ -10713,9 +10842,32 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
+void LLPipeline::skipRenderingShadows()
+{
+ LLGLDepthTest depth(GL_TRUE);
+
+ for (S32 j = 0; j < 4; j++)
+ {
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].clear();
+ mRT->shadow[j].flush();
+ }
+}
+
+void LLPipeline::handleShadowDetailChanged()
+{
+ if (RenderShadowDetail > gSavedSettings.getS32("RenderShadowDetail"))
+ {
+ skipRenderingShadows();
+ }
+ else
+ {
+ LLViewerShaderMgr::instance()->setShaders();
+ }
+}
+
void LLPipeline::overrideEnvironmentMap()
{
//mReflectionMapManager.mProbes.clear();
//mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin());
}
-