From ab31e3bb217089e0cc28ca57bb5c4e46c06789dd Mon Sep 17 00:00:00 2001
From: Tofu Linden <tofu.linden@lindenlab.com>
Date: Fri, 21 May 2010 15:11:16 +0100
Subject: [PATCH] Fix up the SSE stuff so it compiles on Linux.  Though I don't
 think it actually works properly.

---
 indra/llcommon/llmemory.cpp              | 19 ---------------
 indra/llcommon/llmemory.h                | 31 +++++++++++++++++++-----
 indra/newview/llpolymesh.cpp             |  9 ++++---
 indra/newview/llviewerjointmesh_sse.cpp  |  4 +--
 indra/newview/llviewerjointmesh_sse2.cpp |  4 +--
 5 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 2a8015e26d9..5c6ca30cdd0 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -73,25 +73,6 @@ void LLMemory::freeReserve()
 	reserveMem = NULL;
 }
 
-void* ll_allocate (size_t size)
-{
-	if (size == 0)
-	{
-		llwarns << "Null allocation" << llendl;
-	}
-	void *p = malloc(size);
-	if (p == NULL)
-	{
-		LLMemory::freeReserve();
-		llerrs << "Out of memory Error" << llendl;
-	}
-	return p;
-}
-
-void ll_release (void *p)
-{
-	free(p);
-}
 
 //----------------------------------------------------------------------------
 
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 1c6f64dd8bc..f0813fb4ee3 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -32,14 +32,33 @@
 #ifndef LLMEMORY_H
 #define LLMEMORY_H
 
+#include <stdlib.h>
 
+inline void* ll_aligned_malloc(size_t size, size_t alignment = 16) // alignment MUST be power-of-two multiple of sizeof(void*).   returned hunk MUST be freed with ll_aligned_free().
+{
+#if defined(LL_WINDOWS)
+	return _mm_malloc(size, alignment);
+#else
+	void *rtn;
+	if (LL_LIKELY(0 == posix_memalign(&rtn, alignment, size)))
+	{
+		return rtn;
+	}
+	else // bad alignment requested, or out of memory
+	{
+		return NULL;
+	}
+#endif
+}
 
-extern S32 gTotalDAlloc;
-extern S32 gTotalDAUse;
-extern S32 gDACount;
-
-extern void* ll_allocate (size_t size);
-extern void ll_release (void *p);
+inline void ll_aligned_free(void *p)
+{
+#if defined(LL_WINDOWS)
+	_mm_free(p);
+#else
+	free(p); // posix_memalign() is compatible with heap deallocator
+#endif
+}
 
 class LL_COMMON_API LLMemory
 {
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index b8bdbfb2f81..af3c3e2b169 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -35,7 +35,8 @@
 //-----------------------------------------------------------------------------
 #include "llviewerprecompiledheaders.h"
 
-#include "llpolymesh.h"
+#include "llfasttimer.h"
+#include "llmemory.h"
 
 #include "llviewercontrol.h"
 #include "llxmltree.h"
@@ -45,7 +46,7 @@
 #include "llvolume.h"
 #include "llendianswizzle.h"
 
-#include "llfasttimer.h"
+#include "llpolymesh.h"
 
 #define HEADER_ASCII "Linden Mesh 1.0"
 #define HEADER_BINARY "Linden Binary Mesh 1.0"
@@ -715,7 +716,7 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_
 		int nfloats = nverts * (2*4 + 3*3 + 2 + 4);
 
 		//use aligned vertex data to make LLPolyMesh SSE friendly
-		mVertexData = (F32*) _mm_malloc(nfloats*4, 16);
+		mVertexData = (F32*) ll_aligned_malloc(nfloats*4, 16);
 		int offset = 0;
 		mCoords = 				(LLVector4*)(mVertexData + offset); offset += 4*nverts;
 		mNormals = 				(LLVector4*)(mVertexData + offset); offset += 4*nverts;
@@ -759,7 +760,7 @@ LLPolyMesh::~LLPolyMesh()
 	delete [] mClothingWeights;
 	delete [] mTexCoords;
 #else
-	_mm_free(mVertexData);
+	ll_aligned_free(mVertexData);
 #endif
 }
 
diff --git a/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp
index e586b910cd4..4fb5fafad12 100644
--- a/indra/newview/llviewerjointmesh_sse.cpp
+++ b/indra/newview/llviewerjointmesh_sse.cpp
@@ -94,8 +94,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
 	buffer->getNormalStrider(o_normals,   mesh->mFaceVertexOffset);
 
 	const F32*			weights			= mesh->getWeights();
-	const LLVector3*	coords			= mesh->getCoords();
-	const LLVector3*	normals			= mesh->getNormals();
+	const LLVector3*	coords			= (const LLVector3*)mesh->getCoords();
+	const LLVector3*	normals			= (const LLVector3*)mesh->getNormals();
 	for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
 	{
 		if( weight != weights[index])
diff --git a/indra/newview/llviewerjointmesh_sse2.cpp b/indra/newview/llviewerjointmesh_sse2.cpp
index 550044c321f..58cd75871d1 100644
--- a/indra/newview/llviewerjointmesh_sse2.cpp
+++ b/indra/newview/llviewerjointmesh_sse2.cpp
@@ -101,8 +101,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
 	buffer->getNormalStrider(o_normals,   mesh->mFaceVertexOffset);
 
 	const F32*			weights			= mesh->getWeights();
-	const LLVector3*	coords			= mesh->getCoords();
-	const LLVector3*	normals			= mesh->getNormals();
+	const LLVector3*	coords			= (const LLVector3*)mesh->getCoords();
+	const LLVector3*	normals			= (const LLVector3*)mesh->getNormals();
 	for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
 	{
 		if( weight != weights[index])
-- 
GitLab