diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 262 |
1 files changed, 74 insertions, 188 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9851d4bc6a..66083470e2 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -855,17 +855,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) S32 shadow_detail = RenderShadowDetail; bool ssao = RenderDeferredSSAO; - const U32 occlusion_divisor = 3; - //allocate deferred rendering color buffers - if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; - //if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; - if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true, true, LLTexUnit::TT_TEXTURE, false, samples)) return false; if (!addDeferredAttachments(mRT->deferredScreen)) return false; GLuint screenFormat = GL_RGBA16; - if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, true, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; mRT->deferredScreen.shareDepthBuffer(mRT->screen); @@ -905,9 +901,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mRT->fxaaBuffer.release(); mRT->screen.release(); mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first - //mRT->deferredDepth.release(); - mRT->occlusionDepth.release(); - + if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_TEXTURE, FALSE)) return false; } @@ -926,8 +920,6 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; S32 shadow_detail = RenderShadowDetail; - const U32 occlusion_divisor = 3; - F32 scale = llmax(0.f, RenderShadowResolutionScale); U32 sun_shadow_map_width = BlurHappySize(resX, scale); U32 sun_shadow_map_height = BlurHappySize(resY, scale); @@ -936,12 +928,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) { //allocate 4 sun shadow maps for (U32 i = 0; i < 4; i++) { - if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) - { - return false; - } - - if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) + if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, true, true, LLTexUnit::TT_TEXTURE)) { return false; } @@ -966,11 +953,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) U32 spot_shadow_map_height = height; for (U32 i = 0; i < 2; i++) { - if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) - { - return false; - } - if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE)) + if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, true, true)) { return false; } @@ -1001,7 +984,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) } } - if (shadow_detail > 1) + if (shadow_detail > 1 && !gCubeSnapshot) { for (U32 i = 0; i < 2; i++) { @@ -1198,7 +1181,6 @@ void LLPipeline::releaseScreenBuffers() mRT->deferredScreen.release(); mRT->deferredDepth.release(); mRT->deferredLight.release(); - mRT->occlusionDepth.release(); } @@ -1206,7 +1188,6 @@ void LLPipeline::releaseSunShadowTarget(U32 index) { llassert(index < 4); mRT->shadow[index].release(); - mRT->shadowOcclusion[index].release(); } void LLPipeline::releaseSunShadowTargets() @@ -1224,7 +1205,6 @@ void LLPipeline::releaseSpotShadowTargets() for (U32 i = 0; i < 2; i++) { mSpotShadow[i].release(); - mSpotShadowOcclusion[i].release(); } } } @@ -1239,7 +1219,7 @@ void LLPipeline::createGLBuffers() if (LLPipeline::sRenderTransparentWater) { //water reflection texture U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); - mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE); + mWaterDis.allocate(res,res,GL_RGBA,true,true,LLTexUnit::TT_TEXTURE); } // Use FBO for bake tex @@ -2353,16 +2333,35 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); -void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep) +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) { - static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion"); - static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion"); - 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 - if (planep != nullptr) + bool water_clip = !sRenderTransparentWater; + + if (water_clip) { - camera.setUserClipPlane(*planep); + + LLVector3 pnorm; + + F32 water_height = LLEnvironment::instance().getWaterHeight(); + + if (sUnderWaterRender) + { + //camera is below water, cull above water + pnorm.setVec(0, 0, 1); + } + else + { + //camera is above water, cull below water + pnorm = LLVector3(0, 0, -1); + } + + LLPlane plane; + plane.setVec(LLVector3(0, 0, water_height), pnorm); + + camera.setUserClipPlane(plane); } else { @@ -2373,56 +2372,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla sCull->clear(); - bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.shadersLoaded(); - - if (to_texture) - { - if (LLPipeline::sRenderDeferred && can_use_occlusion) - { - mRT->occlusionDepth.bindTarget(); - } - else - { - mRT->screen.bindTarget(); - } - } - - if (sUseOcclusion > 1) - { - gGL.setColorMask(false, false); - } - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadMatrix(gGLLastProjection); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLLastModelView); - - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - - bool bound_shader = false; - if (gPipeline.shadersLoaded() && LLGLSLShader::sCurBoundShader == 0) - { //if no shader is currently bound, use the occlusion shader instead of fixed function if we can - // (shadow render uses a special shader that clamps to clip planes) - bound_shader = true; - gOcclusionCubeProgram.bind(); - } - - if (sUseOcclusion > 1) - { - if (mCubeVB.isNull()) - { //cube VB will be used for issuing occlusion queries - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW); - } - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - } - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { @@ -2444,16 +2393,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla LLVOCachePartition* vo_part = region->getVOCachePartition(); if(vo_part) { - bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe; - vo_part->cull(camera, do_occlusion_cull); + vo_part->cull(camera, sUseOcclusion > 0); } } - if (bound_shader) - { - gOcclusionCubeProgram.unbind(); - } - if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) @@ -2479,28 +2422,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla { LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water); } - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - - if (sUseOcclusion > 1) - { - gGL.setColorMask(true, false); - } - - if (to_texture) - { - if (LLPipeline::sRenderDeferred && can_use_occlusion) - { - mRT->occlusionDepth.flush(); - } - else - { - mRT->screen.flush(); - } - } } void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) @@ -2563,19 +2484,22 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("downsampleDepthBuffer"); + LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; LLGLSLShader* shader = NULL; if (scratch_space) { +#if 0 // TODO -- restore occlusion culling functionality GLint bits = 0; - llassert(!source.hasStencil()); // stencil buffer usage is deprecated - bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0; - bits |= GL_DEPTH_BUFFER_BIT; - scratch_space->copyContents(source, + bits = GL_DEPTH_BUFFER_BIT; + scratch_space->copyContents(source, 0, 0, source.getWidth(), source.getHeight(), 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), bits, GL_NEAREST); +#endif } dest.bindTarget(); @@ -2624,23 +2548,6 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d } } -void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - llassert(!gCubeSnapshot); -#if 0 - downsampleDepthBuffer(source, dest, scratch_space); - dest.bindTarget(); - doOcclusion(camera); - dest.flush(); -#else - // none of the above shenanigans should matter (enough) because we've preserved hierarchical Z before issuing occlusion queries - //source.bindTarget(); - doOcclusion(camera); - //source.flush(); -#endif -} - void LLPipeline::doOcclusion(LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -2741,10 +2648,6 @@ void LLPipeline::updateGL() LLGLUpdate::sGLQ.pop_front(); } } - - { //seed VBO Pools - LLVertexBuffer::seedPools(); - } } void LLPipeline::clearRebuildGroups() @@ -3321,6 +3224,7 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("stateSort"); if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, @@ -3929,6 +3833,7 @@ void LLPipeline::postSort(LLCamera &camera) // flush particle VB if (LLVOPartGroup::sVB) { + LL_PROFILE_GPU_ZONE("flush particle vb"); LLVOPartGroup::sVB->flush(); } else @@ -3952,9 +3857,12 @@ void LLPipeline::postSort(LLCamera &camera) }*/ // pack vertex buffers for groups that chose to delay their updates - for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter) { - (*iter)->rebuildMesh(); + LL_PROFILE_GPU_ZONE("rebuildMesh"); + for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter) + { + (*iter)->rebuildMesh(); + } } /*if (use_transform_feedback) @@ -7351,8 +7259,6 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLVOPartGroup::destroyGL(); gGL.resetVertexBuffer(); - SUBSYSTEM_CLEANUP(LLVertexBuffer); - if (LLVertexBuffer::sGLCount != 0) { LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL; @@ -7372,7 +7278,6 @@ void LLPipeline::doResetVertexBuffers(bool forced) sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); - LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); gGL.initVertexBuffer(); mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); @@ -7445,30 +7350,28 @@ void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, for (LLCullResult::drawinfo_iterator i = begin; i != end; ) { LLDrawInfo* pparams = *i; - if (pparams) - { - LLCullResult::increment_iterator(i, end); + LLCullResult::increment_iterator(i, end); - if (rigged) + if (rigged) + { + if (pparams->mAvatar != nullptr) { - if (pparams->mAvatar != nullptr) + if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) { - if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash) - { - mSimplePool->uploadMatrixPalette(*pparams); - lastAvatar = pparams->mAvatar; - lastMeshId = pparams->mSkinInfo->mHash; - } - - mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture); + mSimplePool->uploadMatrixPalette(*pparams); + lastAvatar = pparams->mAvatar; + lastMeshId = pparams->mSkinInfo->mHash; } + + mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture); } - else if (pparams->mAvatar == nullptr) - { - mSimplePool->pushBatch(*pparams, mask, texture, batch_texture); - } + } + else if (pparams->mAvatar == nullptr) + { + mSimplePool->pushBatch(*pparams, mask, texture, batch_texture); } } + gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; } @@ -9565,20 +9468,17 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLGLEnable cull(GL_CULL_FACE); //enable depth clamping if available - //LLGLEnable depth_clamp(GL_DEPTH_CLAMP); + LLGLEnable depth_clamp(GL_DEPTH_CLAMP); + + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_LESS); if (use_shader) { gDeferredShadowCubeProgram.bind(); } - LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ? - mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] : - mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0]; - - occlusion_target.bindTarget(); + updateCull(shadow_cam, result); - occlusion_target.flush(); stateSort(shadow_cam, result); @@ -9613,15 +9513,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged { bool rigged = j == 1; - if (!use_shader) - { //occlusion program is general purpose depth-only no-textures - gOcclusionProgram.bind(rigged); - } - else - { - gDeferredShadowProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - } + gDeferredShadowProgram.bind(rigged); + LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); gGL.diffuseColor4f(1, 1, 1, 1); @@ -9655,12 +9548,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera } gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - if (!use_shader) - { - gOcclusionProgram.unbind(); - } } + if (occlude > 1) + { // do occlusion culling against non-masked only to take advantage of hierarchical Z + doOcclusion(shadow_cam); + } + + if (use_shader) { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); @@ -9760,15 +9655,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); - LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ? - mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] : - mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0]; - - if (occlude > 1) - { - doOcclusion(shadow_cam, occlusion_source, occlusion_target); - } - if (use_shader) { gDeferredShadowProgram.unbind(); |