From 7c1e4a1d7614b6eb4bd469d66c8a3841b98a1363 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Mon, 23 Mar 2020 21:17:21 -0400
Subject: [PATCH] VBO opt

---
 indra/llcommon/llstrider.h        | 31 +++++++++++++++--
 indra/llrender/llvertexbuffer.cpp | 55 +++++++++++++++++--------------
 2 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index ed9284d2c51..083df5e40ac 100644
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
@@ -26,7 +26,19 @@
 #ifndef LL_LLSTRIDER_H
 #define LL_LLSTRIDER_H
 
-#include "stdtypes.h"
+#include "llmath.h"
+#include "llvector4a.h"
+
+template<typename T>
+inline void copyArray(T* dst, const T* src, const U32 bytes)
+{
+	memcpy(dst, src, bytes);
+}
+template<>
+inline void copyArray<>(LLVector4a* dst, const LLVector4a* src, const U32 bytes)
+{
+	LLVector4a::memcpyNonAliased16(dst->getF32ptr(), src->getF32ptr(), bytes);
+}
 
 template <class Object> class LLStrider
 {
@@ -39,7 +51,7 @@ template <class Object> class LLStrider
 public:
 
 	LLStrider()  { mObjectp = NULL; mSkip = sizeof(Object); } 
-	~LLStrider() { } 
+	~LLStrider() = default;
 
 	const LLStrider<Object>& operator =  (Object *first)    { mObjectp = first; return *this;}
 	void setStride (S32 skipBytes)	{ mSkip = (skipBytes ? skipBytes : sizeof(Object));}
@@ -62,6 +74,21 @@ template <class Object> class LLStrider
 	Object* operator +=(int i)     { mBytep += mSkip*i; return mObjectp; }
 
 	Object& operator[](U32 index)  { return *(Object*)(mBytep + (mSkip * index)); }
+
+	void copyArray(const U32 offset, const Object* src, const U32 length)
+	{
+		if (mSkip == sizeof(Object))
+		{
+			::copyArray(mObjectp + offset, src, length * sizeof(Object));
+		}
+		else
+		{
+			for (U32 i = 0; i < length; i++)
+			{
+				(*this)[offset + i] = src[i];
+			}
+		}
+	}
 };
 
 #endif // LL_LLSTRIDER_H
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index e3035c71942..2b609dad018 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -2097,34 +2097,21 @@ void LLVertexBuffer::unmapBuffer()
 
 //----------------------------------------------------------------------------
 
-template <class T,S32 type> struct VertexBufferStrider
+template <class T, S32 type>
+struct VertexBufferStrider
 {
 	typedef LLStrider<T> strider_t;
-	static bool get(LLVertexBuffer& vbo, 
-					strider_t& strider, 
-					S32 index, S32 count, bool map_range)
+	static bool get(LLVertexBuffer& vbo,
+		strider_t& strider,
+		S32 index, S32 count, bool map_range)
 	{
-		if (type == LLVertexBuffer::TYPE_INDEX)
-		{
-			volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
-
-			if (ptr == NULL)
-			{
-				LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL;
-				return false;
-			}
-
-			strider = (T*)ptr;
-			strider.setStride(0);
-			return true;
-		}
-		else if (vbo.hasDataType(type))
+		if (vbo.hasDataType(type))
 		{
 			S32 stride = LLVertexBuffer::sTypeSize[type];
 
 			volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
 
-			if (ptr == NULL)
+			if (ptr == nullptr)
 			{
 				LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL;
 				return false;
@@ -2142,6 +2129,28 @@ template <class T,S32 type> struct VertexBufferStrider
 	}
 };
 
+template<class T>
+struct VertexBufferStrider<T, LLVertexBuffer::TYPE_INDEX>
+{
+	typedef LLStrider<T> strider_t;
+	static bool get(LLVertexBuffer& vbo,
+		strider_t& strider,
+		S32 index, S32 count, bool map_range)
+	{
+		volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
+
+		if (ptr == nullptr)
+		{
+			LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL;
+			return false;
+		}
+
+		strider = (T*) ptr;
+		strider.setStride(0);
+		return true;
+	}
+};
+
 bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
 {
 	return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count, map_range);
@@ -2326,9 +2335,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			{
 				
 				U32 unsatisfied_mask = (required_mask & ~data_mask);
-				U32 i = 0;
-
-				while (i < TYPE_MAX)
+				for (U32 i = 0; i < TYPE_MAX; i++) // <alchemy/>
 				{
                     U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
 					switch (unsatisfied_flag)
@@ -2355,7 +2362,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
                LL_INFOS() << "Missing indices" << LL_ENDL;
             }
 
-				LL_ERRS() << "Shader consumption mismatches data provision." << LL_ENDL;
+				LL_WARNS() << "Shader consumption mismatches data provision." << LL_ENDL;
 			}
 		}
 	}
-- 
GitLab