From 7235799a022ec6aeebb4dcae262e6d453b67f61c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 29 Apr 2021 00:09:00 +0300 Subject: [PATCH 1/3] SL-15183 Crash at LLModel::matchMaterialOrder --- indra/llprimitive/llmodel.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 548913ecaf..a2596335c2 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1277,6 +1277,14 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."< ref->mMaterialList.size()) + { + LL_INFOS("MESHSKININFO") << "Material of model has more materials than a reference." << LL_ENDL; + // We passed isMaterialListSubset, so materials are a subset, but subset isn't supposed to be + // larger than original and if we keep going, reordering will cause a crash + return false; + } std::map index_map; From 22cb7f469ebde3e5da5effdad521bb961057fc02 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 29 Apr 2021 09:06:29 +0200 Subject: [PATCH 2/3] Manually apply SL-15181 Crash at LLSkinningUtil::initSkinningMatrixPalette --- indra/newview/llskinningutil.cpp | 140 +++++++++++++++++-------------- 1 file changed, 75 insertions(+), 65 deletions(-) diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index d1e3e9b943..7e40bffc4e 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -132,47 +132,52 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin // Per frame SkinningMatrix Caching //void LLSkinningUtil::initSkinningMatrixPalette( -// LLMatrix4* mat, -// S32 count, -// const LLMeshSkinInfo* skin, -// LLVOAvatar *avatar) +// LLMatrix4* mat, +// S32 count, +// const LLMeshSkinInfo* skin, +// LLVOAvatar *avatar) //{ -// initJointNums(const_cast(skin), avatar); -// for (U32 j = 0; j < count; ++j) -// { -// LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); -// llassert(joint); -// if (joint) -// { +// initJointNums(const_cast(skin), avatar); +// for (U32 j = 0; j < count; ++j) +// { +// S32 joint_num = skin->mJointNums[j]; +// LLJoint * joint = NULL; +// if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) +// { +// joint = avatar->getJoint(joint_num); +// } +// llassert(joint); +// if (joint) +// { //#ifdef MAT_USE_SSE -// LLMatrix4a bind, world, res; -// bind.loadu(skin->mInvBindMatrix[j]); -// world.loadu(joint->getWorldMatrix()); -// matMul(bind, world, res); -// memcpy(mat[j].mMatrix, res.mMatrix, 16 * sizeof(float)); +// LLMatrix4a bind, world, res; +// bind.loadu(skin->mInvBindMatrix[j]); +// world.loadu(joint->getWorldMatrix()); +// matMul(bind, world, res); +// memcpy(mat[j].mMatrix, res.mMatrix, 16 * sizeof(float)); //#else -// mat[j] = skin->mInvBindMatrix[j]; -// mat[j] *= joint->getWorldMatrix(); +// mat[j] = skin->mInvBindMatrix[j]; +// mat[j] *= joint->getWorldMatrix(); //#endif -// } -// else -// { -// mat[j] = skin->mInvBindMatrix[j]; +// } +// else +// { +// mat[j] = skin->mInvBindMatrix[j]; //#if DEBUG_SKINNING -// // This shouldn't happen - in mesh upload, skinned -// // rendering should be disabled unless all joints are -// // valid. In other cases of skinned rendering, invalid -// // joints should already have been removed during scrubInvalidJoints(). -// LL_WARNS_ONCE("Avatar") << avatar->getFullname() -// << " rigged to invalid joint name " << skin->mJointNames[j] -// << " num " << skin->mJointNums[j] << LL_ENDL; -// LL_WARNS_ONCE("Avatar") << avatar->getFullname() -// << " avatar build state: isBuilt() " << avatar->isBuilt() -// << " mInitFlags " << avatar->mInitFlags << LL_ENDL; +// // This shouldn't happen - in mesh upload, skinned +// // rendering should be disabled unless all joints are +// // valid. In other cases of skinned rendering, invalid +// // joints should already have been removed during scrubInvalidJoints(). +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " rigged to invalid joint name " << skin->mJointNames[j] +// << " num " << skin->mJointNums[j] << LL_ENDL; +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " avatar build state: isBuilt() " << avatar->isBuilt() +// << " mInitFlags " << avatar->mInitFlags << LL_ENDL; //#endif -// dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); -// } -// } +// dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); +// } +// } //} #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -186,44 +191,49 @@ void LLSkinningUtil::initSkinningMatrixPalette( LLVOAvatar *avatar) { #ifndef LL_RELEASE_FOR_DOWNLOAD - // This timer is too hot for normal use (though better now with caching) - LL_RECORD_BLOCK_TIME(FTM_SKINNING_INIT); + // This timer is too hot for normal use (though better now with caching) + LL_RECORD_BLOCK_TIME(FTM_SKINNING_INIT); #endif - LLMatrix4a bind[LL_MAX_JOINTS_PER_MESH_OBJECT]; - LLMatrix4a world[LL_MAX_JOINTS_PER_MESH_OBJECT]; + LLMatrix4a bind[LL_MAX_JOINTS_PER_MESH_OBJECT]; + LLMatrix4a world[LL_MAX_JOINTS_PER_MESH_OBJECT]; - initJointNums(const_cast(skin), avatar); + initJointNums(const_cast(skin), avatar); // TODO: Refactored to encourage the compiler to optimise better but it's too old and stubborn. Need to hand tool the SIMD. // TODO: There are two overheads in this function casued by the unaligned loads. use Matrix4a // TODO: getWorldMatrix forces a reverse recursion up through the skelly. Check if this is happening efficiently. - for (U32 j = 0; j < count; ++j) + for (U32 j = 0; j < count; ++j) { - LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); - if (joint) - { - bind[j].loadu(skin->mInvBindMatrix[j]); - world[j].loadu(joint->getWorldMatrix()); - matMul(bind[j], world[j], mat[j]); - } - else - { - mat[j].loadu(skin->mInvBindMatrix[j]); + S32 joint_num = skin->mJointNums[j]; + LLJoint * joint = NULL; + if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) + { + joint = avatar->getJoint(joint_num); + } + if (joint) + { + bind[j].loadu(skin->mInvBindMatrix[j]); + world[j].loadu(joint->getWorldMatrix()); + matMul(bind[j], world[j], mat[j]); + } + else + { + mat[j].loadu(skin->mInvBindMatrix[j]); #if DEBUG_SKINNING - // This shouldn't happen - in mesh upload, skinned - // rendering should be disabled unless all joints are - // valid. In other cases of skinned rendering, invalid - // joints should already have been removed during scrubInvalidJoints(). - // Beq note - Oct 2018 Animesh - Many rigged meshes still fail here. ('mElbowLeeft' typo in the rigging data) - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " rigged to invalid joint name " << skin->mJointNames[j] - << " num " << skin->mJointNums[j] << LL_ENDL; - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " avatar build state: isBuilt() " << avatar->isBuilt() - << " mInitFlags " << avatar->mInitFlags << LL_ENDL; + // This shouldn't happen - in mesh upload, skinned + // rendering should be disabled unless all joints are + // valid. In other cases of skinned rendering, invalid + // joints should already have been removed during scrubInvalidJoints(). + // Beq note - Oct 2018 Animesh - Many rigged meshes still fail here. ('mElbowLeeft' typo in the rigging data) + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " rigged to invalid joint name " << skin->mJointNames[j] + << " num " << skin->mJointNums[j] << LL_ENDL; + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " avatar build state: isBuilt() " << avatar->isBuilt() + << " mInitFlags " << avatar->mInitFlags << LL_ENDL; #endif - } + } //LL_DEBUGS("Skinning") << "[" << avatar->getFullname() << "] joint(" << skin->mJointNames[j] << ") matices bind(" << bind << ") world(" << world << ")" << LL_ENDL; } } @@ -232,7 +242,7 @@ void LLSkinningUtil::initSkinningMatrixPalette( void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) { #if DEBUG_SKINNING - const S32 max_joints = skin->mJointNames.size(); + const S32 max_joints = skin->mJointNames.size(); for (U32 j=0; j 0.0f && num_joints > joint_index) { S32 joint_num = skin->mJointNums[joint_index]; From 420cbaa6452f39892509e6f898bb443ed8d3caf2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 29 Apr 2021 13:35:28 +0300 Subject: [PATCH 3/3] SL-15188 Crash at SecondLifeViewer!LLUUID::isNull(1007) Crash at getNormalID().isNull() --- indra/newview/llface.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6576ab783a..316951c316 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1144,6 +1144,13 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs F32 map_rot = 0.f, map_scaleS = 0.f, map_scaleT = 0.f, map_offsS = 0.f, map_offsT = 0.f; + LLMaterial* mat = orig_tep->getMaterialParams(); + if (!mat && map != LLRender::DIFFUSE_MAP) + { + LL_WARNS_ONCE("llface") << "Face is set to use specular or normal map but has no material, defaulting to diffuse" << LL_ENDL; + map = LLRender::DIFFUSE_MAP; + } + switch (map) { case LLRender::DIFFUSE_MAP: @@ -1154,26 +1161,26 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs map_offsT = orig_tep->mOffsetT; break; case LLRender::NORMAL_MAP: - if (orig_tep->getMaterialParams()->getNormalID().isNull()) + if (mat->getNormalID().isNull()) { return false; } - map_rot = orig_tep->getMaterialParams()->getNormalRotation(); - map_scaleS = orig_tep->getMaterialParams()->getNormalRepeatX(); - map_scaleT = orig_tep->getMaterialParams()->getNormalRepeatY(); - map_offsS = orig_tep->getMaterialParams()->getNormalOffsetX(); - map_offsT = orig_tep->getMaterialParams()->getNormalOffsetY(); + map_rot = mat->getNormalRotation(); + map_scaleS = mat->getNormalRepeatX(); + map_scaleT = mat->getNormalRepeatY(); + map_offsS = mat->getNormalOffsetX(); + map_offsT = mat->getNormalOffsetY(); break; case LLRender::SPECULAR_MAP: - if (orig_tep->getMaterialParams()->getSpecularID().isNull()) + if (mat->getSpecularID().isNull()) { return false; } - map_rot = orig_tep->getMaterialParams()->getSpecularRotation(); - map_scaleS = orig_tep->getMaterialParams()->getSpecularRepeatX(); - map_scaleT = orig_tep->getMaterialParams()->getSpecularRepeatY(); - map_offsS = orig_tep->getMaterialParams()->getSpecularOffsetX(); - map_offsT = orig_tep->getMaterialParams()->getSpecularOffsetY(); + map_rot = mat->getSpecularRotation(); + map_scaleS = mat->getSpecularRepeatX(); + map_scaleT = mat->getSpecularRepeatY(); + map_offsS = mat->getSpecularOffsetX(); + map_offsT = mat->getSpecularOffsetY(); break; default: /*make compiler happy*/ break;