From 5988f6cf88056c9c14a30efd193632e0767a130a Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 27 Mar 2014 21:27:40 -0500 Subject: [PATCH 1/5] Updated rigged mesh face batch/pool handling. Fixed issue with fullbright and glow occlusion. RenderTransparentWater toggling should work more gracefully. Fixed some bugs in general drawpool classification for faces. Bump pool was superceding more than it should have. --- indra/newview/lldrawpoolavatar.cpp | 4 +- indra/newview/lldrawpoolsimple.cpp | 14 +++- indra/newview/llface.cpp | 7 +- indra/newview/llviewercontrol.cpp | 6 ++ indra/newview/llvovolume.cpp | 129 ++++++++++++++++++++++++----- indra/newview/llvowater.cpp | 2 +- indra/newview/pipeline.cpp | 44 +++++----- 7 files changed, 157 insertions(+), 49 deletions(-) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index eba3d2606..42dcd4547 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1951,7 +1951,7 @@ void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) LLRender::BF_ONE_MINUS_SOURCE_ALPHA); renderRigged(avatar, RIGGED_ALPHA); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + //gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setColorMask(true, false); } } @@ -1969,7 +1969,7 @@ void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) LLRender::BF_ONE_MINUS_SOURCE_ALPHA); renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + //gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setColorMask(true, false); } } diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 012a4b9dd..a0d6dbf92 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -548,11 +548,17 @@ void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) { if (LLPipeline::sUnderWaterRender) { - gDeferredFullbrightWaterProgram.bind(); + //gDeferredFullbrightWaterProgram.bind(); + //Use alpha-mask version to ignore alpha values while still allowing us to occlude glow. + gDeferredFullbrightAlphaMaskWaterProgram.bind(); + gDeferredFullbrightAlphaMaskWaterProgram.setMinimumAlpha(0.f); } else { - gDeferredFullbrightProgram.bind(); + //gDeferredFullbrightProgram.bind(); + //Use alpha-mask version to ignore alpha values while still allowing us to occlude glow. + gDeferredFullbrightAlphaMaskProgram.bind(); + gDeferredFullbrightAlphaMaskProgram.setMinimumAlpha(0.f); } } @@ -573,11 +579,11 @@ void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) { if (LLPipeline::sUnderWaterRender) { - gDeferredFullbrightWaterProgram.unbind(); + gDeferredFullbrightAlphaMaskWaterProgram.unbind(); } else { - gDeferredFullbrightProgram.unbind(); + gDeferredFullbrightAlphaMaskProgram.unbind(); } LLRenderPass::endRenderPass(pass); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5947a0717..15430989e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1338,9 +1338,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - if (shiny_in_alpha) + if(getPoolType() == LLDrawPool::POOL_FULLBRIGHT) + { + color.mV[3] = 1.f; //Simple fullbright reads alpha for fog contrib, not shiny/transparency, so since opaque, force to 1. + } + else if (shiny_in_alpha) { - GLfloat alpha[4] = { 0.00f, diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 1229fef67..bd54b6195 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -204,6 +204,12 @@ bool handleRenderAvatarComplexityLimitChanged(const LLSD& newvalue) bool handleRenderTransparentWaterChanged(const LLSD& newvalue) { + LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && gSavedSettings.getBOOL("VertexShaderEnable"); + if (gPipeline.isInit()) //If water is opaque then distortion/reflection fbos will not be needed. + { + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); + } LLWorld::getInstance()->updateWaterObjects(); return true; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ea9e5605c..121b4388c 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4191,10 +4191,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); + + U32 pool_type = facep->getPoolType(); bool cmp_bump = (type == LLRenderPass::PASS_BUMP) || (type == LLRenderPass::PASS_POST_BUMP); - bool cmp_shiny = !alt_batching ? !!mat : ((type == LLRenderPass::PASS_SHINY) || (type == LLRenderPass::PASS_FULLBRIGHT_SHINY) || (type == LLRenderPass::PASS_INVISI_SHINY)); - bool cmp_mat = !alt_batching || LLPipeline::sRenderDeferred && ((facep->getPoolType() == LLDrawPool::POOL_MATERIALS) || (facep->getPoolType() == LLDrawPool::POOL_ALPHA)); + bool cmp_mat = (!alt_batching) || LLPipeline::sRenderDeferred && facep->getTextureEntry()->getColor().mV[3] >= 0.999f && + ((pool_type == LLDrawPool::POOL_MATERIALS) || (pool_type == LLDrawPool::POOL_ALPHA)); + bool cmp_shiny = (!alt_batching) ? !!mat : (mat && cmp_mat); + bool cmp_fullbright = !alt_batching || cmp_shiny || pool_type == LLDrawPool::POOL_ALPHA; U8 bump = facep->getTextureEntry()->getBumpmap(); U8 shiny = facep->getTextureEntry()->getShiny(); @@ -4209,7 +4213,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 shader_mask = 0xFFFFFFFF; //no shader - if (mat) + if (mat && cmp_mat) { if (type == LLRenderPass::PASS_ALPHA) { @@ -4255,9 +4259,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, #endif (!cmp_mat || draw_vec[idx]->mMaterial == mat) && //draw_vec[idx]->mMaterialID == mat_id && - draw_vec[idx]->mFullbright == fullbright && + (!cmp_fullbright || draw_vec[idx]->mFullbright == fullbright) && (!cmp_bump || draw_vec[idx]->mBump == bump) && - (!cmp_shiny || !!draw_vec[idx]->mShiny == !!shiny) && + (!cmp_shiny || draw_vec[idx]->mShiny == shiny) && //(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different draw_vec[idx]->mTextureMatrix == tex_mat && draw_vec[idx]->mModelMatrix == model_mat && @@ -4539,6 +4543,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool is_rigged = false; + static const LLCachedControl alt_batching("SHAltBatching",true); + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -4647,7 +4653,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } LLMaterial* mat = te->getMaterialParams().get(); - + + if(!alt_batching) + { if (mat && LLPipeline::sRenderDeferred) { U8 alpha_mode = mat->getDiffuseAlphaMode(); @@ -4760,6 +4768,68 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } } + } + else + { + if(type == LLDrawPool::POOL_ALPHA) + { + if(te->getColor().mV[3] > 0.f) + { + U32 mask = te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA; + if (mat && LLPipeline::sRenderDeferred && te->getColor().mV[3] >= 0.999f ) + { + if(mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND); + else + mask = mat->getShaderMask(); + } + pool->addRiggedFace(facep, mask); + } + } + else if(!LLPipeline::sRenderDeferred) + { + if(type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); + } + else if(type == LLDrawPool::POOL_SIMPLE || type == LLDrawPool::POOL_ALPHA_MASK) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else if(type == LLDrawPool::POOL_BUMP) //Either shiny, or bump (which isn't used in non-deferred) + { + if(te->getShiny()) + pool->addRiggedFace(facep, te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY); + else + pool->addRiggedFace(facep, te->getFullbright() ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + } + + else + { + if( type == LLDrawPool::POOL_FULLBRIGHT || type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); + } + //Annoying exception to the rule. getPoolTypeFromTE will return POOL_ALPHA_MASK for legacy bumpmaps, but there is no POOL_ALPHA_MASK in deferred. + else if(type == LLDrawPool::POOL_MATERIALS || (type == LLDrawPool::POOL_ALPHA_MASK && mat)) + { + pool->addRiggedFace(facep, mat->getShaderMask()); + } + else if (type == LLDrawPool::POOL_BUMP && te->getBumpmap()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + } + } + } } continue; @@ -4804,8 +4874,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - static const LLCachedControl alt_batching("SHAltBatching",true); - bool force_fullbright = group->isHUDGroup(); BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); U32 type = gPipeline.getPoolTypeFromTE(te, tex); @@ -4836,7 +4904,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } } - else if (force_fullbright) + else if (force_fullbright) //Hud is done in a forward render. Fullbright cannot be shared with simple. { if(type == LLDrawPool::POOL_ALPHA_MASK) type = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK; @@ -5368,11 +5436,9 @@ struct CompareBatchBreakerModified return lte->getMaterialParams() < rte->getMaterialParams(); } else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny())) - { return lte->getShiny() < rte->getShiny(); } - else { return lhs->getTexture() < rhs->getTexture(); @@ -5396,9 +5462,11 @@ struct CompareBatchBreakerModified return !(batch_left < batch_right); } - bool batch_shiny = (!LLPipeline::sRenderDeferred || lhs->isState(LLFace::FULLBRIGHT)) && lhs->getPoolType() == LLDrawPool::POOL_BUMP; + static const LLCachedControl sh_fullbright_deferred("SHFullbrightDeferred",true); + bool batch_shiny = (!LLPipeline::sRenderDeferred || (sh_fullbright_deferred && lhs->isState(LLFace::FULLBRIGHT))) && lhs->getPoolType() == LLDrawPool::POOL_BUMP; + bool batch_fullbright = sh_fullbright_deferred || !LLPipeline::sRenderDeferred && lhs->getPoolType() == LLDrawPool::POOL_ALPHA; - if (lhs->isState(LLFace::FULLBRIGHT) != rhs->isState(LLFace::FULLBRIGHT)) + if (batch_fullbright && lhs->isState(LLFace::FULLBRIGHT) != rhs->isState(LLFace::FULLBRIGHT)) { return lhs->isState(LLFace::FULLBRIGHT) < rhs->isState(LLFace::FULLBRIGHT); } @@ -6196,21 +6264,40 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac llassert_always(mask & LLVertexBuffer::MAP_NORMAL); } - if (is_fullbright) + if(LLPipeline::sRenderDeferred) { - registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT); - if(is_bump) - registerFace(group, facep, LLPipeline::sRenderDeferred ? LLRenderPass::PASS_POST_BUMP : LLRenderPass::PASS_BUMP); + static const LLCachedControl sh_fullbright_deferred("SHFullbrightDeferred",true); + if(sh_fullbright_deferred && is_fullbright) + { + registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT); + if(is_bump) + { + registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); + } + } + else + { + //is_bump should always be true. + registerFace(group, facep, is_bump ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_SIMPLE); + } } else { - registerFace(group, facep, (LLPipeline::sRenderDeferred || !is_shiny_shader) ? LLRenderPass::PASS_SIMPLE : LLRenderPass::PASS_SHINY); + if (is_fullbright ) + { + registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_FULLBRIGHT); + } + else + { + registerFace(group, facep, is_shiny_shader ? LLRenderPass::PASS_SHINY : LLRenderPass::PASS_SIMPLE); + } + if(is_bump) registerFace(group, facep, LLRenderPass::PASS_BUMP); - } - if(is_shiny_fixed) - registerFace(group, facep, LLRenderPass::PASS_SHINY); + if(is_shiny_fixed) + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } } } if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f) diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index c4e73d90b..b4ab34d36 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -166,7 +166,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) static const LLCachedControl render_transparent_water("RenderTransparentWater",false); static const LLCachedControl water_subdiv("SianaVoidWaterSubdivision", 16); - const S32 size = (render_transparent_water && LLGLSLShader::sNoFixedFunction) ? water_subdiv : 1; + const S32 size = ((render_transparent_water || LLPipeline::sRenderDeferred) && LLGLSLShader::sNoFixedFunction) ? water_subdiv : 1; const S32 num_quads = size * size; face->setSize(vertices_per_quad * num_quads, indices_per_quad * num_quads); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 79d6ad670..924e348d0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1567,34 +1567,39 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima } else { + static const LLCachedControl sh_fullbright_deferred("SHFullbrightDeferred",true); + + //Bump goes into bump pool unless using deferred and there's a normal map that takes precedence. + bool legacy_bump = (!LLPipeline::sRenderDeferred || !mat || mat->getNormalID().isNull()) && LLPipeline::sRenderBump && te->getBumpmap() && te->getBumpmap() < 18; if (alpha) { return LLDrawPool::POOL_ALPHA; } - else if ((!LLPipeline::sRenderDeferred || !mat || mat->getNormalID().isNull()) && LLPipeline::sRenderBump && te->getBumpmap() && te->getBumpmap() < 18) - { - return LLDrawPool::POOL_BUMP; //Bump goes into bump pool unless using deferred and there's a normal map that takes precedence. - } else if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { - if(te->getFullbright()) + if(!LLPipeline::sRenderDeferred || legacy_bump) + { + return te->getFullbright() ? LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK : LLDrawPool::POOL_ALPHA_MASK; + } + else if(te->getFullbright() && !mat->getEnvironmentIntensity() && !te->getShiny()) { return LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK; } - else - { - return LLPipeline::sRenderDeferred ? LLDrawPool::POOL_MATERIALS : LLDrawPool::POOL_ALPHA_MASK; - } + return LLDrawPool::POOL_MATERIALS; + } + else if (legacy_bump) + { + return LLDrawPool::POOL_BUMP; } else if(LLPipeline::sRenderDeferred && mat) { - if(te->getFullbright() && mat->getEnvironmentIntensity()) + if(te->getFullbright() && !mat->getEnvironmentIntensity() && !te->getShiny()) { - return LLDrawPool::POOL_FULLBRIGHT; + return sh_fullbright_deferred ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE; } return LLDrawPool::POOL_MATERIALS; } - else if(te->getFullbright()) + else if((sh_fullbright_deferred || !LLPipeline::sRenderDeferred) && te->getFullbright()) { return (LLPipeline::sRenderBump && te->getShiny()) ? LLDrawPool::POOL_BUMP : LLDrawPool::POOL_FULLBRIGHT; } @@ -8558,10 +8563,10 @@ void LLPipeline::renderDeferredLighting() pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, LLPipeline::RENDER_TYPE_FULLBRIGHT, - //LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_VOLUME, LLPipeline::RENDER_TYPE_GLOW, LLPipeline::RENDER_TYPE_BUMP, - /*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used. + LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_ALPHA, LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -8573,7 +8578,7 @@ void LLPipeline::renderDeferredLighting() LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SHINY, LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/ + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_ALPHA_MASK, LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, @@ -9181,10 +9186,10 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, LLPipeline::RENDER_TYPE_FULLBRIGHT, - //LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_VOLUME, LLPipeline::RENDER_TYPE_GLOW, LLPipeline::RENDER_TYPE_BUMP, - /*LLPipeline::RENDER_TYPE_PASS_SIMPLE, //These aren't used. + LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_ALPHA, LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -9196,7 +9201,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SHINY, LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,*/ + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_ALPHA_MASK, LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, @@ -9401,7 +9406,8 @@ inline float sgn(float a) void LLPipeline::generateWaterReflection(LLCamera& camera_in) { - if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) + static const LLCachedControl render_transparent_water("RenderTransparentWater",false); + if ((render_transparent_water || LLPipeline::sRenderDeferred) && LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) { BOOL skip_avatar_update = FALSE; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) From 34a7bf4dbb07675d15ddefa53d090172ea83c79f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 27 Mar 2014 21:30:23 -0500 Subject: [PATCH 2/5] Comment out unused shader. --- indra/newview/llviewershadermgr.cpp | 6 +++--- indra/newview/llviewershadermgr.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b5a819032..277fdd197 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -190,7 +190,7 @@ LLGLSLShader gDeferredWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calc LLGLSLShader gDeferredUnderWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED);//Not in mShaderList LLGLSLShader gDeferredDiffuseAlphaMaskProgram(LLViewerShaderMgr::SHADER_DEFERRED); -LLGLSLShader gDeferredNonIndexedDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED); +//LLGLSLShader gDeferredNonIndexedDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredSkinnedDiffuseProgram(LLViewerShaderMgr::SHADER_DEFERRED); @@ -1078,7 +1078,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL); } - if (success) + /*if (success) { gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); @@ -1086,7 +1086,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredNonIndexedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); - } + }*/ if (success) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 99374c31a..feea7cfbc 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -300,7 +300,7 @@ extern LLGLSLShader gDeferredDiffuseProgram; extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; -extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; +//extern LLGLSLShader gDeferredNonIndexedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedDiffuseProgram; extern LLGLSLShader gDeferredSkinnedBumpProgram; extern LLGLSLShader gDeferredSkinnedAlphaProgram; From 07a261a2598e16d421d7027eca53f6ce5963e702 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 27 Mar 2014 22:04:30 -0500 Subject: [PATCH 3/5] A little bit of cleanup. --- indra/newview/lldrawpoolalpha.cpp | 11 +++--- indra/newview/lldrawpoolbump.cpp | 2 +- indra/newview/llviewershadermgr.cpp | 11 ++---- indra/newview/pipeline.cpp | 55 ++++++++--------------------- 4 files changed, 25 insertions(+), 54 deletions(-) diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index ce4b19b82..3d88b34ca 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -373,6 +373,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) BOOL light_enabled = TRUE; BOOL use_shaders = gPipeline.canUseVertexShaders(); + + BOOL depth_only = (pass == 1 && !LLPipeline::sImpostorRender); for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { @@ -387,7 +389,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) || group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_CLOUD || group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; - bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow. + bool draw_glow_for_this_partition = !depth_only && mVertexShaderLevel > 0; // no shaders = no glow. static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group"); LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP); @@ -410,7 +412,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) // Fix for bug - NORSPEC-271 // If the face is more than 90% transparent, then don't update the Depth buffer for Dof // We don't want the nearly invisible objects to cause of DoF effects - if(pass == 1 && !LLPipeline::sImpostorRender) + if(depth_only) { LLFace* face = params.mFace; if(face) @@ -443,9 +445,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) llassert_always(!LLGLSLShader::sNoFixedFunction); llassert_always(!LLGLSLShader::sCurBoundShaderPtr); - if(params.mFullbright == light_enabled || !initialized_lighting) + bool fullbright = depth_only || params.mFullbright; + if(fullbright == light_enabled || !initialized_lighting) { - light_enabled = !params.mFullbright; + light_enabled = !fullbright; initialized_lighting = true; if (light_enabled) // Turn off lighting if it hasn't already been so. diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index d9eac7b7b..6a4c1b2ba 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -270,7 +270,7 @@ void LLDrawPoolBump::render(S32 pass) { LLFastTimer t(FTM_RENDER_BUMP); - if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE)) + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) { return; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 277fdd197..453a1e076 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -552,6 +552,7 @@ void LLViewerShaderMgr::setShaders() else { LLGLSLShader::sNoFixedFunction = false; + LLGLSLShader::sIndexedTextureChannels = 1; gPipeline.mVertexShadersEnabled = FALSE; gPipeline.mVertexShadersLoaded = 0; for (S32 i = 0; i < SHADER_COUNT; i++) @@ -569,6 +570,7 @@ void LLViewerShaderMgr::setShaders() else { LLGLSLShader::sNoFixedFunction = false; + LLGLSLShader::sIndexedTextureChannels = 1; gPipeline.mVertexShadersEnabled = FALSE; gPipeline.mVertexShadersLoaded = 0; for (S32 i = 0; i < SHADER_COUNT; i++) @@ -673,14 +675,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // (in order of shader function call depth for reference purposes, deepest level first) shaders.clear(); - S32 ch = 1; - - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { //use indexed texture rendering for GLSL >= 1.30 - static const LLCachedControl no_texture_indexing("ShyotlUseLegacyTextureBatching",false); - if(!no_texture_indexing) - ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); - } + S32 ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1); std::vector index_channels; index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 924e348d0..9c83cfeb3 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2549,15 +2549,13 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d { mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); mDeferredVB->allocateBuffer(8, 0, true); - } - - LLStrider vert; - mDeferredVB->getVertexStrider(vert); - LLStrider tc0; + LLStrider vert; + mDeferredVB->getVertexStrider(vert); - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); + vert[0].set(-1,1,0); + vert[1].set(-1,-3,0); + vert[2].set(3,1,0); + } if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE) { @@ -7962,15 +7960,14 @@ void LLPipeline::renderDeferredLighting() { mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); mDeferredVB->allocateBuffer(8, 0, true); + LLStrider vert; + mDeferredVB->getVertexStrider(vert); + + vert[0].set(-1,1,0); + vert[1].set(-1,-3,0); + vert[2].set(3,1,0); } - LLStrider vert; - mDeferredVB->getVertexStrider(vert); - - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - { setupHWLights(NULL); //to set mSunDir; LLVector4 dir(mSunDir, 0.f); @@ -8392,12 +8389,6 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSpotLightProgram); } - //reset mDeferredVB to fullscreen triangle - mDeferredVB->getVertexStrider(vert); - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - { LLGLDepthTest depth(GL_FALSE); @@ -8510,14 +8501,10 @@ void LLPipeline::renderDeferredLighting() { LLGLDepthTest depth(GL_FALSE, GL_FALSE); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) mScreen.getWidth()*2, - (F32) mScreen.getHeight()*2); - mScreen.bindTarget(); // Apply gamma correction to the frame here. gDeferredPostGammaCorrectProgram.bind(); - //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); S32 channel = 0; channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) @@ -8528,21 +8515,7 @@ void LLPipeline::renderDeferredLighting() gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); - //F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); - - //gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); gGL.getTexUnit(channel)->unbind(mScreen.getUsage()); gDeferredPostGammaCorrectProgram.unbind(); From 894261862d9af0fd768003eee55407cff755ac5b Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 27 Mar 2014 22:31:47 -0500 Subject: [PATCH 4/5] Tweaks to stencil handling to allow masking out of sky (or geometry). Reset stencil clear value to 0 after done clearing. --- indra/newview/lldrawpoolwater.cpp | 1 + indra/newview/lldrawpoolwlsky.cpp | 1 + indra/newview/llmaniptranslate.cpp | 1 + indra/newview/llspatialpartition.cpp | 3 +++ indra/newview/pipeline.cpp | 1 + 5 files changed, 7 insertions(+) diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 0872f5f9d..12f91ea67 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -253,6 +253,7 @@ void LLDrawPoolWater::render(S32 pass) glClearStencil(1); glClear(GL_STENCIL_BUFFER_BIT); + glClearStencil(0); LLGLEnable gls_stencil(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 3d0762132..864975460 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -326,6 +326,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius(); + LLGLDisable stencil(GL_STENCIL_TEST); LLGLSNoFog disableFog; LLGLDepthTest depth(GL_TRUE, GL_FALSE); LLGLDisable clip(GL_CLIP_PLANE0); diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index bdbc132c5..f9a3b0cdd 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1676,6 +1676,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, glStencilMask(stencil_mask); glClearStencil(1); glClear(GL_STENCIL_BUFFER_BIT); + glClearStencil(0); LLGLEnable cull_face(GL_CULL_FACE); LLGLEnable stencil(GL_STENCIL_TEST); LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index c2fb74365..1919611ec 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1528,6 +1528,7 @@ static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); void LLSpatialGroup::doOcclusion(LLCamera* camera) { + LLGLDisable stencil(GL_STENCIL_TEST); if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { //static const LLCachedControl render_water_void_culling("RenderWaterVoidCulling", TRUE); @@ -3867,6 +3868,8 @@ public: return; } + LLGLDisable stencil(GL_STENCIL_TEST); + group->rebuildGeom(); group->rebuildMesh(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9c83cfeb3..8ac0640fd 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2334,6 +2334,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); + LLGLDisable stencil(GL_STENCIL_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); From d6fdaa93a4b86590c8dcade84d8b894baff4679b Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 28 Mar 2014 02:34:03 -0500 Subject: [PATCH 5/5] Added adaptive vsync support (selectable in preferences->graphics->hardware, provided the driver supports it). Also hide 16x fsaa on amd hardware, as it is not supported on said hardware (unsure about intel). --- indra/llrender/llgl.cpp | 9 ++++ indra/llrender/llgl.h | 2 + indra/llwindow/llwindow.cpp | 12 +++--- indra/llwindow/llwindow.h | 6 ++- indra/llwindow/llwindowheadless.cpp | 2 +- indra/llwindow/llwindowheadless.h | 6 ++- indra/llwindow/llwindowmacosx.cpp | 23 ++++++++--- indra/llwindow/llwindowmacosx.h | 9 ++-- indra/llwindow/llwindowmesaheadless.cpp | 2 +- indra/llwindow/llwindowmesaheadless.h | 6 ++- indra/llwindow/llwindowsdl.cpp | 40 +++++++++++++++--- indra/llwindow/llwindowsdl.h | 9 ++-- indra/llwindow/llwindowwin32.cpp | 41 +++++++++++++++---- indra/llwindow/llwindowwin32.h | 7 +++- indra/newview/app_settings/settings_sh.xml | 11 +++++ indra/newview/llpaneldisplay.cpp | 25 ++++++++++- indra/newview/llpaneldisplay.h | 1 + indra/newview/llviewerwindow.cpp | 37 +++++++++++++---- indra/newview/llviewerwindow.h | 2 +- .../xui/en-us/panel_preferences_graphics1.xml | 8 +++- 20 files changed, 204 insertions(+), 54 deletions(-) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 8b5310beb..064183d49 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -442,6 +442,8 @@ LLGLManager::LLGLManager() : mHasCubeMap(FALSE), mHasDebugOutput(FALSE), + mHasAdaptiveVsync(FALSE), + mIsATI(FALSE), mIsNVIDIA(FALSE), mIsIntel(FALSE), @@ -956,6 +958,12 @@ void LLGLManager::initExtensions() mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts)); #endif +#if LL_WINDOWS + mHasAdaptiveVsync = ExtensionExists("WGL_EXT_swap_control_tear", gGLHExts.mSysExts); +#elif LL_LINUX + mHasAdaptiveVsync = ExtensionExists("GLX_EXT_swap_control_tear", gGLHExts.mSysExts); +#endif + #if LL_LINUX || LL_SOLARIS llinfos << "initExtensions() checking shell variables to adjust features..." << llendl; // Our extension support for the Linux Client is very young with some @@ -980,6 +988,7 @@ void LLGLManager::initExtensions() mHasShaderObjects = FALSE; mHasVertexShader = FALSE; mHasFragmentShader = FALSE; + mHasAdaptiveVsync = FALSE; LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL; } else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */ diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 65161a6fa..9b277c70a 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -113,6 +113,8 @@ public: BOOL mHasCubeMap; BOOL mHasDebugOutput; + BOOL mHasAdaptiveVsync; + // Vendor-specific extensions BOOL mIsATI; BOOL mIsNVIDIA; diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 8df242331..b3b37d705 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -388,7 +388,7 @@ LLWindow* LLWindowManager::createWindow( const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL use_gl, BOOL ignore_pixel_depth, U32 fsaa_samples) @@ -400,26 +400,26 @@ LLWindow* LLWindowManager::createWindow( #if LL_MESA_HEADLESS new_window = new LLWindowMesaHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth); #elif LL_SDL new_window = new LLWindowSDL(callbacks, title, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS new_window = new LLWindowWin32(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth, fsaa_samples); #elif LL_DARWIN new_window = new LLWindowMacOSX(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth, fsaa_samples); #endif } else { new_window = new LLWindowHeadless(callbacks, title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, ignore_pixel_depth); + fullscreen, clearBg, vsync_mode, ignore_pixel_depth); } if (FALSE == new_window->isValid()) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 575c57816..0d53f5951 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -82,7 +82,7 @@ public: BOOL setSize(LLCoordScreen size); BOOL setSize(LLCoordWindow size); virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0; + virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL) = 0; virtual BOOL setCursorPosition(LLCoordWindow position) = 0; virtual BOOL getCursorPosition(LLCoordWindow *position) = 0; virtual void showCursor() = 0; @@ -121,6 +121,8 @@ public: virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma virtual void setFSAASamples(const U32 fsaa_samples) = 0; //set number of FSAA samples virtual U32 getFSAASamples() = 0; + virtual void setVsyncMode(const S32 vsync_mode) = 0; + virtual S32 getVsyncMode() = 0; virtual BOOL restoreGamma() = 0; // Restore original gamma table (before updating gamma) virtual ESwapMethod getSwapMethod() { return mSwapMethod; } virtual void processMiscNativeEvents(); @@ -274,7 +276,7 @@ public: U32 flags = 0, BOOL fullscreen = FALSE, BOOL clearBg = FALSE, - BOOL disable_vsync = TRUE, + const S32 vsync_mode = 0, BOOL use_gl = TRUE, BOOL ignore_pixel_depth = FALSE, U32 fsaa_samples = 0); diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp index dbdb40f5b..d07521cf2 100644 --- a/indra/llwindow/llwindowheadless.cpp +++ b/indra/llwindow/llwindowheadless.cpp @@ -35,7 +35,7 @@ // LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL ignore_pixel_depth) + const S32 vsync_mode, BOOL ignore_pixel_depth) : LLWindow(callbacks, fullscreen, flags) { // Initialize a headless keyboard. diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 72f9684ca..491f9afd2 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -48,7 +48,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL) {return FALSE;}; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; /*virtual*/ void showCursor() {}; @@ -69,6 +69,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { } /*virtual*/ U32 getFSAASamples() { return 0; } + /*virtual*/ void setVsyncMode(const S32 vsync_mode) {} + /*virtual*/ S32 getVsyncMode() { return 0; } /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput() {}; @@ -96,7 +98,7 @@ public: S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clear_background, - BOOL disable_vsync, BOOL ignore_pixel_depth); + const S32 vsync_mode, BOOL ignore_pixel_depth); virtual ~LLWindowHeadless(); private: diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 303a23959..096742dc9 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -210,7 +210,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(NULL, fullscreen, flags) @@ -253,6 +253,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mPreeditor = NULL; mRawKeyEvent = NULL; mFSAASamples = fsaa_samples; + mVsyncMode = vsync_mode; mForceRebuild = FALSE; // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state. @@ -283,7 +284,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, gWindowImplementation = this; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, vsync_mode)) { if(mWindow != NULL) { @@ -323,7 +324,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, stop_glerror(); } -BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode) { OSStatus err; BOOL glNeedsInit = FALSE; @@ -780,7 +781,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Disable vertical sync for swap GLint frames_per_swap = 0; - if (disable_vsync) + if (vsync_mode != 1) { LL_DEBUGS("GLInit") << "Disabling vertical sync" << LL_ENDL; frames_per_swap = 0; @@ -816,7 +817,7 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // changing fullscreen resolution, or switching between windowed and fullscreen mode. -BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp) { BOOL needsRebuild = FALSE; BOOL result = true; @@ -892,7 +893,7 @@ BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, B { mForceRebuild = FALSE; destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); + result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, vsync_mode); if (result) { if(mWindow != NULL) @@ -1341,6 +1342,16 @@ void LLWindowMacOSX::setFSAASamples(const U32 samples) mForceRebuild = TRUE; } +S32 LLWindowMacOSX::getVsyncMode() +{ + return mVsyncMode; +} +void LLWindowMacOSX::setVsyncMode(const S32 vsync_mode) +{ + mVsyncMode = vsync_mode + mForceRebuild = TRUE; +} + BOOL LLWindowMacOSX::restoreGamma() { CGDisplayRestoreColorSyncSettings(); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 3f75dc9ab..7f7181a58 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -60,7 +60,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ void showCursor(); @@ -81,6 +81,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma /*virtual*/ U32 getFSAASamples(); /*virtual*/ void setFSAASamples(const U32 fsaa_samples); + /*virtual*/ void setVsyncMode(const S32 vsync_mode); + /*virtual*/ S32 getVsyncMode(); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput(); @@ -124,7 +126,7 @@ public: protected: LLWindowMacOSX(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, + BOOL fullscreen, BOOL clearBg, const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowMacOSX(); @@ -152,7 +154,7 @@ protected: // // create or re-create the GL context/window. Called from the constructor and switchContext(). - BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync); + BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode); void destroyContext(); void setupFailure(const std::string& text, const std::string& caption, U32 type); static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData); @@ -201,6 +203,7 @@ protected: BOOL mMaximized; BOOL mMinimized; U32 mFSAASamples; + S32 mVsyncMode; BOOL mForceRebuild; S32 mDragOverrideCursor; diff --git a/indra/llwindow/llwindowmesaheadless.cpp b/indra/llwindow/llwindowmesaheadless.cpp index 2b668d3fc..095a7d17c 100644 --- a/indra/llwindow/llwindowmesaheadless.cpp +++ b/indra/llwindow/llwindowmesaheadless.cpp @@ -41,7 +41,7 @@ U16 *gMesaBuffer = NULL; LLWindowMesaHeadless::LLWindowMesaHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL ignore_pixel_depth) + const S32 vsync_mode, BOOL ignore_pixel_depth) : LLWindow(callbacks, fullscreen, flags) { llinfos << "MESA Init" << llendl; diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index c8d2bf282..438964dae 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -52,7 +52,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL) {return FALSE;}; /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; /*virtual*/ void showCursor() {}; @@ -74,6 +74,8 @@ public: /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { /* FSAA not supported yet on Mesa headless.*/ } /*virtual*/ U32 getFSAASamples() { return 0; } + /*virtual*/ void setVsyncMode(const S32 vsync_mode) {} + /*virtual*/ S32 getVsyncMode() { return 0; } //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput() {}; /*virtual*/ void delayInputProcessing() {}; @@ -98,7 +100,7 @@ public: LLWindowMesaHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, BOOL ignore_pixel_depth); + const S32 vsync_mode, BOOL ignore_pixel_depth); ~LLWindowMesaHeadless(); private: diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 10bcf816a..48f2c1949 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -192,7 +192,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, const std::string& title, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags), Lock_Display(NULL), @@ -233,7 +233,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, mWindowTitle = title; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, vsync_mode)) { gGLManager.initGL(); @@ -373,7 +373,7 @@ static int x11_detect_VRAM_kb() } #endif // LL_X11 -BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync) +BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, const S32 vsync_mode, S32 vsync_mode) { //bool glneedsinit = false; @@ -721,6 +721,26 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B } #endif // LL_X11 + // Disable vertical sync for swap + if (vsync_mode == 0) + { + LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; + SDL_GL_SetSwapInterval(0); + } + else if(vsync_mode == -1) + { + LL_DEBUGS("Window") << "Enabling adaptive vertical sync" << LL_ENDL; + if(SDL_GL_SetSwapInterval(-1) == -1) + { + LL_DEBUGS("Window") << "Failed to enable adaptive vertical sync. Disabling vsync." << LL_ENDL; + SDL_GL_SetSwapInterval(0); + } + } + else + { + LL_DEBUGS("Window") << "Enabling vertical sync" << LL_ENDL; + SDL_GL_SetSwapInterval(1); + } //make sure multisampling is disabled by default glDisable(GL_MULTISAMPLE_ARB); @@ -736,7 +756,7 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B // changing fullscreen resolution, or switching between windowed and fullscreen mode. -BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp) { const BOOL needsRebuild = TRUE; // Just nuke the context and start over. BOOL result = true; @@ -746,7 +766,7 @@ BOOL LLWindowSDL::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL if(needsRebuild) { destroyContext(); - result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); + result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, vsync_mode); if (result) { gGLManager.initGL(); @@ -987,6 +1007,16 @@ void LLWindowSDL::setFSAASamples(const U32 samples) mFSAASamples = samples; } +S32 LLWindowSDL::getVsyncMode() +{ + return mVsyncMode; +} + +void LLWindowSDL::setVsyncMode(const S32 vsync_mode) +{ + mVsyncMode = vsync_mode +} + F32 LLWindowSDL::getGamma() { return 1/mGamma; diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 134554e6e..3334fcb98 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -65,7 +65,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ void showCursor(); @@ -92,6 +92,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma /*virtual*/ U32 getFSAASamples(); /*virtual*/ void setFSAASamples(const U32 samples); + /*virtual*/ void setVsyncMode(const S32 vsync_mode); + /*virtual*/ S32 getVsyncMode(); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void processMiscNativeEvents(); @@ -149,7 +151,7 @@ public: protected: LLWindowSDL(LLWindowCallbacks* callbacks, const std::string& title, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, + BOOL fullscreen, BOOL clearBg, const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowSDL(); @@ -174,7 +176,7 @@ protected: // // create or re-create the GL context/window. Called from the constructor and switchContext(). - BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync); + BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, const S32 vsync_mode); void destroyContext(); void setupFailure(const std::string& text, const std::string& caption, U32 type); void fixWindowSize(void); @@ -194,6 +196,7 @@ protected: F32 mOverrideAspectRatio; F32 mGamma; U32 mFSAASamples; + S32 mVsyncMode; int mSDLFlags; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 807c547bd..8e6b4c57c 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -363,7 +363,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, - BOOL disable_vsync, + const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(callbacks, fullscreen, flags) @@ -903,7 +903,7 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size) } // changing fullscreen resolution -BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp) +BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp) { GLuint pixel_format; DEVMODE dev_mode; @@ -1650,14 +1650,27 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } // Disable vertical sync for swap - if (disable_vsync && wglSwapIntervalEXT) + if(wglSwapIntervalEXT) { - LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; - wglSwapIntervalEXT(0); - } - else - { - LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL; + if (vsync_mode == 0) + { + LL_DEBUGS("Window") << "Disabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(0); + } + else if(vsync_mode == -1) + { + LL_DEBUGS("Window") << "Enabling adaptive vertical sync" << LL_ENDL; + if(wglSwapIntervalEXT(-1) == 0) + { + LL_DEBUGS("Window") << "Failed to enable adaptive vertical sync. Disabling vsync." << LL_ENDL; + wglSwapIntervalEXT(0); + } + } + else + { + LL_DEBUGS("Window") << "Enabling vertical sync" << LL_ENDL; + wglSwapIntervalEXT(1); + } } SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); @@ -3030,6 +3043,16 @@ U32 LLWindowWin32::getFSAASamples() return mFSAASamples; } +S32 LLWindowWin32::getVsyncMode() +{ + return mVsyncMode; +} + +void LLWindowWin32::setVsyncMode(const S32 vsync_mode) +{ + mVsyncMode = vsync_mode; +} + LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions) { if (!mSupportedResolutions) diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 9f678b96c..07dc67c20 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -59,7 +59,7 @@ public: /*virtual*/ BOOL setPosition(LLCoordScreen position); /*virtual*/ BOOL setSizeImpl(LLCoordScreen size); /*virtual*/ BOOL setSizeImpl(LLCoordWindow size); - /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); + /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, const S32 vsync_mode, const LLCoordScreen * const posp = NULL); /*virtual*/ BOOL setCursorPosition(LLCoordWindow position); /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position); /*virtual*/ void showCursor(); @@ -80,6 +80,8 @@ public: /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma /*virtual*/ void setFSAASamples(const U32 fsaa_samples); /*virtual*/ U32 getFSAASamples(); + /*virtual*/ void setVsyncMode(const S32 vsync_mode); + /*virtual*/ S32 getVsyncMode(); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput(); @@ -121,7 +123,7 @@ public: protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, - BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, + BOOL fullscreen, BOOL clearBg, const S32 vsync_mode, BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowWin32(); @@ -186,6 +188,7 @@ protected: F32 mCurrentGamma; U32 mFSAASamples; + S32 mVsyncMode; WORD mPrevGammaRamp[256*3]; WORD mCurrentGammaRamp[256*3]; diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 83731c3ec..c06a6f710 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -251,5 +251,16 @@ Value 1 + SHRenderVsyncMode + + Comment + Desired vertical sychronization method. (0 = Disabled, 1 = Standard [Double-buffered], -1 = Adaptive [if supported]) + Persist + 1 + Type + S32 + Value + 0 + diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index 0f7184757..9fc9b96c9 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -334,6 +334,16 @@ BOOL LLPanelDisplay::postBuild() mVBOStream = getChild("vbo_stream"); + if(gGLManager.mIsATI) //AMD gpus don't go beyond 8x fsaa. + { + LLComboBox* fsaa = getChild("fsaa"); + fsaa->remove("16x"); + } + if(!gGLManager.mHasAdaptiveVsync) + { + LLComboBox* vsync = getChild("vsync"); + vsync->remove("VSyncAdaptive"); + } refresh(); @@ -447,8 +457,10 @@ void LLPanelDisplay::refresh() mGamma = gSavedSettings.getF32("RenderGamma"); mVideoCardMem = gSavedSettings.getS32("TextureMemory"); mFogRatio = gSavedSettings.getF32("RenderFogRatio"); + mVsyncMode = gSavedSettings.getS32("SHRenderVsyncMode"); childSetValue("fsaa", (LLSD::Integer) mFSAASamples); + childSetValue("vsync", (LLSD::Integer) mVsyncMode); refreshEnabledState(); } @@ -846,13 +858,22 @@ void LLPanelDisplay::cancel() gSavedSettings.setF32("RenderGamma", mGamma); gSavedSettings.setS32("TextureMemory", mVideoCardMem); gSavedSettings.setF32("RenderFogRatio", mFogRatio); + gSavedSettings.setS32("SHRenderVsyncMode", mVsyncMode); } void LLPanelDisplay::apply() { U32 fsaa_value = childGetValue("fsaa").asInteger(); + S32 vsync_value = childGetValue("vsync").asInteger(); + + if(vsync_value == -1 && !gGLManager.mHasAdaptiveVsync) + vsync_value = 0; + bool apply_fsaa_change = !gSavedSettings.getBOOL("RenderUseFBO") && (mFSAASamples != fsaa_value); + bool apply_vsync_change = vsync_value != mVsyncMode; + gSavedSettings.setU32("RenderFSAASamples", fsaa_value); + gSavedSettings.setS32("SHRenderVsyncMode", vsync_value); applyResolution(); @@ -865,7 +886,7 @@ void LLPanelDisplay::apply() // Hardware tab //Still do a bit of voodoo here. V2 forces restart to change FSAA with FBOs off. //Let's not do that, and instead do pre-V2 FSAA change handling for that particular case - if(apply_fsaa_change) + if(apply_fsaa_change || apply_vsync_change) { bool logged_in = (LLStartUp::getStartupState() >= STATE_STARTED); LLWindow* window = gViewerWindow->getWindow(); @@ -875,7 +896,7 @@ void LLPanelDisplay::apply() LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(window->getFullscreen(), size, - gSavedSettings.getBOOL("DisableVerticalSync"), + vsync_value, logged_in); LLGLState::checkStates(); LLGLState::checkTextureChannels(); diff --git a/indra/newview/llpaneldisplay.h b/indra/newview/llpaneldisplay.h index 9b39ee555..1652b497b 100644 --- a/indra/newview/llpaneldisplay.h +++ b/indra/newview/llpaneldisplay.h @@ -194,6 +194,7 @@ protected: F32 mGamma; S32 mVideoCardMem; F32 mFogRatio; + S32 mVsyncMode; // if the quality radio buttons are changed void onChangeQuality(LLUICtrl* caller); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 4f2e5c931..455c3b272 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1640,12 +1640,18 @@ LLViewerWindow::LLViewerWindow( LLViewerWindow::sMovieBaseName = "SLmovie"; resetSnapshotLoc(); + S32 vsync_mode = gSavedSettings.getS32("SHRenderVsyncMode"); + if(vsync_mode == -1 && !gGLManager.mHasAdaptiveVsync) + { + vsync_mode = 0; //Disable vsync if adaptive is desired yet isn't supported. + } + // create window mWindow = LLWindowManager::createWindow(this, title, name, x, y, width, height, 0, fullscreen, gNoRender, - gSavedSettings.getBOOL("DisableVerticalSync"), + vsync_mode, !gNoRender, ignore_pixel_depth, gSavedSettings.getBOOL("RenderUseFBO") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled @@ -4436,14 +4442,20 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height) BORDERHEIGHT = size.mY- y; LLCoordScreen new_size(new_width + BORDERWIDTH, new_height + BORDERHEIGHT); - BOOL disable_sync = gSavedSettings.getBOOL("DisableVerticalSync"); + + S32 vsync_mode = gSavedSettings.getS32("SHRenderVsyncMode"); + if(vsync_mode == -1 && !gGLManager.mHasAdaptiveVsync) + { + vsync_mode = 0; //Disable vsync if adaptive is desired yet isn't supported. + } + if (gViewerWindow->getWindow()->getFullscreen()) { LLGLState::checkStates(); LLGLState::checkTextureChannels(); gViewerWindow->changeDisplaySettings(FALSE, new_size, - disable_sync, + vsync_mode, TRUE); LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -5429,9 +5441,16 @@ BOOL LLViewerWindow::checkSettings() LLGLState::checkStates(); LLGLState::checkTextureChannels(); + + S32 vsync_mode = gSavedSettings.getS32("SHRenderVsyncMode"); + if(vsync_mode == -1 && !gGLManager.mHasAdaptiveVsync) + { + vsync_mode = 0; //Disable vsync if adaptive is desired yet isn't supported. + } + changeDisplaySettings(TRUE, desired_screen_size, - gSavedSettings.getBOOL("DisableVerticalSync"), + vsync_mode, mShowFullscreenProgress); LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -5472,7 +5491,7 @@ void LLViewerWindow::restartDisplay(BOOL show_progress_bar) } } -BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar) +BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, const S32 vsync_mode, BOOL show_progress_bar) { BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized"); mWantFullscreen = fullscreen; @@ -5491,6 +5510,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); U32 old_fsaa = mWindow->getFSAASamples(); + // going from windowed to windowed if (!old_fullscreen && !fullscreen) { @@ -5500,7 +5520,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mWindow->setSize(size); } - if (fsaa == old_fsaa) + if (fsaa == old_fsaa && vsync_mode == mWindow->getFSAASamples()) { return TRUE; } @@ -5539,13 +5559,14 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, } mWindow->setFSAASamples(fsaa); + mWindow->setVsyncMode(vsync_mode); - result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync, &new_pos); + result_first_try = mWindow->switchContext(fullscreen, size, vsync_mode, &new_pos); if (!result_first_try) { // try to switch back mWindow->setFSAASamples(old_fsaa); - result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync, &new_pos); + result_second_try = mWindow->switchContext(old_fullscreen, old_size, vsync_mode, &new_pos); if (!result_second_try) { diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 7ec0f3ec3..7e47a1a1b 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -386,7 +386,7 @@ public: void requestResolutionUpdate(bool fullscreen_checked); BOOL checkSettings(); void restartDisplay(BOOL show_progress_bar); - BOOL changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar); + BOOL changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, const S32 vsync_mode, BOOL show_progress_bar); BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; } F32 getDisplayAspectRatio() const; const LLVector2& getDisplayScale() const { return mDisplayScale; } diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml index e2c4376ac..a2652e226 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml @@ -118,6 +118,12 @@ 4x 8x 16x + + VSync: + + Disabled + Standard + Adaptive - + Note: The Gamma and Fog Distance Ratio