From 484994b43b65f19d3d64c7ea3760313277e9e138 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 11 Apr 2012 12:20:03 -0500 Subject: MAINT-870 Fix for crash from out of control lawns. --- indra/newview/llvovolume.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 080d1f774a..16b61496a6 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5089,6 +5089,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun mFaceList.clear(); //for each drawable + for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; @@ -5109,11 +5110,14 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun //sum up face verts and indices drawablep->updateFaceSize(i); LLFace* facep = drawablep->getFace(i); - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) + + + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && + facep->getGeomCount() + vertex_count <= 65536) { vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); - llassert(facep->getIndicesCount() < 65536); + //remember face (for sorting) mFaceList.push_back(facep); } -- cgit v1.2.3 From 70ade9f538f6aa9ab0915c0a7040bbf20dfb98a1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 17 Apr 2012 17:44:39 -0500 Subject: MAINT-775 WIP on crash when exploring Insilico -- don't hold onto off-screen vertex buffers for more than a few seconds. --- indra/newview/llvovolume.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 16b61496a6..f656e61cca 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -682,7 +682,21 @@ void LLVOVolume::updateTextures() const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) { - updateTextureVirtualSize(); + updateTextureVirtualSize(); + + if (mDrawable.notNull() && !isVisible()) + { //delete vertex buffer to free up some VRAM + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->destroyGL(true); + + //flag the group as having changed draw info state so it gets a rebuild next time + //it becomes visible + group->setState(LLSpatialGroup::NEW_DRAWINFO); + } + } + } } -- cgit v1.2.3 From 06bd74502713200d2103b576f7b97e715c1992c1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 Apr 2012 14:50:23 -0500 Subject: MAINT-775 More aggressive removal of textures from video memory. --- indra/newview/llvovolume.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f656e61cca..1193aa50f9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -729,7 +729,15 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) if(!forced) { if(!isVisible()) - { + { //don't load textures for non-visible faces + const S32 num_faces = mDrawable->getNumFaces(); + for (S32 i = 0; i < num_faces; i++) + { + LLFace* face = mDrawable->getFace(i); + face->setPixelArea(0.f); + face->setVirtualSize(0.f); + } + return ; } @@ -4056,7 +4064,6 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) } static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume"); -static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj) { @@ -4098,7 +4105,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) { - LLFastTimer ftm(FTM_REBUILD_VBO); LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); rebuildMesh(group); @@ -4107,8 +4113,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } group->mBuilt = 1.f; - LLFastTimer ftm(FTM_REBUILD_VBO); - + LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); LLVOAvatar* pAvatarVO = NULL; -- cgit v1.2.3 From 5334c410ea7552ebc2c758ee8911b3235f76824a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 19 Apr 2012 14:16:49 -0500 Subject: MAINT-775 Don't thrash vertex buffers on animated prims (flexis, spinners, etc). --- indra/newview/llvovolume.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 1193aa50f9..102fe4bab6 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -691,9 +691,9 @@ void LLVOVolume::updateTextures() { group->destroyGL(true); - //flag the group as having changed draw info state so it gets a rebuild next time + //flag the group as having changed geometry so it gets a rebuild next time //it becomes visible - group->setState(LLSpatialGroup::NEW_DRAWINFO); + group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } } @@ -1524,8 +1524,9 @@ void LLVOVolume::updateRelativeXform() LLVector3 delta_pos, delta_scale; //matrix from local space to parent relative/global space - delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation(); - delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition(); + bool use_identity = drawable->isSpatialRoot() || drawable->isState(LLDrawable::ANIMATED_CHILD); + delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); + delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); delta_scale = mDrawable->getScale(); // Vertex transform (4x4) @@ -1626,7 +1627,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) return res; } - dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); + LLSpatialGroup* group = drawable->getSpatialGroup(); + if (group) + { + group->dirtyMesh(); + } BOOL compiled = FALSE; @@ -1639,6 +1644,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mVolumeChanged || mFaceMappingChanged ) { + dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); + compiled = TRUE; if (mVolumeChanged) @@ -1657,6 +1664,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) } else if ((mLODChanged) || (mSculptChanged)) { + dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); + LLVolume *old_volumep, *new_volumep; F32 old_lod, new_lod; S32 old_num_faces, new_num_faces ; @@ -3957,9 +3966,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, const LLMatrix4* model_mat = NULL; LLDrawable* drawable = facep->getDrawable(); + if (drawable->isActive()) { - model_mat = &(drawable->getRenderMatrix()); + model_mat = &drawable->getRenderMatrix(); } else { @@ -4667,7 +4677,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); +// llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); } struct CompareBatchBreakerModified -- cgit v1.2.3 From d953cce3868cf53b3f84e1fdd97119c83d3dff7d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 19 Apr 2012 17:29:32 -0500 Subject: MAINT-775 Cleanup of some weird corner cases on animated child prims. --- indra/newview/llvovolume.cpp | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 102fe4bab6..847a3767bc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -684,7 +684,7 @@ void LLVOVolume::updateTextures() { updateTextureVirtualSize(); - if (mDrawable.notNull() && !isVisible()) + if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) { //delete vertex buffer to free up some VRAM LLSpatialGroup* group = mDrawable->getSpatialGroup(); if (group) @@ -1438,7 +1438,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); -// bool rigged = false; + // bool rigged = false; LLVolume* volume = mRiggedVolume; if (!volume) { @@ -1493,7 +1493,7 @@ void LLVOVolume::preRebuild() } } -void LLVOVolume::updateRelativeXform() +void LLVOVolume::updateRelativeXform(bool force_identity) { if (mVolumeImpl) { @@ -1517,14 +1517,14 @@ void LLVOVolume::updateRelativeXform() mRelativeXform.invert(); mRelativeXformInvTrans.transpose(); } - else if (drawable->isActive()) + else if (drawable->isActive() || force_identity) { // setup relative transforms LLQuaternion delta_rot; LLVector3 delta_pos, delta_scale; //matrix from local space to parent relative/global space - bool use_identity = drawable->isSpatialRoot() || drawable->isState(LLDrawable::ANIMATED_CHILD); + bool use_identity = force_identity || drawable->isSpatialRoot(); delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation(); delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition(); delta_scale = mDrawable->getScale(); @@ -3969,7 +3969,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (drawable->isActive()) { - model_mat = &drawable->getRenderMatrix(); + if (drawable->isState(LLDrawable::ANIMATED_CHILD)) + { + model_mat = &drawable->getWorldMatrix(); + } + else + { + model_mat = &drawable->getRenderMatrix(); + } } else { @@ -4618,6 +4625,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + LLVolume* volume = vobj->getVolume(); for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { @@ -4637,6 +4649,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } } } + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(); + } + drawablep->clearState(LLDrawable::REBUILD_ALL); } @@ -4951,10 +4969,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: LLVOVolume* vobj = drawablep->getVOVolume(); LLVolume* volume = vobj->getVolume(); + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(true); + } + U32 te_idx = facep->getTEOffset(); facep->getGeometryVolume(*volume, te_idx, vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); + + if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) + { + vobj->updateRelativeXform(false); + } } } -- cgit v1.2.3 From 5ef21ba6c5b0d6c8b5f201c7d2bede983504383c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 20 Apr 2012 00:58:55 -0500 Subject: MAINT-775 More edge case cleanup -- spinning child prims still break on deselect until the next LoD update --- indra/newview/llvovolume.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 847a3767bc..433fa475ee 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -684,7 +684,7 @@ void LLVOVolume::updateTextures() { updateTextureVirtualSize(); - if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) + /*if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) { //delete vertex buffer to free up some VRAM LLSpatialGroup* group = mDrawable->getSpatialGroup(); if (group) @@ -695,7 +695,7 @@ void LLVOVolume::updateTextures() //it becomes visible group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - } + }*/ } } @@ -3967,16 +3967,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLDrawable* drawable = facep->getDrawable(); - if (drawable->isActive()) + if (drawable->isState(LLDrawable::ANIMATED_CHILD)) { - if (drawable->isState(LLDrawable::ANIMATED_CHILD)) - { - model_mat = &drawable->getWorldMatrix(); - } - else - { - model_mat = &drawable->getRenderMatrix(); - } + model_mat = &drawable->getWorldMatrix(); + } + else if (drawable->isActive()) + { + model_mat = &drawable->getRenderMatrix(); } else { -- cgit v1.2.3 From 7a20b5be7844d1f41307d3186b0a9e297efd797a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 1 May 2012 15:33:16 -0500 Subject: MAINT-775, MAINT-1022 Regression cleanup. --- indra/newview/llvovolume.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 433fa475ee..3430e1a610 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -684,7 +684,7 @@ void LLVOVolume::updateTextures() { updateTextureVirtualSize(); - /*if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) + if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) { //delete vertex buffer to free up some VRAM LLSpatialGroup* group = mDrawable->getSpatialGroup(); if (group) @@ -695,7 +695,7 @@ void LLVOVolume::updateTextures() //it becomes visible group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } - }*/ + } } } @@ -1497,7 +1497,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity) { if (mVolumeImpl) { - mVolumeImpl->updateRelativeXform(); + mVolumeImpl->updateRelativeXform(force_identity); return; } @@ -3984,6 +3984,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } + //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD))); + U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; LLViewerTexture* tex = facep->getTexture(); -- cgit v1.2.3 From 71bbb384b056476bbf1177d20b2ade16ca0a4bcf Mon Sep 17 00:00:00 2001 From: "simon@Simon-PC.lindenlab.com" Date: Mon, 7 May 2012 13:24:52 -0700 Subject: MAINT-753 : [crashhunters] crash at LLVOVolume::updateFaceFlags(). Null pointer checks are good. Reviewed by Kelly --- indra/newview/llvovolume.cpp | 120 ++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 46 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3430e1a610..75ab807c39 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -520,6 +520,7 @@ void LLVOVolume::animateTextures() for (S32 i = start; i <= end; i++) { LLFace* facep = mDrawable->getFace(i); + if (!facep) continue; if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; const LLTextureEntry* te = facep->getTextureEntry(); @@ -734,8 +735,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) for (S32 i = 0; i < num_faces; i++) { LLFace* face = mDrawable->getFace(i); - face->setPixelArea(0.f); - face->setVirtualSize(0.f); + if (face) + { + face->setPixelArea(0.f); + face->setVirtualSize(0.f); + } } return ; @@ -765,6 +769,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) for (S32 i = 0; i < num_faces; i++) { LLFace* face = mDrawable->getFace(i); + if (!face) continue; const LLTextureEntry *te = face->getTextureEntry(); LLViewerTexture *imagep = face->getTexture(); if (!imagep || !te || @@ -1268,7 +1273,8 @@ BOOL LLVOVolume::calcLOD() llround(radius, 0.01f)); - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO)) + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) && + mDrawable->getFace(0)) { //setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); @@ -1347,25 +1353,23 @@ void LLVOVolume::updateFaceFlags() for (S32 i = 0; i < getVolume()->getNumFaces(); i++) { LLFace *face = mDrawable->getFace(i); - if (!face) + if (face) { - return; - } - - BOOL fullbright = getTE(i)->getFullbright(); - face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); + BOOL fullbright = getTE(i)->getFullbright(); + face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); - if (fullbright || (mMaterial == LL_MCODE_LIGHT)) - { - face->setState(LLFace::FULLBRIGHT); - } - if (mDrawable->isLight()) - { - face->setState(LLFace::LIGHT); - } - if (isHUDAttachment()) - { - face->setState(LLFace::HUD_RENDER); + if (fullbright || (mMaterial == LL_MCODE_LIGHT)) + { + face->setState(LLFace::FULLBRIGHT); + } + if (mDrawable->isLight()) + { + face->setState(LLFace::LIGHT); + } + if (isHUDAttachment()) + { + face->setState(LLFace::HUD_RENDER); + } } } } @@ -1402,6 +1406,8 @@ void LLVOVolume::regenFaces() for (S32 i = 0; i < mNumFaces; i++) { LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i); + if (!facep) continue; + facep->setTEOffset(i); facep->setTexture(getTEImage(i)); facep->setViewerObject(this); @@ -1747,16 +1753,19 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) void LLVOVolume::updateFaceSize(S32 idx) { LLFace* facep = mDrawable->getFace(idx); - if (idx >= getVolume()->getNumVolumeFaces()) + if (facep) { - facep->setSize(0,0, true); - } - else - { - const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, - true); // <--- volume faces should be padded for 16-byte alignment + if (idx >= getVolume()->getNumVolumeFaces()) + { + facep->setSize(0,0, true); + } + else + { + const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); + facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, + true); // <--- volume faces should be padded for 16-byte alignment + } } } @@ -3129,6 +3138,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const for (S32 i = 0; i < num_faces; ++i) { const LLFace* face = drawablep->getFace(i); + if (!face) continue; const LLTextureEntry* te = face->getTextureEntry(); const LLViewerTexture* img = face->getTexture(); @@ -3400,6 +3410,7 @@ F32 LLVOVolume::getBinRadius() for (S32 i = 0; i < mDrawable->getNumFaces(); i++) { LLFace* face = mDrawable->getFace(i); + if (!face) continue; if (face->getPoolType() == LLDrawPool::POOL_ALPHA && !face->canRenderAsMask()) { @@ -3623,7 +3634,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { LLFace* face = mDrawable->getFace(face_hit); - if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))) + if (face && + (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))) { v_end = p; if (face_hitp != NULL) @@ -4233,6 +4245,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) for (S32 i = 0; i < drawablep->getNumFaces(); i++) { LLFace* facep = drawablep->getFace(i); + if (!facep) + { + continue; + } //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group @@ -4453,12 +4469,20 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) S32 face; for (face = 0; face < vobj->getNumTEs(); face++) { - drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM); + LLFace * facep = drawablep->getFace(face); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } } } else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) { - drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM); + LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } } } @@ -4682,10 +4706,13 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); - LLVertexBuffer* buff = face->getVertexBuffer(); - if (face && buff && buff->isLocked()) + if (face) { - buff->flush(); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff && buff->isLocked()) + { + buff->flush(); + } } } } @@ -5166,20 +5193,21 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun //sum up face verts and indices drawablep->updateFaceSize(i); LLFace* facep = drawablep->getFace(i); - - - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && - facep->getGeomCount() + vertex_count <= 65536) + if (facep) { - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && + facep->getGeomCount() + vertex_count <= 65536) + { + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); - //remember face (for sorting) - mFaceList.push_back(facep); - } - else - { - facep->clearVertexBuffer(); + //remember face (for sorting) + mFaceList.push_back(facep); + } + else + { + facep->clearVertexBuffer(); + } } } } -- cgit v1.2.3 From 89b0b6ac7198653d989dea78ee1c3d3f4f61161f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 15 May 2012 16:42:04 -0500 Subject: MAINT-616 Different VBO Pooling scheme -- populate VBO pool with buffers that are likely to be requested, but never reuse a previously used buffer. --- indra/newview/llvovolume.cpp | 755 ++++++++++++++++++++++--------------------- 1 file changed, 394 insertions(+), 361 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 75ab807c39..6d4565ec2f 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -639,7 +639,7 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { LLViewerObject::idleUpdate(agent, world, time); - static LLFastTimer::DeclareTimer ftm("Volume"); + static LLFastTimer::DeclareTimer ftm("Volume Idle"); LLFastTimer t(ftm); if (mDead || mDrawable.isNull()) @@ -3945,8 +3945,11 @@ bool can_batch_texture(LLFace* facep) return true; } +static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face"); + void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) { + LLFastTimer t(FTM_REGISTER_FACE); LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) @@ -4091,7 +4094,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) } -static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume VB"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_FACE_LIST("Build Face List"); +static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info"); static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj) { @@ -4122,6 +4127,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj) void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { + + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -4133,17 +4140,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) { - LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); - rebuildMesh(group); } return; } + LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); + group->mBuilt = 1.f; - LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); - LLVOAvatar* pAvatarVO = NULL; LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); @@ -4192,371 +4197,375 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool emissive = false; - //get all the faces into a list - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; - - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); + + //get all the faces into a list + for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { - continue; - } + LLDrawable* drawablep = *drawable_iter; + + if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + { + continue; + } - if (drawablep->isAnimating()) - { //fall back to stream draw for animating verts - useage = GL_STREAM_DRAW_ARB; - } + if (drawablep->isAnimating()) + { //fall back to stream draw for animating verts + useage = GL_STREAM_DRAW_ARB; + } - LLVOVolume* vobj = drawablep->getVOVolume(); + LLVOVolume* vobj = drawablep->getVOVolume(); - if (!vobj) - { - continue; - } + if (!vobj) + { + continue; + } - if (vobj->isMesh() && - (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) - { - continue; - } + if (vobj->isMesh() && + (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) + { + continue; + } - LLVolume* volume = vobj->getVolume(); - if (volume) - { - const LLVector3& scale = vobj->getScale(); - group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); - } + LLVolume* volume = vobj->getVolume(); + if (volume) + { + const LLVector3& scale = vobj->getScale(); + group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); + } - llassert_always(vobj); - vobj->updateTextureVirtualSize(true); - vobj->preRebuild(); + llassert_always(vobj); + vobj->updateTextureVirtualSize(true); + vobj->preRebuild(); - drawablep->clearState(LLDrawable::HAS_ALPHA); + drawablep->clearState(LLDrawable::HAS_ALPHA); - bool rigged = vobj->isAttachment() && - vobj->isMesh() && - gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); + bool rigged = vobj->isAttachment() && + vobj->isMesh() && + gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj); - bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); + bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); - bool is_rigged = false; + bool is_rigged = false; - //for each face - for (S32 i = 0; i < drawablep->getNumFaces(); i++) - { - LLFace* facep = drawablep->getFace(i); - if (!facep) + //for each face + for (S32 i = 0; i < drawablep->getNumFaces(); i++) { - continue; - } + LLFace* facep = drawablep->getFace(i); + if (!facep) + { + continue; + } - //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render - // batch, it will recover its vertex buffer reference from the spatial group - facep->setVertexBuffer(NULL); + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render + // batch, it will recover its vertex buffer reference from the spatial group + facep->setVertexBuffer(NULL); - //sum up face verts and indices - drawablep->updateFaceSize(i); + //sum up face verts and indices + drawablep->updateFaceSize(i); - if (rigged) - { - if (!facep->isState(LLFace::RIGGED)) - { //completely reset vertex buffer - facep->clearVertexBuffer(); - } + if (rigged) + { + if (!facep->isState(LLFace::RIGGED)) + { //completely reset vertex buffer + facep->clearVertexBuffer(); + } - facep->setState(LLFace::RIGGED); - is_rigged = true; + facep->setState(LLFace::RIGGED); + is_rigged = true; - //get drawpool of avatar with rigged face - LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); + //get drawpool of avatar with rigged face + LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); - //Determine if we've received skininfo that contains an - //alternate bind matrix - if it does then apply the translational component - //to the joints of the avatar. - bool pelvisGotSet = false; + //Determine if we've received skininfo that contains an + //alternate bind matrix - if it does then apply the translational component + //to the joints of the avatar. + bool pelvisGotSet = false; - if ( pAvatarVO ) - { - LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); - const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); - - if ( pSkinData ) + if ( pAvatarVO ) { - const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) - { - const int jointCnt = pSkinData->mJointNames.size(); - const F32 pelvisZOffset = pSkinData->mPelvisOffset; - bool fullRig = (jointCnt>=20) ? true : false; - if ( fullRig ) - { - for ( int i=0; igetVolume()->getParams().getSculptID(); + const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj ); + + if ( pSkinData ) + { + const int bindCnt = pSkinData->mAlternateBindMatrix.size(); + if ( bindCnt > 0 ) + { + const int jointCnt = pSkinData->mJointNames.size(); + const F32 pelvisZOffset = pSkinData->mPelvisOffset; + bool fullRig = (jointCnt>=20) ? true : false; + if ( fullRig ) { - std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); - //llinfos<<"joint name "<getJoint( lookingForJoint ); - if ( pJoint && pJoint->getId() != currentId ) - { - pJoint->setId( currentId ); - const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); - //Set the joint position - pJoint->storeCurrentXform( jointPos ); - //If joint is a pelvis then handle old/new pelvis to foot values - if ( lookingForJoint == "mPelvis" ) - { + for ( int i=0; imJointNames[i].c_str(); + //llinfos<<"joint name "<getJoint( lookingForJoint ); + if ( pJoint && pJoint->getId() != currentId ) + { + pJoint->setId( currentId ); + const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); + //Set the joint position pJoint->storeCurrentXform( jointPos ); - if ( !pAvatarVO->hasPelvisOffset() ) - { - pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); - //Trigger to rebuild viewer AV - pelvisGotSet = true; + //If joint is a pelvis then handle old/new pelvis to foot values + if ( lookingForJoint == "mPelvis" ) + { + pJoint->storeCurrentXform( jointPos ); + if ( !pAvatarVO->hasPelvisOffset() ) + { + pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); + //Trigger to rebuild viewer AV + pelvisGotSet = true; + } } - } + } } - } - } + } + } } } - } - //If we've set the pelvis to a new position we need to also rebuild some information that the - //viewer does at launch (e.g. body size etc.) - if ( pelvisGotSet ) - { - pAvatarVO->postPelvisSetRecalc(); - } - - if (pool) - { - const LLTextureEntry* te = facep->getTextureEntry(); - - //remove face from old pool if it exists - LLDrawPool* old_pool = facep->getPool(); - if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) + //If we've set the pelvis to a new position we need to also rebuild some information that the + //viewer does at launch (e.g. body size etc.) + if ( pelvisGotSet ) { - ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); + pAvatarVO->postPelvisSetRecalc(); } - //add face to new pool - LLViewerTexture* tex = facep->getTexture(); - U32 type = gPipeline.getPoolTypeFromTE(te, tex); - - if (type == LLDrawPool::POOL_ALPHA) + if (pool) { - if (te->getColor().mV[3] > 0.f) + const LLTextureEntry* te = facep->getTextureEntry(); + + //remove face from old pool if it exists + LLDrawPool* old_pool = facep->getPool(); + if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) + { + ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); + } + + //add face to new pool + LLViewerTexture* tex = facep->getTexture(); + U32 type = gPipeline.getPoolTypeFromTE(te, tex); + + if (type == LLDrawPool::POOL_ALPHA) + { + if (te->getColor().mV[3] > 0.f) + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + } + } + } + else if (te->getShiny()) { if (te->getFullbright()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); } else { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + if (LLPipeline::sRenderDeferred) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + } } } - } - else if (te->getShiny()) - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); - } else { - if (LLPipeline::sRenderDeferred) + if (te->getFullbright()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); } else { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); } } - } - else - { - if (te->getFullbright()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); - } - else + + if (te->getGlow()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); } - } - - if (te->getGlow()) - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); - } - if (LLPipeline::sRenderDeferred) - { - if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) + if (LLPipeline::sRenderDeferred) { - if (te->getBumpmap()) + if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + if (te->getBumpmap()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + } } } } - } - continue; - } - else - { - if (facep->isState(LLFace::RIGGED)) - { //face is not rigged but used to be, remove from rigged face pool - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); - if (pool) - { - pool->removeRiggedFace(facep); - } - facep->clearState(LLFace::RIGGED); + continue; } - } - - - if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) - { - facep->clearVertexBuffer(); - continue; - } - - cur_total += facep->getGeomCount(); - - if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) - { - const LLTextureEntry* te = facep->getTextureEntry(); - LLViewerTexture* tex = facep->getTexture(); - - if (te->getGlow() >= 1.f/255.f) - { - emissive = true; - } - - if (facep->isState(LLFace::TEXTURE_ANIM)) + else { - if (!vobj->mTexAnimMode) - { - facep->clearState(LLFace::TEXTURE_ANIM); + if (facep->isState(LLFace::RIGGED)) + { //face is not rigged but used to be, remove from rigged face pool + LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); + if (pool) + { + pool->removeRiggedFace(facep); + } + facep->clearState(LLFace::RIGGED); } } - BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); - U32 type = gPipeline.getPoolTypeFromTE(te, tex); - if (type != LLDrawPool::POOL_ALPHA && force_simple) - { - type = LLDrawPool::POOL_SIMPLE; - } - facep->setPoolType(type); - if (vobj->isHUDAttachment()) + if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) { - facep->setState(LLFace::FULLBRIGHT); + facep->clearVertexBuffer(); + continue; } - if (vobj->mTextureAnimp && vobj->mTexAnimMode) + cur_total += facep->getGeomCount(); + + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) { - if (vobj->mTextureAnimp->mFace <= -1) + const LLTextureEntry* te = facep->getTextureEntry(); + LLViewerTexture* tex = facep->getTexture(); + + if (te->getGlow() >= 1.f/255.f) { - S32 face; - for (face = 0; face < vobj->getNumTEs(); face++) - { - LLFace * facep = drawablep->getFace(face); - if (facep) - { - facep->setState(LLFace::TEXTURE_ANIM); - } - } + emissive = true; } - else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) + + if (facep->isState(LLFace::TEXTURE_ANIM)) { - LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); - if (facep) + if (!vobj->mTexAnimMode) { - facep->setState(LLFace::TEXTURE_ANIM); + facep->clearState(LLFace::TEXTURE_ANIM); } } - } - if (type == LLDrawPool::POOL_ALPHA) - { - if (facep->canRenderAsMask()) - { //can be treated as alpha mask - simple_faces.push_back(facep); - } - else + BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); + U32 type = gPipeline.getPoolTypeFromTE(te, tex); + if (type != LLDrawPool::POOL_ALPHA && force_simple) { - if (te->getColor().mV[3] > 0.f) - { //only treat as alpha in the pipeline if < 100% transparent - drawablep->setState(LLDrawable::HAS_ALPHA); - } - alpha_faces.push_back(facep); + type = LLDrawPool::POOL_SIMPLE; } - } - else - { - if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + facep->setPoolType(type); + + if (vobj->isHUDAttachment()) { - facep->mLastUpdateTime = gFrameTimeSeconds; + facep->setState(LLFace::FULLBRIGHT); } - if (gPipeline.canUseWindLightShadersOnObjects() - && LLPipeline::sRenderBump) + if (vobj->mTextureAnimp && vobj->mTexAnimMode) { - if (te->getBumpmap()) - { //needs normal + binormal - bump_faces.push_back(facep); + if (vobj->mTextureAnimp->mFace <= -1) + { + S32 face; + for (face = 0; face < vobj->getNumTEs(); face++) + { + LLFace * facep = drawablep->getFace(face); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } + } + } + else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs()) + { + LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace); + if (facep) + { + facep->setState(LLFace::TEXTURE_ANIM); + } } - else if (te->getShiny() || !te->getFullbright()) - { //needs normal + } + + if (type == LLDrawPool::POOL_ALPHA) + { + if (facep->canRenderAsMask()) + { //can be treated as alpha mask simple_faces.push_back(facep); } - else - { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); - fullbright_faces.push_back(facep); + else + { + if (te->getColor().mV[3] > 0.f) + { //only treat as alpha in the pipeline if < 100% transparent + drawablep->setState(LLDrawable::HAS_ALPHA); + } + alpha_faces.push_back(facep); } } else { - if (te->getBumpmap() && LLPipeline::sRenderBump) - { //needs normal + binormal - bump_faces.push_back(facep); + if (drawablep->isState(LLDrawable::REBUILD_VOLUME)) + { + facep->mLastUpdateTime = gFrameTimeSeconds; } - else if ((te->getShiny() && LLPipeline::sRenderBump) || - !(te->getFullbright() || bake_sunlight)) - { //needs normal - simple_faces.push_back(facep); + + if (gPipeline.canUseWindLightShadersOnObjects() + && LLPipeline::sRenderBump) + { + if (te->getBumpmap()) + { //needs normal + binormal + bump_faces.push_back(facep); + } + else if (te->getShiny() || !te->getFullbright()) + { //needs normal + simple_faces.push_back(facep); + } + else + { //doesn't need normal + facep->setState(LLFace::FULLBRIGHT); + fullbright_faces.push_back(facep); + } } - else - { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); - fullbright_faces.push_back(facep); + else + { + if (te->getBumpmap() && LLPipeline::sRenderBump) + { //needs normal + binormal + bump_faces.push_back(facep); + } + else if ((te->getShiny() && LLPipeline::sRenderBump) || + !(te->getFullbright() || bake_sunlight)) + { //needs normal + simple_faces.push_back(facep); + } + else + { //doesn't need normal + facep->setState(LLFace::FULLBRIGHT); + fullbright_faces.push_back(facep); + } } } } + else + { //face has no renderable geometry + facep->clearVertexBuffer(); + } } - else - { //face has no renderable geometry - facep->clearVertexBuffer(); - } - } - if (is_rigged) - { - drawablep->setState(LLDrawable::RIGGED); - } - else - { - drawablep->clearState(LLDrawable::RIGGED); + if (is_rigged) + { + drawablep->setState(LLDrawable::RIGGED); + } + else + { + drawablep->clearState(LLDrawable::RIGGED); + } } } @@ -4623,15 +4632,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } -static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry"); -static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild"); void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { llassert(group); if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) { - LLFastTimer tm(FTM_VOLUME_GEOM); + LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); + LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers + S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ; group->mBuilt = 1.f; @@ -4640,7 +4649,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { - LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL); LLDrawable* drawablep = *drawable_iter; if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) ) @@ -4747,8 +4755,20 @@ struct CompareBatchBreakerModified } }; +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FIND_VB("Find VB"); +static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); + + + + + void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector& faces, BOOL distance_sort, BOOL batch_textures) { + LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); + U32 buffer_usage = group->mBufferUsage; #if LL_DARWIN @@ -4766,15 +4786,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); - if (!distance_sort) - { - //sort faces by things that break batches - std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); - } - else { - //sort faces by distance - std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); + LLFastTimer t(FTM_GEN_DRAW_INFO_SORT); + if (!distance_sort) + { + //sort faces by things that break batches + std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified()); + } + else + { + //sort faces by distance + std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater()); + } } bool hud_group = group->isHUDGroup() ; @@ -4839,57 +4862,86 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: std::vector texture_list; - if (batch_textures) { - U8 cur_tex = 0; - facep->setTextureIndex(cur_tex); - texture_list.push_back(tex); - - //if (can_batch_texture(facep)) + LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); + if (batch_textures) { - while (i != faces.end()) + U8 cur_tex = 0; + facep->setTextureIndex(cur_tex); + texture_list.push_back(tex); + + //if (can_batch_texture(facep)) { - facep = *i; - if (facep->getTexture() != tex) + while (i != faces.end()) { - if (distance_sort) - { //textures might be out of order, see if texture exists in current batch - bool found = false; - for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) - { - if (facep->getTexture() == texture_list[tex_idx]) + facep = *i; + if (facep->getTexture() != tex) + { + if (distance_sort) + { //textures might be out of order, see if texture exists in current batch + bool found = false; + for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx) { - cur_tex = tex_idx; - found = true; - break; + if (facep->getTexture() == texture_list[tex_idx]) + { + cur_tex = tex_idx; + found = true; + break; + } } - } - if (!found) + if (!found) + { + cur_tex = texture_list.size(); + } + } + else { - cur_tex = texture_list.size(); + cur_tex++; } - } - else - { - cur_tex++; - } - if (!can_batch_texture(facep)) - { //face is bump mapped or has an animated texture matrix -- can't - //batch more than 1 texture at a time - break; + if (!can_batch_texture(facep)) + { //face is bump mapped or has an animated texture matrix -- can't + //batch more than 1 texture at a time + break; + } + + if (cur_tex >= texture_index_channels) + { //cut batches when index channels are depleted + break; + } + + tex = facep->getTexture(); + + texture_list.push_back(tex); } - if (cur_tex >= texture_index_channels) - { //cut batches when index channels are depleted + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut batches on geom count too big break; } - tex = facep->getTexture(); + ++i; + index_count += facep->getIndicesCount(); + geom_count += facep->getGeomCount(); - texture_list.push_back(tex); + facep->setTextureIndex(cur_tex); } + } + + tex = texture_list[0]; + } + else + { + while (i != faces.end() && + (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) + { + facep = *i; + + + //face has no texture index + facep->mDrawInfo = NULL; + facep->setTextureIndex(255); if (geom_count + facep->getGeomCount() > max_vertices) { //cut batches on geom count too big @@ -4899,40 +4951,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: ++i; index_count += facep->getIndicesCount(); geom_count += facep->getGeomCount(); - - facep->setTextureIndex(cur_tex); } } - - tex = texture_list[0]; } - else - { - while (i != faces.end() && - (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) - { - facep = *i; - - //face has no texture index - facep->mDrawInfo = NULL; - facep->setTextureIndex(255); - - if (geom_count + facep->getGeomCount() > max_vertices) - { //cut batches on geom count too big - break; - } - - ++i; - index_count += facep->getIndicesCount(); - geom_count += facep->getGeomCount(); - } - } - //create/delete/resize vertex buffer if needed LLVertexBuffer* buffer = NULL; + if (group->mBufferUsage != GL_DYNAMIC_DRAW_ARB) { //try to find a buffer to reuse + LLFastTimer t(FTM_GEN_DRAW_INFO_FIND_VB); LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); if (found_iter != group->mBufferMap[mask].end()) @@ -4943,23 +4971,28 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } } - - if (!buffer || !buffer->isWriteable()) - { //create new buffer if needed - buffer = createVertexBuffer(mask, buffer_usage); - buffer->allocateBuffer(geom_count, index_count, TRUE); - } - else - { //resize pre-existing buffer - if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage || - buffer->getTypeMask() != mask) - { + + { + LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE); + + if (!buffer || !buffer->isWriteable()) + { //create new buffer if needed buffer = createVertexBuffer(mask, buffer_usage); buffer->allocateBuffer(geom_count, index_count, TRUE); } - else - { - buffer->resizeBuffer(geom_count, index_count); + else + { //resize pre-existing buffer + LLFastTimer t(FTM_GEN_DRAW_INFO_RESIZE_VB); + if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage || + buffer->getTypeMask() != mask) + { + buffer = createVertexBuffer(mask, buffer_usage); + buffer->allocateBuffer(geom_count, index_count, TRUE); + } + else + { + buffer->resizeBuffer(geom_count, index_count); + } } } -- cgit v1.2.3 From b7cfd8c7f09a1a913c5678a5a25a951307593eb3 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 21 May 2012 23:33:25 -0500 Subject: MAINT-616 Factor out calls to glGenFoo where possible, add setting to control synchronizing strategy WRT occlusion queries, add experimental transform feedback driven LoD update --- indra/newview/llvovolume.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6d4565ec2f..6bb4e9e63b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1089,9 +1089,33 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } + + static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + + bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && + (!mVolumeImpl || !mVolumeImpl->isVolumeUnique()); + + if (cache_in_vram) + { //this volume might be used as source data for a transform object, put it in vram + LLVolume* volume = getVolume(); + for (S32 i = 0; i < volume->getNumFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + if (face.mVertexBuffer.notNull()) + { //already cached + break; + } + volume->genBinormals(i); + LLFace::cacheFaceInVRAM(face); + } + } + + return TRUE; } + + return FALSE; } -- cgit v1.2.3 From b9606f57c32dc021fd967a40aebc1d2a44bea0bd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 22 May 2012 00:04:13 -0500 Subject: MAINT-616 Minor raycasting optimization. --- indra/newview/llvovolume.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6bb4e9e63b..ba117ed977 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3516,9 +3516,12 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const { LLVector3 ret = pos - getRenderPosition(); ret = ret * ~getRenderRotation(); - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); - ret.scaleVec(invObjScale); + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]); + ret.scaleVec(invObjScale); + } return ret; } @@ -3536,8 +3539,12 @@ LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const { LLVector3 ret = dir; - LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale(); - ret.scaleVec(objScale); + if (!isVolumeGlobal()) + { + LLVector3 objScale = getScale(); + ret.scaleVec(objScale); + } + ret = ret * getRenderRotation(); ret += getRenderPosition(); -- cgit v1.2.3 From 8c5bf1d0bac65053469888c27523e6bf30ee53cf Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 29 May 2012 13:29:03 -0500 Subject: MAINT-775 Fix for regression where rigged attachments get distorted on region crossing or teleport. --- indra/newview/llvovolume.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ba117ed977..9d6a12cc6e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4682,7 +4682,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLDrawable* drawablep = *drawable_iter; - if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) ) + if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); @@ -4701,6 +4701,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLVertexBuffer* buff = face->getVertexBuffer(); if (buff) { + llassert(!face->isState(LLFace::RIGGED)); face->getGeometryVolume(*volume, face->getTEOffset(), vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); @@ -5066,6 +5067,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U32 te_idx = facep->getTEOffset(); + llassert(!facep->isState(LLFace::RIGGED)); + facep->getGeometryVolume(*volume, te_idx, vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); -- cgit v1.2.3 From defbd61d318d0da12fdea208cf2b2297d9a6b122 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 31 May 2012 13:25:19 -0500 Subject: MAINT-639 Fix for random rainbow effects on some prims. --- indra/newview/llvovolume.cpp | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) (limited to 'indra/newview/llvovolume.cpp') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 9d6a12cc6e..c4e7ea44b4 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4987,45 +4987,13 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } - //create/delete/resize vertex buffer if needed + //create vertex buffer LLVertexBuffer* buffer = NULL; - if (group->mBufferUsage != GL_DYNAMIC_DRAW_ARB) - { //try to find a buffer to reuse - LLFastTimer t(FTM_GEN_DRAW_INFO_FIND_VB); - LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); - - if (found_iter != group->mBufferMap[mask].end()) - { - if ((U32) buffer_index < found_iter->second.size()) - { - buffer = found_iter->second[buffer_index]; - } - } - } - { LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE); - - if (!buffer || !buffer->isWriteable()) - { //create new buffer if needed - buffer = createVertexBuffer(mask, buffer_usage); - buffer->allocateBuffer(geom_count, index_count, TRUE); - } - else - { //resize pre-existing buffer - LLFastTimer t(FTM_GEN_DRAW_INFO_RESIZE_VB); - if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage || - buffer->getTypeMask() != mask) - { - buffer = createVertexBuffer(mask, buffer_usage); - buffer->allocateBuffer(geom_count, index_count, TRUE); - } - else - { - buffer->resizeBuffer(geom_count, index_count); - } - } + buffer = createVertexBuffer(mask, buffer_usage); + buffer->allocateBuffer(geom_count, index_count, TRUE); } group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); @@ -5070,7 +5038,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: llassert(!facep->isState(LLFace::RIGGED)); facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true); if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) { -- cgit v1.2.3