From 8e725e74aa4cebdc472844252adf5b2952f7e3ff Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 26 Jul 2021 21:20:53 +0300 Subject: DRTVWR-542 Attempt to simplify all faces of an object as a whole and split back into faces #2 --- indra/llmath/llvolume.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e085fa6ada..b036ece71e 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6327,9 +6327,9 @@ void LLVolumeFace::resizeVertices(S32 num_verts) if (num_verts) { //pad texture coordinate block end to allow for QWORD reads - S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; + S32 tc_size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; - mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size); + mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+tc_size); mNormals = mPositions+num_verts; mTexCoords = (LLVector2*) (mNormals+num_verts); -- cgit v1.2.3 From 2d2ed85c56c0aa47e6909becaf60b71f1daaf46f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 28 Jul 2021 21:30:49 +0300 Subject: DRTVWR-542 Fix malfunctioning warning --- indra/llmath/llvolume.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index a77e8c08c6..c0b224b1ff 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -936,17 +936,23 @@ public: LLVector4a* mCenter; LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face. - S32 mNumVertices; + S32 mNumVertices; // num vertices == num normals == num texcoords S32 mNumAllocatedVertices; S32 mNumIndices; - LLVector4a* mPositions; - LLVector4a* mNormals; + LLVector4a* mPositions; // Contains vertices, nortmals and texcoords + LLVector4a* mNormals; // pointer into mPositions LLVector4a* mTangents; - LLVector2* mTexCoords; + LLVector2* mTexCoords; // pointer into mPositions + + // mIndices contains mNumIndices amount of elements. + // It contains triangles, each 3 indices describe one triangle. + // If mIndices contains {0, 2, 3, 1, 2, 4}, it means there + // are two triangles {0, 2, 3} and {1, 2, 4} with values being + // indexes for mPositions/mNormals/mTexCoords U16* mIndices; - //vertex buffer filled in by LLFace to cache this volume face geometry in vram + // vertex buffer filled in by LLFace to cache this volume face geometry in vram // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer) mutable LLPointer mVertexBuffer; -- cgit v1.2.3 From f79890669dcf8e44b5ec3ce1abbd1d1fdd34eb3b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 20 Sep 2021 18:58:09 +0000 Subject: SL-16006 and SL-16009 Rigged mesh rendering optimization pass --- indra/llmath/llmatrix4a.h | 41 ++++++++++++++++++++++++++++++++++++++++- indra/llmath/llvector4a.h | 7 +++---- indra/llmath/llvector4a.inl | 4 ++-- indra/llmath/m4math.cpp | 9 +++++++-- indra/llmath/m4math.h | 2 ++ indra/llmath/v3math.cpp | 6 ++++++ indra/llmath/v3math.h | 5 ++++- 7 files changed, 64 insertions(+), 10 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 7ba347062f..5291a05607 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -36,6 +36,26 @@ class LLMatrix4a public: LL_ALIGN_16(LLVector4a mMatrix[4]); + LLMatrix4a() + { + + } + + explicit LLMatrix4a(const LLMatrix4& val) + { + loadu(val); + } + + inline F32* getF32ptr() + { + return (F32*) &mMatrix; + } + + inline const F32* getF32ptr() const + { + return (F32*)&mMatrix; + } + inline void clear() { mMatrix[0].clear(); @@ -44,6 +64,14 @@ public: mMatrix[3].clear(); } + inline void setIdentity() + { + mMatrix[0].set(1.f, 0.f, 0.f, 0.f); + mMatrix[1].set(0.f, 1.f, 0.f, 0.f); + mMatrix[2].set(0.f, 0.f, 1.f, 0.f); + mMatrix[3].set(0.f, 0.f, 0.f, 1.f); + } + inline void loadu(const LLMatrix4& src) { mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]); @@ -105,7 +133,7 @@ public: mMatrix[3].setAdd(a.mMatrix[3],d3); } - inline void rotate(const LLVector4a& v, LLVector4a& res) + inline void rotate(const LLVector4a& v, LLVector4a& res) const { LLVector4a y,z; @@ -151,6 +179,8 @@ public: { affineTransformSSE(v,res); } + + const LLVector4a& getTranslation() const { return mMatrix[3]; } }; inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat) @@ -176,6 +206,15 @@ inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) res.mMatrix[3] = row3; } +//Faster version of matMul wehere res must not be a or b +inline void matMulUnsafe(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) +{ + res.mMatrix[0] = rowMul(a.mMatrix[0], b); + res.mMatrix[1] = rowMul(a.mMatrix[1], b); + res.mMatrix[2] = rowMul(a.mMatrix[2], b); + res.mMatrix[3] = rowMul(a.mMatrix[3], b); +} + inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m) { s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]"; diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 27abf39537..5a02928374 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -46,10 +46,9 @@ class LLRotation; // of this writing, July 08, 2010) about getting it implemented before you resort to // LLVector3/LLVector4. ///////////////////////////////// -struct LLVector4a; LL_ALIGN_PREFIX(16) -struct LLVector4a +class LLVector4a { public: @@ -138,10 +137,10 @@ public: // BASIC GET/SET //////////////////////////////////// - // Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) + // Return a "this" as an F32 pointer. inline F32* getF32ptr(); - // Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) + // Return a "this" as a const F32 pointer. inline const F32* const getF32ptr() const; // Read-only access a single float in this vector. Do not use in proximity to any function call that manipulates diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 69d3d01efe..8be1c1b114 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -58,13 +58,13 @@ inline void LLVector4a::store4a(F32* dst) const // BASIC GET/SET //////////////////////////////////// -// Return a "this" as an F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) +// Return a "this" as an F32 pointer. F32* LLVector4a::getF32ptr() { return (F32*) &mQ; } -// Return a "this" as a const F32 pointer. Do not use unless you have a very good reason. (Not sure? Ask Falcon) +// Return a "this" as a const F32 pointer. const F32* const LLVector4a::getF32ptr() const { return (const F32* const) &mQ; diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 3baf1bad18..6e40dae30b 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -32,8 +32,7 @@ #include "m4math.h" #include "m3math.h" #include "llquaternion.h" - - +#include "llmatrix4a.h" // LLMatrix4 @@ -115,6 +114,12 @@ LLMatrix4::LLMatrix4(const LLQuaternion &q) *this = initRotation(q); } +LLMatrix4::LLMatrix4(const LLMatrix4a& mat) + : LLMatrix4(mat.getF32ptr()) +{ + +} + LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos) { *this = initRotTrans(q, pos); diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index bf60adb9b6..b9da970cde 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -32,6 +32,7 @@ class LLVector4; class LLMatrix3; class LLQuaternion; +class LLMatrix4a; // NOTA BENE: Currently assuming a right-handed, x-forward, y-left, z-up universe @@ -104,6 +105,7 @@ public: explicit LLMatrix4(const F32 *mat); // Initializes Matrix to values in mat explicit LLMatrix4(const LLMatrix3 &mat); // Initializes Matrix to values in mat and sets position to (0,0,0) explicit LLMatrix4(const LLQuaternion &q); // Initializes Matrix with rotation q and sets position to (0,0,0) + explicit LLMatrix4(const LLMatrix4a& mat); LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos); // Initializes Matrix to values in mat and pos diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index b04c67d926..93010d2250 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -316,6 +316,12 @@ LLVector3::LLVector3(const LLVector4 &vec) mV[VZ] = (F32)vec.mV[VZ]; } +LLVector3::LLVector3(const LLVector4a& vec) + : LLVector3(vec.getF32ptr()) +{ + +} + LLVector3::LLVector3(const LLSD& sd) { setValue(sd); diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 6f857d7061..068f489020 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -33,6 +33,7 @@ #include "llsd.h" class LLVector2; class LLVector4; +class LLVector4a; class LLMatrix3; class LLMatrix4; class LLVector3d; @@ -62,7 +63,9 @@ class LLVector3 explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0) explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2]) explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) - explicit LLVector3(const LLSD& sd); + explicit LLVector3(const LLVector4a& vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2]) + explicit LLVector3(const LLSD& sd); + LLSD getValue() const; -- cgit v1.2.3 From 8e4907beeea1ca0474dd124c7f6b4bf5dba45c3e Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Mon, 20 Sep 2021 09:47:26 -0700 Subject: SL-16014: Add Tracy markup for LLVolumeFace --- indra/llmath/llvolume.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e085fa6ada..130f30bedc 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -383,6 +383,7 @@ public: virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data + LL_PROFILE_ZONE_SCOPED LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -822,6 +823,8 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -1302,6 +1305,8 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { + LL_PROFILE_ZONE_SCOPED + // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; @@ -1536,6 +1541,8 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { + LL_PROFILE_ZONE_SCOPED + if ((!mDirty) && (!is_sculpted)) { return FALSE; @@ -2112,6 +2119,8 @@ LLVolume::~LLVolume() BOOL LLVolume::generate() { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY llassert_always(mProfilep); @@ -2370,6 +2379,8 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { + LL_PROFILE_ZONE_SCOPED + //input stream is now pointing at a zlib compressed block of LLSD //decompress block LLSD mdl; @@ -2755,6 +2766,8 @@ S32 LLVolume::getNumFaces() const void LLVolume::createVolumeFaces() { + LL_PROFILE_ZONE_SCOPED + if (mGenerateSingleFace) { // do nothing @@ -3720,6 +3733,8 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, const LLMatrix3& norm_mat_in, S32 face_mask) { + LL_PROFILE_ZONE_SCOPED + LLMatrix4a mat; mat.loadu(mat_in); @@ -4846,6 +4861,8 @@ void LLVolumeFace::freeData() BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + //tree for this face is no longer valid delete mOctree; mOctree = NULL; @@ -5514,6 +5531,8 @@ bool LLVolumeFace::cacheOptimize() void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { + LL_PROFILE_ZONE_SCOPED + if (mOctree) { return; @@ -6287,6 +6306,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe void LLVolumeFace::createTangents() { + LL_PROFILE_ZONE_SCOPED + if (!mTangents) { allocateTangents(mNumVertices); @@ -6482,6 +6503,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { + LL_PROFILE_ZONE_SCOPED + LL_CHECK_MEMORY BOOL flat = mTypeMask & FLAT_MASK; @@ -6974,6 +6997,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { + LL_PROFILE_ZONE_SCOPED + //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); // new(tan1) LLVector4a; -- cgit v1.2.3 From bfcb1f61a82508160fcb078b03c3e4772bc156df Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 28 Oct 2021 01:27:18 +0300 Subject: SL-16263 RaiseException in LLVolumeFace::createSide --- indra/llmath/llvolume.cpp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e085fa6ada..a1540840a5 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5723,7 +5723,16 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) resizeIndices(grid_size*grid_size*6); if (!volume->isMeshAssetLoaded()) { - mEdge.resize(grid_size*grid_size * 6); + S32 size = grid_size * grid_size * 6; + try + { + mEdge.resize(size); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL; + return false; + } } U16* out = mIndices; @@ -6514,7 +6523,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!volume->isMeshAssetLoaded()) { - mEdge.resize(num_indices); + try + { + mEdge.resize(num_indices); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL; + return false; + } } } @@ -6742,7 +6759,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector4a* norm = mNormals; static LLAlignedArray triangle_normals; - triangle_normals.resize(count); + try + { + triangle_normals.resize(count); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL; + return false; + } LLVector4a* output = triangle_normals.mArray; LLVector4a* end_output = output+count; -- cgit v1.2.3 From 8d20480c5f77fe1fab8149d3cda79bdd61e77656 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 28 Oct 2021 18:06:21 +0000 Subject: SL-16148 SL-16244 SL-16270 SL-16253 Remove most BlockTimers, remove LLMemTracked, introduce alignas, hook most/all reamining allocs, disable synchronous occlusion, and convert frequently accessed LLSingletons to LLSimpleton --- indra/llmath/lloctree.h | 13 ++----------- indra/llmath/llrigginginfo.h | 29 ++++------------------------- indra/llmath/llvector4a.h | 6 +++--- indra/llmath/llvolumeoctree.h | 27 ++++----------------------- 4 files changed, 13 insertions(+), 62 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 0e2f62f9db..8c4a1304b4 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -74,8 +74,9 @@ public: }; template -class LLOctreeNode : public LLTreeNode +class alignas(16) LLOctreeNode : public LLTreeNode { + LL_ALIGN_NEW public: typedef LLOctreeTraveler oct_traveler; @@ -91,16 +92,6 @@ public: typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - LLOctreeNode( const LLVector4a& center, const LLVector4a& size, BaseType* parent, diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h index b3d6bc2d19..059c6ae082 100644 --- a/indra/llmath/llrigginginfo.h +++ b/indra/llmath/llrigginginfo.h @@ -34,9 +34,9 @@ // Extents are in joint space // isRiggedTo is based on the state of all currently associated rigged meshes -LL_ALIGN_PREFIX(16) -class LLJointRiggingInfo +class alignas(16) LLJointRiggingInfo { + LL_ALIGN_NEW public: LLJointRiggingInfo(); bool isRiggedTo() const; @@ -45,31 +45,10 @@ public: const LLVector4a *getRiggedExtents() const; void merge(const LLJointRiggingInfo& other); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - - void* operator new[](size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete[](void* ptr) - { - ll_aligned_free_16(ptr); - } - - private: - LL_ALIGN_16(LLVector4a mRiggedExtents[2]); + LLVector4a mRiggedExtents[2]; bool mIsRiggedTo; -} LL_ALIGN_POSTFIX(16); +}; // For storing all the rigging info associated with a given avatar or // object, keyed by joint_num. diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 5a02928374..53c8f604f6 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -47,9 +47,9 @@ class LLRotation; // LLVector3/LLVector4. ///////////////////////////////// -LL_ALIGN_PREFIX(16) -class LLVector4a +class alignas(16) LLVector4a { + LL_ALIGN_NEW public: /////////////////////////////////// @@ -323,7 +323,7 @@ public: private: LLQuad mQ; -} LL_ALIGN_POSTFIX(16); +}; inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p) { diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 13150028d8..b2bc440368 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -34,19 +34,10 @@ #include "llvolume.h" #include "llvector4a.h" -class LLVolumeTriangle : public LLRefCount +class alignas(16) LLVolumeTriangle : public LLRefCount { + LL_ALIGN_NEW public: - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - LLVolumeTriangle() { mBinIndex = -1; @@ -86,20 +77,10 @@ public: }; -class LLVolumeOctreeListener : public LLOctreeListener +class alignas(16) LLVolumeOctreeListener : public LLOctreeListener { + LL_ALIGN_NEW public: - - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); -- cgit v1.2.3 From 28f9fb06a9f4cb9edccb2ff8132c7f6a9b27c060 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 20 Nov 2021 18:49:19 +0000 Subject: SL-16289 Rigged mesh rendering overhaul --- indra/llmath/llmatrix4a.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 5291a05607..2cf50e9cd2 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -78,8 +78,15 @@ public: mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]); mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]); mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]); - } + + inline void loadu(const F32* src) + { + mMatrix[0] = _mm_loadu_ps(src); + mMatrix[1] = _mm_loadu_ps(src+4); + mMatrix[2] = _mm_loadu_ps(src+8); + mMatrix[3] = _mm_loadu_ps(src+12); + } inline void loadu(const LLMatrix3& src) { -- cgit v1.2.3 From a71f772cc399cc516e8d4d4652ee91009b4ff95a Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 13 Jan 2022 13:03:37 -0800 Subject: SL-16606: Add profiler category VOLUME --- indra/llmath/llvolume.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c226315e5c..e9ccde5fae 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -383,7 +383,7 @@ public: virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -823,7 +823,7 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME if ((!mDirty) && (!is_sculpted)) { @@ -1305,7 +1305,7 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME // Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; @@ -1541,7 +1541,7 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail) BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, BOOL is_sculpted, S32 sculpt_size) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME if ((!mDirty) && (!is_sculpted)) { @@ -2119,7 +2119,7 @@ LLVolume::~LLVolume() BOOL LLVolume::generate() { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME LL_CHECK_MEMORY llassert_always(mProfilep); @@ -2379,7 +2379,7 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME //input stream is now pointing at a zlib compressed block of LLSD //decompress block @@ -2766,7 +2766,7 @@ S32 LLVolume::getNumFaces() const void LLVolume::createVolumeFaces() { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME if (mGenerateSingleFace) { @@ -3733,7 +3733,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, const LLMatrix3& norm_mat_in, S32 face_mask) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME LLMatrix4a mat; mat.loadu(mat_in); @@ -4861,7 +4861,7 @@ void LLVolumeFace::freeData() BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME //tree for this face is no longer valid delete mOctree; @@ -5531,7 +5531,7 @@ bool LLVolumeFace::cacheOptimize() void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME if (mOctree) { @@ -6306,7 +6306,7 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe void LLVolumeFace::createTangents() { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME if (!mTangents) { @@ -6503,7 +6503,7 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME LL_CHECK_MEMORY BOOL flat = mTypeMask & FLAT_MASK; @@ -6997,7 +6997,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME //LLVector4a *tan1 = new LLVector4a[vertexCount * 2]; LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); -- cgit v1.2.3 From 1566c01ad16a973f22990653b3dab8e5bd476db8 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 13 Jan 2022 21:09:52 -0800 Subject: SL-16607: Cleanup magic number for no child nodes --- indra/llmath/lloctree.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 8c4a1304b4..80eca781a9 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -92,10 +92,15 @@ public: typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; + enum + { + NO_CHILD_NODES = 255 // Note: This is an U8 to match the max value in mChildMap[] + }; + LLOctreeNode( const LLVector4a& center, const LLVector4a& size, BaseType* parent, - U8 octant = 255) + U8 octant = NO_CHILD_NODES) : mParent((oct_node*)parent), mOctant(octant) { @@ -108,7 +113,7 @@ public: mSize = size; updateMinMax(); - if ((mOctant == 255) && mParent) + if ((mOctant == NO_CHILD_NODES) && mParent) { mOctant = ((oct_node*) mParent)->getOctant(mCenter); } @@ -253,7 +258,7 @@ public: for (U32 i = 0; i < 8; i++) { U8 idx = mChildMap[i]; - if (idx != 255) + if (idx != NO_CHILD_NODES) { LLOctreeNode* child = mChild[idx]; @@ -286,7 +291,7 @@ public: // the data U8 next_node = node->mChildMap[octant]; - while (next_node != 255 && node->getSize()[0] >= rad) + while (next_node != NO_CHILD_NODES && node->getSize()[0] >= rad) { node = node->getChild(next_node); octant = node->getOctant(pos); @@ -514,9 +519,7 @@ public: void clearChildren() { mChildCount = 0; - - U32* foo = (U32*) mChildMap; - foo[0] = foo[1] = 0xFFFFFFFF; + memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); } void validate() @@ -607,11 +610,9 @@ public: --mChildCount; mChild[index] = mChild[mChildCount]; - //rebuild child map - U32* foo = (U32*) mChildMap; - foo[0] = foo[1] = 0xFFFFFFFF; + memset(mChildMap, NO_CHILD_NODES, sizeof(mChildMap)); for (U32 i = 0; i < mChildCount; ++i) { -- cgit v1.2.3 From 9b5f6c636b16e033059bb47d63a7919aeebb69ac Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 13 Jan 2022 21:10:53 -0800 Subject: SL-16607: Add Tracy capture colors for insert, remove, and balance --- indra/llmath/lloctree.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 80eca781a9..7032c9651b 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -34,6 +34,9 @@ #define OCT_ERRS LL_WARNS("OctreeErrors") +#define OCTREE_DEBUG_COLOR_REMOVE 0x0000FF // r +#define OCTREE_DEBUG_COLOR_INSERT 0x00FF00 // g +#define OCTREE_DEBUG_COLOR_BALANCE 0xFF0000 // b extern U32 gOctreeMaxCapacity; extern float gOctreeMinSize; @@ -308,6 +311,8 @@ public: virtual bool insert(T* data) { + //LL_PROFILE_ZONE_NAMED_COLOR("Octree::insert()",OCTREE_DEBUG_COLOR_INSERT); + if (data == NULL || data->getBinIndex() != -1) { OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL; @@ -454,6 +459,8 @@ public: bool remove(T* data) { + //LL_PROFILE_ZONE_NAMED_COLOR("Octree::remove()", OCTREE_DEBUG_COLOR_REMOVE); + S32 i = data->getBinIndex(); if (i >= 0 && i < mElementCount) @@ -692,6 +699,8 @@ public: bool balance() { + //LL_PROFILE_ZONE_NAMED_COLOR("Octree::balance()",OCTREE_DEBUG_COLOR_BALANCE); + if (this->getChildCount() == 1 && !(this->mChild[0]->isLeaf()) && this->mChild[0]->getElementCount() == 0) -- cgit v1.2.3 From 1dde66ca7924358ef6c19c7d9eb8883c434882bf Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Thu, 13 Jan 2022 21:11:24 -0800 Subject: SL-16607: Cleanup whitespace --- indra/llmath/lloctree.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 7032c9651b..2283df1e1a 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -126,9 +126,9 @@ public: clearChildren(); } - virtual ~LLOctreeNode() + virtual ~LLOctreeNode() { - BaseType::destroyListeners(); + BaseType::destroyListeners(); for (U32 i = 0; i < mElementCount; ++i) { @@ -167,7 +167,7 @@ public: return rad <= mSize[0]*2.f && isInside(pos); } - inline bool isInside(T* data) const + inline bool isInside(T* data) const { return isInside(data->getPositionGroup(), data->getBinRadius()); } @@ -284,7 +284,7 @@ public: LLOctreeNode* node = this; if (node->isInside(pos, rad)) - { + { //do a quick search by octant U8 octant = node->getOctant(pos); @@ -655,7 +655,7 @@ public: OCT_ERRS << "Octree failed to delete requested child." << LL_ENDL; } -protected: +protected: typedef enum { CENTER = 0, @@ -679,7 +679,6 @@ protected: element_list mData; element_iter mDataEnd; U32 mElementCount; - }; //just like a regular node, except it might expand on insert and compress on balance @@ -688,7 +687,7 @@ class LLOctreeRoot : public LLOctreeNode { public: typedef LLOctreeNode BaseType; - typedef LLOctreeNode oct_node; + typedef LLOctreeNode oct_node; LLOctreeRoot(const LLVector4a& center, const LLVector4a& size, @@ -703,7 +702,7 @@ public: if (this->getChildCount() == 1 && !(this->mChild[0]->isLeaf()) && - this->mChild[0]->getElementCount() == 0) + this->mChild[0]->getElementCount() == 0) { //if we have only one child and that child is an empty branch, make that child the root oct_node* child = this->mChild[0]; -- cgit v1.2.3 From f47730b92c309092d0a5a95e2d49d7ad53230a97 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 14 Feb 2022 18:07:24 +0000 Subject: SL-16418 Media texture update stall fix. Make media texture updates use LLImageGL thread to update, fix AMD sync issue on ImageGL thread and install debug callbacks on LLImageGL thread when debug gl enabled. --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e9ccde5fae..d91a973153 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -88,7 +88,7 @@ const F32 SKEW_MAX = 0.95f; const F32 SCULPT_MIN_AREA = 0.002f; const S32 SCULPT_MIN_AREA_DETAIL = 1; -BOOL gDebugGL = FALSE; +BOOL gDebugGL = FALSE; // See settings.xml "RenderDebugGL" BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { -- cgit v1.2.3 From 43517c5adc69ecb1d8a5e031a9e2840b005eecf9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 5 May 2022 19:41:56 +0300 Subject: SL-17244 Fix 'empty leaf' crashes --- indra/llmath/lloctree.h | 12 +++++++++--- indra/llmath/llvolume.cpp | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 2283df1e1a..a9a54a8113 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -73,7 +73,7 @@ template class LLOctreeTravelerDepthFirst : public LLOctreeTraveler { public: - virtual void traverse(const LLOctreeNode* node); + virtual void traverse(const LLOctreeNode* node) override; }; template @@ -696,7 +696,7 @@ public: { } - bool balance() + bool balance() override { //LL_PROFILE_ZONE_NAMED_COLOR("Octree::balance()",OCTREE_DEBUG_COLOR_BALANCE); @@ -732,7 +732,7 @@ public: } // LLOctreeRoot::insert - bool insert(T* data) + bool insert(T* data) override { if (data == NULL) { @@ -835,6 +835,12 @@ public: return false; } + + bool isLeaf() const override + { + // root can't be a leaf + return false; + } }; //======================== diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3727ce85af..5099920f32 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -414,7 +414,7 @@ public: max.setMax(max, *tri->mV[2]); } } - else if (!branch->isLeaf()) + else if (branch->getChildCount() > 0) { //no data, but child nodes exist LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0); @@ -424,7 +424,7 @@ public: } else { - LL_ERRS() << "Empty leaf" << LL_ENDL; + llassert(!branch->isLeaf()); // Empty leaf } for (S32 i = 0; i < branch->getChildCount(); ++i) -- cgit v1.2.3 From b08340f1831005ae227577899a64408cc939a12d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 10 Jun 2022 19:43:14 +0300 Subject: SL-17475 Remap models before simplification --- indra/llmath/CMakeLists.txt | 3 +++ indra/llmath/llvolume.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ indra/llmath/llvolume.h | 4 ++++ 3 files changed, 49 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 552e820127..4617309606 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -4,12 +4,14 @@ project(llmath) include(00-Common) include(LLCommon) +include(LLMeshOptimizer) include(bugsplat) include(Boost) include_directories( ${LLCOMMON_INCLUDE_DIRS} ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ${LLMESHOPTIMIZER_INCLUDE_DIRS} ) set(llmath_SOURCE_FILES @@ -109,6 +111,7 @@ add_library (llmath ${llmath_SOURCE_FILES}) target_link_libraries(llmath ${LLCOMMON_LIBRARIES} + ${LLMESHOPTIMIZER_LIBRARIES} ) # Add tests diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5099920f32..23f372f6e3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -49,6 +49,7 @@ #include "llsdserialize.h" #include "llvector4a.h" #include "llmatrix4a.h" +#include "llmeshoptimizer.h" #include "lltimer.h" #define DEBUG_SILHOUETTE_BINORMALS 0 @@ -4952,6 +4953,47 @@ bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a return a.mV[2] < b.mV[2]; } +void LLVolumeFace::remap() +{ + // generate a remap buffer + std::vector remap(mNumIndices); + S32 remap_vertices_count = LLMeshOptimizer::generateRemapMulti(&remap[0], + NULL, + mNumIndices, + mPositions, + mNormals, + mTexCoords, + mNumVertices); + + // Allocate new buffers + U16* remap_indices = (U16*)ll_aligned_malloc_16(mNumIndices * sizeof(U16)); + + S32 tc_bytes_size = ((remap_vertices_count * sizeof(LLVector2)) + 0xF) & ~0xF; + LLVector4a* remap_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * remap_vertices_count + tc_bytes_size); + LLVector4a* remap_normals = remap_positions + remap_vertices_count; + LLVector2* remap_tex_coords = (LLVector2*)(remap_normals + remap_vertices_count); + + // fill the buffers + LLMeshOptimizer::remapIndexBufferU16(remap_indices, mIndices, mNumIndices, &remap[0]); + LLMeshOptimizer::remapPositionsBuffer(remap_positions, mPositions, mNumVertices, &remap[0]); + LLMeshOptimizer::remapNormalsBuffer(remap_normals, mNormals, mNumVertices, &remap[0]); + LLMeshOptimizer::remapUVBuffer(remap_tex_coords, mTexCoords, mNumVertices, &remap[0]); + + // free unused buffers + ll_aligned_free_16(mIndices); + ll_aligned_free<64>(mPositions); + ll_aligned_free_16(mTangents); + + mTangents = NULL; + + mIndices = remap_indices; + mPositions = remap_positions; + mNormals = remap_normals; + mTexCoords = remap_tex_coords; + mNumVertices = remap_vertices_count; + mNumAllocatedVertices = remap_vertices_count; +} + void LLVolumeFace::optimize(F32 angle_cutoff) { LLVolumeFace new_face; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c0b224b1ff..9697952f5b 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -902,6 +902,10 @@ public: typedef std::map, VertexMapData::ComparePosition > PointMap; }; + // Eliminates non unique triangles, takes positions, + // normals and texture coordinates into account. + void remap(); + void optimize(F32 angle_cutoff = 2.f); bool cacheOptimize(); -- cgit v1.2.3 From 45bcefd981e268b158d11d59f2ba9063293986a6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 14 Jun 2022 16:39:46 +0300 Subject: SL-17475 fix remap causing an assert --- indra/llmath/llvolume.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 23f372f6e3..9efdcd4e8c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4957,8 +4957,8 @@ void LLVolumeFace::remap() { // generate a remap buffer std::vector remap(mNumIndices); - S32 remap_vertices_count = LLMeshOptimizer::generateRemapMulti(&remap[0], - NULL, + S32 remap_vertices_count = LLMeshOptimizer::generateRemapMultiU16(&remap[0], + mIndices, mNumIndices, mPositions, mNormals, -- cgit v1.2.3 From b1cbf369cf63f270cb810f640a14420be53035ed Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 14 Jun 2022 18:33:50 +0300 Subject: SL-17475 Use a shadow indices buffer before simplification --- indra/llmath/llvolume.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 9efdcd4e8c..04d3e9fc08 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4955,7 +4955,7 @@ bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a void LLVolumeFace::remap() { - // generate a remap buffer + // Generate a remap buffer std::vector remap(mNumIndices); S32 remap_vertices_count = LLMeshOptimizer::generateRemapMultiU16(&remap[0], mIndices, @@ -4966,26 +4966,29 @@ void LLVolumeFace::remap() mNumVertices); // Allocate new buffers - U16* remap_indices = (U16*)ll_aligned_malloc_16(mNumIndices * sizeof(U16)); + S32 size = ((mNumIndices * sizeof(U16)) + 0xF) & ~0xF; + U16* remap_indices = (U16*)ll_aligned_malloc_16(size); S32 tc_bytes_size = ((remap_vertices_count * sizeof(LLVector2)) + 0xF) & ~0xF; LLVector4a* remap_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * remap_vertices_count + tc_bytes_size); LLVector4a* remap_normals = remap_positions + remap_vertices_count; LLVector2* remap_tex_coords = (LLVector2*)(remap_normals + remap_vertices_count); - // fill the buffers + // Fill the buffers LLMeshOptimizer::remapIndexBufferU16(remap_indices, mIndices, mNumIndices, &remap[0]); LLMeshOptimizer::remapPositionsBuffer(remap_positions, mPositions, mNumVertices, &remap[0]); LLMeshOptimizer::remapNormalsBuffer(remap_normals, mNormals, mNumVertices, &remap[0]); LLMeshOptimizer::remapUVBuffer(remap_tex_coords, mTexCoords, mNumVertices, &remap[0]); - // free unused buffers + // Free unused buffers ll_aligned_free_16(mIndices); ll_aligned_free<64>(mPositions); - ll_aligned_free_16(mTangents); + // Tangets are now invalid + ll_aligned_free_16(mTangents); mTangents = NULL; + // Assign new values mIndices = remap_indices; mPositions = remap_positions; mNormals = remap_normals; -- cgit v1.2.3 From f451672b0c549092796a018997152cbeb57418b2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 16 Jun 2022 16:46:04 +0300 Subject: SL-17475 Fix wrong remap buffer size --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 04d3e9fc08..4a069b0f63 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4956,7 +4956,7 @@ bool LLVolumeFace::VertexMapData::ComparePosition::operator()(const LLVector3& a void LLVolumeFace::remap() { // Generate a remap buffer - std::vector remap(mNumIndices); + std::vector remap(mNumVertices); S32 remap_vertices_count = LLMeshOptimizer::generateRemapMultiU16(&remap[0], mIndices, mNumIndices, -- cgit v1.2.3 From 076a89506243e8d4037f34c2a78278ff6ee0f1f7 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 21 Jun 2022 17:55:29 +0300 Subject: SL-17635 remove unused variables --- indra/llmath/llvolume.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5099920f32..3de5e04177 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1624,9 +1624,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); genNGon(params, llfloor(MIN_DETAIL_FACES * detail)); - F32 t = 0.f; - F32 tStep = 1.0f / mPath.size(); - F32 toggle = 0.5f; for (S32 i=0;i<(S32)mPath.size();i++) { @@ -1635,7 +1632,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, toggle = -0.5f; else toggle = 0.5f; - t += tStep; } } -- cgit v1.2.3 From dbe0cb58653b3199f6abcf640d38e8fb99b2e073 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 11 Apr 2022 10:36:13 -0700 Subject: SL-17021: Clean up some unneeded member variables from lloctree No performance difference measured --- indra/llmath/lloctree.h | 64 ++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 41 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index a9a54a8113..7e73fb6b57 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -85,8 +85,8 @@ public: typedef LLOctreeTraveler oct_traveler; typedef LLTreeTraveler tree_traveler; typedef std::vector< LLPointer > element_list; // note: don't remove the whitespace between "> >" - typedef LLPointer* element_iter; - typedef const LLPointer* const_element_iter; + typedef typename element_list::iterator element_iter; + typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; typedef LLOctreeNode** child_list; typedef LLOctreeNode** child_iter; @@ -108,9 +108,6 @@ public: mOctant(octant) { llassert(size[0] >= gOctreeMinSize*0.5f); - //always keep a NULL terminated list to avoid out of bounds exceptions in debug builds - mData.push_back(NULL); - mDataEnd = &mData[0]; mCenter = center; mSize = size; @@ -121,8 +118,6 @@ public: mOctant = ((oct_node*) mParent)->getOctant(mCenter); } - mElementCount = 0; - clearChildren(); } @@ -130,15 +125,14 @@ public: { BaseType::destroyListeners(); - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { mData[i]->setBinIndex(-1); mData[i] = NULL; } mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; for (U32 i = 0; i < getChildCount(); i++) { @@ -238,14 +232,12 @@ public: void accept(oct_traveler* visitor) { visitor->visit(this); } virtual bool isLeaf() const { return mChildCount == 0; } - U32 getElementCount() const { return mElementCount; } - bool isEmpty() const { return mElementCount == 0; } - element_list& getData() { return mData; } - const element_list& getData() const { return mData; } - element_iter getDataBegin() { return &mData[0]; } - element_iter getDataEnd() { return mDataEnd; } - const_element_iter getDataBegin() const { return &mData[0]; } - const_element_iter getDataEnd() const { return mDataEnd; } + U32 getElementCount() const { return (U32)mData.size(); } + bool isEmpty() const { return mData.empty(); } + element_iter getDataBegin() { return mData.begin(); } + element_iter getDataEnd() { return mData.end(); } + const_element_iter getDataBegin() const { return mData.cbegin(); } + const_element_iter getDataEnd() const { return mData.cend(); } U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } @@ -326,11 +318,8 @@ public: if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -366,11 +355,8 @@ public: if( lt == 0x7 ) { - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -429,28 +415,25 @@ public: } void _remove(T* data, S32 i) - { //precondition -- mElementCount > 0, idx is in range [0, mElementCount) + { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount()) - mElementCount--; data->setBinIndex(-1); - if (mElementCount > 0) + const U32 new_element_count = getElementCount() - 1; + if (new_element_count > 0) { - if (mElementCount != i) + if (new_element_count != i) { - mData[i] = mData[mElementCount]; //might unref data, do not access data after this point + mData[i] = mData[new_element_count]; //might unref data, do not access data after this point mData[i]->setBinIndex(i); } - mData[mElementCount] = NULL; + mData[new_element_count] = NULL; mData.pop_back(); - mDataEnd = &mData[mElementCount]; } else { mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; } this->notifyRemoval(data); @@ -463,7 +446,7 @@ public: S32 i = data->getBinIndex(); - if (i >= 0 && i < mElementCount) + if (i >= 0 && i < getElementCount()) { if (mData[i] == data) { //found it @@ -506,7 +489,8 @@ public: void removeByAddress(T* data) { - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { if (mData[i] == data) { //we have data @@ -677,8 +661,6 @@ protected: U32 mChildCount; element_list mData; - element_iter mDataEnd; - U32 mElementCount; }; //just like a regular node, except it might expand on insert and compress on balance -- cgit v1.2.3 From 162280cd981b97ffef927553ec230cddcda878ce Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 12 Apr 2022 14:05:51 -0700 Subject: SL-17021: Templatize LLOctreeNode and related classes to allow for option to store elements in octrees as raw pointers. Use for faster allocation in LLVolumeFace::createOctree. --- indra/llmath/lloctree.h | 89 ++++++++++++++++++++++------------------- indra/llmath/llvolume.cpp | 21 +++++++--- indra/llmath/llvolume.h | 7 +++- indra/llmath/llvolumeoctree.cpp | 18 ++++----- indra/llmath/llvolumeoctree.h | 20 +++++---- 5 files changed, 85 insertions(+), 70 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 7e73fb6b57..318ee65cc0 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -48,52 +48,59 @@ extern float gOctreeMinSize; #define LL_OCTREE_MAX_CAPACITY 128 #endif*/ -template class LLOctreeNode; - -template +// T is the type of the element referenced by the octree node. +// T_PTR determines how pointers to elements are stored internally. +// LLOctreeNode> assumes ownership of inserted elements and +// deletes elements removed from the tree. +// LLOctreeNode doesn't take ownership of inserted elements, so the API +// user is responsible for managing the storage lifecycle of elements added to +// the tree. +template class LLOctreeNode; + +template class LLOctreeListener: public LLTreeListener { public: typedef LLTreeListener BaseType; - typedef LLOctreeNode oct_node; + typedef LLOctreeNode oct_node; virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0; virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0; }; -template +template class LLOctreeTraveler { public: - virtual void traverse(const LLOctreeNode* node); - virtual void visit(const LLOctreeNode* branch) = 0; + virtual void traverse(const LLOctreeNode* node); + virtual void visit(const LLOctreeNode* branch) = 0; }; -template -class LLOctreeTravelerDepthFirst : public LLOctreeTraveler +template +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler { public: - virtual void traverse(const LLOctreeNode* node) override; + virtual void traverse(const LLOctreeNode* node) override; }; -template +template class alignas(16) LLOctreeNode : public LLTreeNode { LL_ALIGN_NEW public: - typedef LLOctreeTraveler oct_traveler; - typedef LLTreeTraveler tree_traveler; - typedef std::vector< LLPointer > element_list; // note: don't remove the whitespace between "> >" + typedef LLOctreeTraveler oct_traveler; + typedef LLTreeTraveler tree_traveler; + typedef std::vector element_list; typedef typename element_list::iterator element_iter; typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; - typedef LLOctreeNode** child_list; - typedef LLOctreeNode** child_iter; + typedef LLOctreeNode** child_list; + typedef LLOctreeNode** child_iter; - typedef LLTreeNode BaseType; - typedef LLOctreeNode oct_node; - typedef LLOctreeListener oct_listener; + typedef LLTreeNode BaseType; + typedef LLOctreeNode oct_node; + typedef LLOctreeListener oct_listener; enum { @@ -255,7 +262,7 @@ public: U8 idx = mChildMap[i]; if (idx != NO_CHILD_NODES) { - LLOctreeNode* child = mChild[idx]; + oct_node* child = mChild[idx]; if (child->getOctant() != i) { @@ -273,7 +280,7 @@ public: oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) { - LLOctreeNode* node = this; + oct_node* node = this; if (node->isInside(pos, rad)) { @@ -295,7 +302,7 @@ public: } else if (!node->contains(rad) && node->getParent()) { //if we got here, data does not exist in this node - return ((LLOctreeNode*) node->getParent())->getNodeAt(pos, rad); + return ((oct_node*) node->getParent())->getNodeAt(pos, rad); } return node; @@ -310,7 +317,7 @@ public: OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL; return false; } - LLOctreeNode* parent = getOctParent(); + oct_node* parent = getOctParent(); //is it here? if (isInside(data->getPositionGroup())) @@ -343,7 +350,7 @@ public: size.mul(0.5f); //push center in direction of data - LLOctreeNode::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); // handle case where floating point number gets too small LLVector4a val; @@ -382,7 +389,7 @@ public: llassert(size[0] >= gOctreeMinSize*0.5f); //make the new kid - child = new LLOctreeNode(center, size, this); + child = new oct_node(center, size, this); addChild(child); child->insert(data); @@ -502,7 +509,7 @@ public: for (U32 i = 0; i < getChildCount(); i++) { //we don't contain data, so pass this guy down - LLOctreeNode* child = (LLOctreeNode*) getChild(i); + oct_node* child = (oct_node*) getChild(i); child->removeByAddress(data); } } @@ -656,7 +663,7 @@ protected: oct_node* mParent; U8 mOctant; - LLOctreeNode* mChild[8]; + oct_node* mChild[8]; U8 mChildMap[8]; U32 mChildCount; @@ -664,12 +671,12 @@ protected: }; //just like a regular node, except it might expand on insert and compress on balance -template -class LLOctreeRoot : public LLOctreeNode +template +class LLOctreeRoot : public LLOctreeNode { public: - typedef LLOctreeNode BaseType; - typedef LLOctreeNode oct_node; + typedef LLOctreeNode BaseType; + typedef LLOctreeNode oct_node; LLOctreeRoot(const LLVector4a& center, const LLVector4a& size, @@ -750,7 +757,7 @@ public: oct_node* node = this->getNodeAt(data); if (node == this) { - LLOctreeNode::insert(data); + oct_node::insert(data); } else if (node->isInside(data->getPositionGroup())) { @@ -770,13 +777,13 @@ public: LLVector4a center, size; center = this->getCenter(); size = this->getSize(); - LLOctreeNode::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); this->setCenter(center); size.mul(2.f); this->setSize(size); this->updateMinMax(); } - LLOctreeNode::insert(data); + oct_node::insert(data); } else { @@ -788,7 +795,7 @@ public: //expand this node LLVector4a newcenter(center); - LLOctreeNode::pushCenter(newcenter, size, data); + oct_node::pushCenter(newcenter, size, data); this->setCenter(newcenter); LLVector4a size2 = size; size2.mul(2.f); @@ -798,11 +805,11 @@ public: llassert(size[0] >= gOctreeMinSize); //copy our children to a new branch - LLOctreeNode* newnode = new LLOctreeNode(center, size, this); + oct_node* newnode = new oct_node(center, size, this); for (U32 i = 0; i < this->getChildCount(); i++) { - LLOctreeNode* child = this->getChild(i); + oct_node* child = this->getChild(i); newnode->addChild(child); } @@ -828,8 +835,8 @@ public: //======================== // LLOctreeTraveler //======================== -template -void LLOctreeTraveler::traverse(const LLOctreeNode* node) +template +void LLOctreeTraveler::traverse(const LLOctreeNode* node) { node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) @@ -838,8 +845,8 @@ void LLOctreeTraveler::traverse(const LLOctreeNode* node) } } -template -void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) +template +void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) { for (U32 i = 0; i < node->getChildCount(); i++) { diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3de5e04177..414e96f67a 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -370,7 +370,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } -class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: const LLVolumeFace* mFace; @@ -380,7 +380,7 @@ public: mFace = face; } - virtual void visit(const LLOctreeNode* branch) + virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME @@ -398,8 +398,7 @@ public: min = *(tri->mV[0]); max = *(tri->mV[0]); - for (LLOctreeNode::const_element_iter iter = - branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) + for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { //for each triangle in node //stretch by triangles in node @@ -4874,6 +4873,8 @@ void LLVolumeFace::freeData() delete mOctree; mOctree = NULL; + mOctreeTriangles.clear(); + mOctreeTriangles.shrink_to_fit(); } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -4883,6 +4884,8 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) //tree for this face is no longer valid delete mOctree; mOctree = NULL; + mOctreeTriangles.clear(); + mOctreeTriangles.shrink_to_fit(); LL_CHECK_MEMORY BOOL ret = FALSE ; @@ -5556,12 +5559,18 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe return; } - mOctree = new LLOctreeRoot(center, size, NULL); + mOctree = new LLOctreeRoot(center, size, NULL); new LLVolumeOctreeListener(mOctree); + // Clear old triangles, but keep the underlying storage pointer + mOctreeTriangles.clear(); + const U32 num_triangles = mNumIndices / 3; + // Initialize all the triangles we need + mOctreeTriangles.resize(num_triangles); for (U32 i = 0; i < mNumIndices; i+= 3) { //for each triangle - LLPointer tri = new LLVolumeTriangle(); + const U32 triangle_index = i / 3; + LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; const LLVector4a& v0 = mPositions[mIndices[i]]; const LLVector4a& v1 = mPositions[mIndices[i+1]]; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c0b224b1ff..da155c7b41 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -35,7 +35,8 @@ class LLVolumeParams; class LLProfile; class LLPath; -template class LLOctreeNode; +template class LLPointer; +template class LLOctreeNode; class LLVolumeFace; class LLVolume; @@ -974,7 +975,9 @@ public: // vertices per joint. LLJointRiggingInfoTab mJointRiggingInfoTab; - LLOctreeNode* mOctree; + // This octree stores raw pointer references to triangles in mOctreeTriangles + LLOctreeNode* mOctree; + std::vector mOctreeTriangles; //whether or not face has been cache optimized BOOL mOptimized; diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index fb232d5f6c..6894d04d3c 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -75,7 +75,7 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c } -LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode* node) +LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode* node) { node->addListener(this); } @@ -85,13 +85,12 @@ LLVolumeOctreeListener::~LLVolumeOctreeListener() } -void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child) +void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, + LLOctreeNode* child) { new LLVolumeOctreeListener(child); } - LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) @@ -108,7 +107,7 @@ LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& sta mEnd.setAdd(mStart, mDir); } -void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode* node) +void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode* node) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); @@ -122,9 +121,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode } } -void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) +void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) { - for (LLOctreeNode::const_element_iter iter = + for (typename LLOctreeNode::const_element_iter iter = node->getDataBegin(); iter != node->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -219,7 +218,7 @@ const F32& LLVolumeTriangle::getBinRadius() const //TEST CODE -void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) +void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -256,7 +255,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) } //children fit, check data - for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); + for (typename LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -273,4 +272,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) } } - diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index b2bc440368..d65bca5e52 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -77,11 +77,11 @@ public: }; -class alignas(16) LLVolumeOctreeListener : public LLOctreeListener +class alignas(16) LLVolumeOctreeListener : public LLOctreeListener { LL_ALIGN_NEW public: - LLVolumeOctreeListener(LLOctreeNode* node); + LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) @@ -96,11 +96,9 @@ public: } //LISTENER FUNCTIONS - virtual void handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child); + virtual void handleChildAddition(const LLOctreeNode* parent, LLOctreeNode* child); virtual void handleStateChange(const LLTreeNode* node) { } - virtual void handleChildRemoval(const LLOctreeNode* parent, - const LLOctreeNode* child) { } + virtual void handleChildRemoval(const LLOctreeNode* parent, const LLOctreeNode* child) { } virtual void handleInsertion(const LLTreeNode* node, LLVolumeTriangle* tri) { } virtual void handleRemoval(const LLTreeNode* node, LLVolumeTriangle* tri) { } virtual void handleDestruction(const LLTreeNode* node) { } @@ -111,7 +109,7 @@ public: LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; -class LLOctreeTriangleRayIntersect : public LLOctreeTraveler +class LLOctreeTriangleRayIntersect : public LLOctreeTraveler { public: const LLVolumeFace* mFace; @@ -129,14 +127,14 @@ public: const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); - void traverse(const LLOctreeNode* node); + void traverse(const LLOctreeNode* node); - virtual void visit(const LLOctreeNode* node); + virtual void visit(const LLOctreeNode* node); }; -class LLVolumeOctreeValidate : public LLOctreeTraveler +class LLVolumeOctreeValidate : public LLOctreeTraveler { - virtual void visit(const LLOctreeNode* branch); + virtual void visit(const LLOctreeNode* branch); }; #endif -- cgit v1.2.3 From c01388fb0b639172f0c0f29f80dd01646fc1b89c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 6 Jul 2022 21:10:22 +0300 Subject: SL-16793 Crash at LLProfile::addHole addHole can be accessed from main tread and from mesh thread, safeguard pt --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5099920f32..47c4977afd 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -683,7 +683,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3 Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); - static LLAlignedArray pt; + static thread_local LLAlignedArray pt; pt.resize(mTotal) ; for (S32 i=mTotalOut;i Date: Thu, 7 Jul 2022 00:01:33 +0300 Subject: SL-16793 Potential crash at createSide --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 47c4977afd..2b23325bff 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6821,7 +6821,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector4a* norm = mNormals; - static LLAlignedArray triangle_normals; + static thread_local LLAlignedArray triangle_normals; try { triangle_normals.resize(count); -- cgit v1.2.3 From 4ef83bb8bd48aef3cd01b2c0f42ae61043388e3c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 21 Jul 2022 10:32:56 -0700 Subject: SL-17801: Add various safeguards to keep triangle indices count valid --- indra/llmath/llvolume.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 414e96f67a..55778fce3a 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2421,6 +2421,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) //copy out indices S32 num_indices = idx.size() / 2; + const S32 indices_to_discard = num_indices % 3; + if (indices_to_discard > 0) + { + // Invalid number of triangle indices + LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL; + num_indices -= indices_to_discard; + } face.resizeIndices(num_indices); if (num_indices > 2 && !face.mIndices) @@ -2436,8 +2443,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } U16* indices = (U16*) &(idx[0]); - U32 count = idx.size()/2; - for (U32 j = 0; j < count; ++j) + for (U32 j = 0; j < num_indices; ++j) { face.mIndices[j] = indices[j]; } @@ -3829,8 +3835,8 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, #if DEBUG_SILHOUETTE_EDGE_MAP //for each triangle - U32 count = face.mNumIndices; - for (U32 j = 0; j < count/3; j++) { + U32 tri_count = face.mNumIndices / 3; + for (U32 j = 0; j < tri_count; j++) { //get vertices S32 v1 = face.mIndices[j*3+0]; S32 v2 = face.mIndices[j*3+1]; @@ -3848,7 +3854,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, continue; } - if (nIndex >= (S32) count/3) { + if (nIndex >= (S32)tri_count) { continue; } //get neighbor vertices @@ -5559,6 +5565,8 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe return; } + llassert(mNumIndices % 3 == 0); + mOctree = new LLOctreeRoot(center, size, NULL); new LLVolumeOctreeListener(mOctree); // Clear old triangles, but keep the underlying storage pointer @@ -5567,14 +5575,14 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe // Initialize all the triangles we need mOctreeTriangles.resize(num_triangles); - for (U32 i = 0; i < mNumIndices; i+= 3) + for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index) { //for each triangle - const U32 triangle_index = i / 3; + const U32 index = triangle_index * 3; LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; - const LLVector4a& v0 = mPositions[mIndices[i]]; - const LLVector4a& v1 = mPositions[mIndices[i+1]]; - const LLVector4a& v2 = mPositions[mIndices[i+2]]; + const LLVector4a& v0 = mPositions[mIndices[index]]; + const LLVector4a& v1 = mPositions[mIndices[index + 1]]; + const LLVector4a& v2 = mPositions[mIndices[index + 2]]; //store pointers to vertex data tri->mV[0] = &v0; @@ -5582,9 +5590,9 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe tri->mV[2] = &v2; //store indices - tri->mIndex[0] = mIndices[i]; - tri->mIndex[1] = mIndices[i+1]; - tri->mIndex[2] = mIndices[i+2]; + tri->mIndex[0] = mIndices[index]; + tri->mIndex[1] = mIndices[index + 1]; + tri->mIndex[2] = mIndices[index + 2]; //get minimum point LLVector4a min = v0; @@ -6498,6 +6506,7 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts) void LLVolumeFace::resizeIndices(S32 num_indices) { ll_aligned_free_16(mIndices); + llassert(num_indices % 3 == 0); if (num_indices) { -- cgit v1.2.3 From f1128da8da714b9d036fe1dbc66cf46ccf7747a5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 22 Jul 2022 13:45:00 -0700 Subject: SL-17801: Use raw array for mOctreeTriangles to avoid memory alignment issues, increasing risk of crashes during picking due to SIMD operations --- indra/llmath/llvolume.cpp | 19 ++++++++++--------- indra/llmath/llvolume.h | 3 ++- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 55778fce3a..67c351ddd7 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4707,6 +4707,7 @@ LLVolumeFace::LLVolumeFace() : #endif mWeightsScrubbed(FALSE), mOctree(NULL), + mOctreeTriangles(NULL), mOptimized(FALSE) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4736,8 +4737,9 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mJointIndices(NULL), #endif mWeightsScrubbed(FALSE), - mOctree(NULL) -{ + mOctree(NULL), + mOctreeTriangles(NULL) +{ mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); mCenter = mExtents+2; *this = src; @@ -4879,8 +4881,8 @@ void LLVolumeFace::freeData() delete mOctree; mOctree = NULL; - mOctreeTriangles.clear(); - mOctreeTriangles.shrink_to_fit(); + delete[] mOctreeTriangles; + mOctreeTriangles = NULL; } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -4890,8 +4892,8 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) //tree for this face is no longer valid delete mOctree; mOctree = NULL; - mOctreeTriangles.clear(); - mOctreeTriangles.shrink_to_fit(); + delete[] mOctreeTriangles; + mOctreeTriangles = NULL; LL_CHECK_MEMORY BOOL ret = FALSE ; @@ -5569,11 +5571,10 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe mOctree = new LLOctreeRoot(center, size, NULL); new LLVolumeOctreeListener(mOctree); - // Clear old triangles, but keep the underlying storage pointer - mOctreeTriangles.clear(); const U32 num_triangles = mNumIndices / 3; // Initialize all the triangles we need - mOctreeTriangles.resize(num_triangles); + delete[] mOctreeTriangles; // External code may delete mOctree + mOctreeTriangles = new LLVolumeTriangle[num_triangles]; for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index) { //for each triangle diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index da155c7b41..ffb02b934d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -977,12 +977,13 @@ public: // This octree stores raw pointer references to triangles in mOctreeTriangles LLOctreeNode* mOctree; - std::vector mOctreeTriangles; //whether or not face has been cache optimized BOOL mOptimized; private: + LLVolumeTriangle* mOctreeTriangles; + BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE); -- cgit v1.2.3 From cdff7169083f054818bd54f43d602dc229a067c4 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 26 Jul 2022 10:36:58 -0700 Subject: SL-17801: Don't let external code delete the raw pointer to the picking octree --- indra/llmath/llvolume.cpp | 30 ++++++++++++++++++------------ indra/llmath/llvolume.h | 7 ++++--- 2 files changed, 22 insertions(+), 15 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 67c351ddd7..5de1fe5a8d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4146,13 +4146,13 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en } else { - if (!face.mOctree) + if (!face.getOctree()) { face.createOctree(); } LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); - intersect.traverse(face.mOctree); + intersect.traverse(face.getOctree()); if (intersect.mHitFace) { hit_face = i; @@ -4879,10 +4879,7 @@ void LLVolumeFace::freeData() mJustWeights = NULL; #endif - delete mOctree; - mOctree = NULL; - delete[] mOctreeTriangles; - mOctreeTriangles = NULL; + destroyOctree(); } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -4890,10 +4887,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME //tree for this face is no longer valid - delete mOctree; - mOctree = NULL; - delete[] mOctreeTriangles; - mOctreeTriangles = NULL; + destroyOctree(); LL_CHECK_MEMORY BOOL ret = FALSE ; @@ -5562,7 +5556,7 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - if (mOctree) + if (getOctree()) { return; } @@ -5573,7 +5567,6 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe new LLVolumeOctreeListener(mOctree); const U32 num_triangles = mNumIndices / 3; // Initialize all the triangles we need - delete[] mOctreeTriangles; // External code may delete mOctree mOctreeTriangles = new LLVolumeTriangle[num_triangles]; for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index) @@ -5636,6 +5629,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe } } +void LLVolumeFace::destroyOctree() +{ + delete mOctree; + mOctree = NULL; + delete[] mOctreeTriangles; + mOctreeTriangles = NULL; +} + +const LLOctreeNode* LLVolumeFace::getOctree() const +{ + return mOctree; +} + void LLVolumeFace::swapData(LLVolumeFace& rhs) { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ffb02b934d..a984aa127e 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -907,6 +907,9 @@ public: bool cacheOptimize(); void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); + void destroyOctree(); + // Get a reference to the octree, which may be null + const LLOctreeNode* getOctree() const; enum { @@ -974,14 +977,12 @@ public: // Which joints are rigged to, and the bounding box of any rigged // vertices per joint. LLJointRiggingInfoTab mJointRiggingInfoTab; - - // This octree stores raw pointer references to triangles in mOctreeTriangles - LLOctreeNode* mOctree; //whether or not face has been cache optimized BOOL mOptimized; private: + LLOctreeNode* mOctree; LLVolumeTriangle* mOctreeTriangles; BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); -- cgit v1.2.3 From 09400b74ad79c468ca207005a6ca6621fa845f5d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 4 Aug 2022 22:14:08 +0300 Subject: SL-17902 Crash at LLAlignedArray, out of bounds --- indra/llmath/llvolume.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index c27b144f19..93f1d508f3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6674,13 +6674,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) else { // Get s value for tex-coord. - if (!flat) + S32 index = mBeginS + s; + if (index >= profile.size()) + { + // edge? + ss = flat ? 1.f - begin_stex : 1.f; + } + else if (!flat) { - ss = profile[mBeginS + s][2]; + ss = profile[index][2]; } else { - ss = profile[mBeginS + s][2] - begin_stex; + ss = profile[index][2] - begin_stex; } } -- cgit v1.2.3