summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2010-06-10 15:16:08 -0500
committerDave Parks <davep@lindenlab.com>2010-06-10 15:16:08 -0500
commitaab53dc25021dfb9b0a734480233e352a82486cd (patch)
treede9c71677f9955112c0b01bf8c064404bd862f53 /indra/llrender
parent1d92a950df91d7e6d3a34e925f445bc389a3fa93 (diff)
parent3ea0018dc6f94c029d7dbf13bdd5b0bc0558c8d8 (diff)
merge
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llimagegl.cpp4
-rw-r--r--indra/llrender/llrender.cpp97
-rw-r--r--indra/llrender/llrender.h14
-rw-r--r--indra/llrender/llrendersphere.cpp86
-rw-r--r--indra/llrender/llrendersphere.h4
-rw-r--r--indra/llrender/llvertexbuffer.cpp294
-rw-r--r--indra/llrender/llvertexbuffer.h26
7 files changed, 370 insertions, 155 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 2f02ccf30b..2579bad0b6 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1813,7 +1813,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
{
LL_WARNS_ONCE("render") << "Ugh, non-finite u/v in mask pick" << LL_ENDL;
u = v = 0.f;
- llassert(false);
+ //llassert(false);
}
if (LL_UNLIKELY(u < 0.f || u > 1.f ||
@@ -1821,7 +1821,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
{
LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL;
u = v = 0.f;
- llassert(false);
+ //llassert(false);
}
S32 x = llfloor(u * mPickMaskWidth);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 2472339ec4..70601663e6 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -39,6 +39,7 @@
#include "llimagegl.h"
#include "llrendertarget.h"
#include "lltexture.h"
+#include "llvector4a.h"
LLRender gGL;
@@ -53,6 +54,7 @@ U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0;
static const U32 LL_NUM_TEXTURE_LAYERS = 16;
+static const U32 LL_MAX_UI_STACK_DEPTH = 32;
static GLenum sGLTextureType[] =
{
@@ -757,14 +759,27 @@ LLRender::LLRender()
mCount(0),
mMode(LLRender::TRIANGLES),
mCurrTextureUnitIndex(0),
- mMaxAnisotropy(0.f)
+ mMaxAnisotropy(0.f),
+ mUIStackDepth(0)
{
mBuffer = new LLVertexBuffer(immediate_mask, 0);
mBuffer->allocateBuffer(4096, 0, TRUE);
- mBuffer->getVertexStrider(mVerticesp);
- mBuffer->getTexCoord0Strider(mTexcoordsp);
- mBuffer->getColorStrider(mColorsp);
-
+
+ LLStrider<LLVector3> vert;
+ LLStrider<LLVector2> tc;
+ LLStrider<LLColor4U> color;
+
+ mBuffer->getVertexStrider(vert);
+ mBuffer->getTexCoord0Strider(tc);
+ mBuffer->getColorStrider(color);
+
+ mVerticesp = (LLVector4a*) vert.get();
+ mTexcoordsp = tc.get();
+ mColorsp = color.get();
+
+ mUIOffset = (LLVector4a*) ll_aligned_malloc_16(LL_MAX_UI_STACK_DEPTH*sizeof(LLVector4a));
+ mUIScale = (LLVector4a*) ll_aligned_malloc_16(LL_MAX_UI_STACK_DEPTH*sizeof(LLVector4a));
+
mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
{
@@ -800,6 +815,11 @@ void LLRender::shutdown()
mTexUnits.clear();
delete mDummyTexUnit;
mDummyTexUnit = NULL;
+
+ ll_aligned_free_16(mUIOffset);
+ mUIOffset = NULL;
+ ll_aligned_free_16(mUIScale);
+ mUIScale = NULL;
}
void LLRender::refreshState(void)
@@ -848,84 +868,83 @@ void LLRender::popMatrix()
void LLRender::translateUI(F32 x, F32 y, F32 z)
{
- if (mUIOffset.empty())
+ if (mUIStackDepth == 0)
{
llerrs << "Need to push a UI translation frame before offsetting" << llendl;
}
- mUIOffset.front().mV[0] += x;
- mUIOffset.front().mV[1] += y;
- mUIOffset.front().mV[2] += z;
+ LLVector4a trans(x,y,z);
+ mUIOffset[mUIStackDepth-1].add(trans);
}
void LLRender::scaleUI(F32 x, F32 y, F32 z)
{
- if (mUIScale.empty())
+ if (mUIStackDepth == 0)
{
llerrs << "Need to push a UI transformation frame before scaling." << llendl;
}
- mUIScale.front().scaleVec(LLVector3(x,y,z));
+ LLVector4a scale(x,y,z);
+ mUIScale[mUIStackDepth-1].mul(scale);
}
void LLRender::pushUIMatrix()
{
- if (mUIOffset.empty())
+ if (mUIStackDepth == 0)
{
- mUIOffset.push_front(LLVector3(0,0,0));
+ mUIOffset[0].clear();
+ mUIScale[0].splat(1.f);
}
- else
+ else if (mUIStackDepth < LL_MAX_UI_STACK_DEPTH)
{
- mUIOffset.push_front(mUIOffset.front());
- }
-
- if (mUIScale.empty())
- {
- mUIScale.push_front(LLVector3(1,1,1));
+ mUIOffset[mUIStackDepth] = mUIOffset[mUIStackDepth-1];
+ mUIScale[mUIStackDepth] = mUIScale[mUIStackDepth-1];
}
else
{
- mUIScale.push_front(mUIScale.front());
+ llerrs << "Blown UI matrix stack." << llendl;
}
+
+ ++mUIStackDepth;
+
}
void LLRender::popUIMatrix()
{
- if (mUIOffset.empty())
+ if (mUIStackDepth == 0)
{
llerrs << "UI offset stack blown." << llendl;
}
- mUIOffset.pop_front();
- mUIScale.pop_front();
+ --mUIStackDepth;
}
LLVector3 LLRender::getUITranslation()
{
- if (mUIOffset.empty())
+ if (mUIStackDepth == 0)
{
llerrs << "UI offset stack empty." << llendl;
}
- return mUIOffset.front();
+ return LLVector3(mUIOffset[mUIStackDepth-1].getF32());
}
LLVector3 LLRender::getUIScale()
{
- if (mUIScale.empty())
+ if (mUIStackDepth == 0)
{
llerrs << "UI scale stack empty." << llendl;
}
- return mUIScale.front();
+ return LLVector3(mUIScale[mUIStackDepth-1].getF32());
}
void LLRender::loadUIIdentity()
{
- if (mUIOffset.empty())
+ if (mUIStackDepth == 0)
{
llerrs << "Need to push UI translation frame before clearing offset." << llendl;
}
- mUIOffset.front().setVec(0,0,0);
- mUIScale.front().setVec(1,1,1);
+ mUIOffset[mUIStackDepth-1].clear();
+ mUIScale[mUIStackDepth-1].splat(1.f);
}
void LLRender::setColorMask(bool writeColor, bool writeAlpha)
@@ -1154,7 +1173,7 @@ void LLRender::flush()
}
#endif
- if (!mUIOffset.empty())
+ if (mUIStackDepth > 0)
{
sUICalls++;
sUIVerts += mCount;
@@ -1206,24 +1225,22 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
return;
}
- if (mUIOffset.empty())
+ LLVector3& v = reinterpret_cast<LLVector3&>(mVerticesp[mCount]);
+ v.set(x,y,z);
+ if (mUIStackDepth != 0)
{
- mVerticesp[mCount] = LLVector3(x,y,z);
- }
- else
- {
- LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.front()).scaledVec(mUIScale.front());
- mVerticesp[mCount] = vert;
+ v += reinterpret_cast<LLVector3&>(mUIOffset[mUIStackDepth-1]);
+ v.scaleVec(reinterpret_cast<LLVector3&>(mUIScale[mUIStackDepth-1]));
}
mCount++;
if (mCount < 4096)
{
- mVerticesp[mCount] = mVerticesp[mCount-1];
mColorsp[mCount] = mColorsp[mCount-1];
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
}
}
+
void LLRender::vertex2i(const GLint& x, const GLint& y)
{
vertex3f((GLfloat) x, (GLfloat) y, 0);
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 3cda4b5770..11cd95646f 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -45,6 +45,7 @@
#include "v4coloru.h"
#include "llstrider.h"
#include "llpointer.h"
+#include "llmemory.h"
#include "llglheaders.h"
class LLVertexBuffer;
@@ -52,6 +53,7 @@ class LLCubeMap;
class LLImageGL;
class LLRenderTarget;
class LLTexture ;
+class LLVector4a;
class LLTexUnit
{
@@ -360,9 +362,10 @@ private:
F32 mCurrAlphaFuncVal;
LLPointer<LLVertexBuffer> mBuffer;
- LLStrider<LLVector3> mVerticesp;
- LLStrider<LLVector2> mTexcoordsp;
- LLStrider<LLColor4U> mColorsp;
+ LLVector4a* mVerticesp;
+ LLVector2* mTexcoordsp;
+ LLColor4U* mColorsp;
+
std::vector<LLTexUnit*> mTexUnits;
LLTexUnit* mDummyTexUnit;
@@ -372,9 +375,10 @@ private:
eBlendFactor mCurrBlendAlphaDFactor;
F32 mMaxAnisotropy;
- std::list<LLVector3> mUIOffset;
- std::list<LLVector3> mUIScale;
+ LLVector4a* mUIOffset;
+ LLVector4a* mUIScale;
+ U32 mUIStackDepth;
};
extern F64 gGLModelView[16];
diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp
index e22b753923..212963f270 100644
--- a/indra/llrender/llrendersphere.cpp
+++ b/indra/llrender/llrendersphere.cpp
@@ -68,45 +68,6 @@ void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks)
}
-// lat = 0 is Z-axis
-// lon = 0, lat = 90 at X-axis
-void lat2xyz(LLVector3 * result, F32 lat, F32 lon)
-{
- // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result
- F32 r;
- result->mV[VX] = (F32) (cos(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD));
- result->mV[VY] = (F32) (sin(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD));
- r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f);
- if (r == 1.0f)
- {
- result->mV[VZ] = 0.0f;
- }
- else
- {
- result->mV[VZ] = (F32) pow(1 - r*r, 0.5f);
- if (lat > 90.01)
- {
- result->mV[VZ] *= -1.0;
- }
- }
-}
-
-void lat2xyz_rad(LLVector3 * result, F32 lat, F32 lon)
-{
- // Convert a latitude and longitude to x,y,z on a normal sphere and return it in result
- F32 r;
- result->mV[VX] = (F32) (cos(lon) * sin(lat));
- result->mV[VY] = (F32) (sin(lon) * sin(lat));
- r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f);
- if (r == 1.0f)
- result->mV[VZ] = 0.0f;
- else
- {
- result->mV[VZ] = (F32) pow(1 - r*r, 0.5f);
- if (lat > F_PI_BY_TWO) result->mV[VZ] *= -1.0;
- }
-}
-
// A couple thoughts on sphere drawing:
// 1) You need more slices than stacks, but little less than 2:1
// 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother
@@ -181,3 +142,50 @@ void LLRenderSphere::render()
{
glCallList(mDList[0]);
}
+
+inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
+{
+ return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude),
+ sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude),
+ cos(F_TWO_PI * latitude));
+}
+
+
+void LLRenderSphere::renderGGL()
+{
+ S32 const LATITUDE_SLICES = 20;
+ S32 const LONGITUDE_SLICES = 30;
+
+ if (mSpherePoints.empty())
+ {
+ mSpherePoints.resize(LATITUDE_SLICES + 1);
+ for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++)
+ {
+ mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1);
+ for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++)
+ {
+ F32 lat = (F32)lat_i / LATITUDE_SLICES;
+ F32 lon = (F32)lon_i / LONGITUDE_SLICES;
+
+ mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon);
+ }
+ }
+ }
+
+ gGL.begin(LLRender::TRIANGLES);
+
+ for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
+ {
+ for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
+ {
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
+
+ gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV);
+ }
+ }
+ gGL.end();
+}
diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h
index 617ee3e12e..ebc71b6146 100644
--- a/indra/llrender/llrendersphere.h
+++ b/indra/llrender/llrendersphere.h
@@ -52,6 +52,10 @@ public:
void cleanupGL();
void render(F32 pixel_area); // of a box of size 1.0 at that position
void render(); // render at highest LOD
+ void renderGGL(); // render using LLRender
+
+private:
+ std::vector< std::vector<LLVector3> > mSpherePoints;
};
extern LLRenderSphere gSphere;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 7fa47cd171..514ca25aa0 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -31,6 +31,7 @@
*/
#include "linden_common.h"
+#include "llmemory.h"
#include <boost/static_assert.hpp>
@@ -39,6 +40,7 @@
#include "llglheaders.h"
#include "llmemtype.h"
#include "llrender.h"
+#include "llvector4a.h"
//============================================================================
@@ -66,6 +68,27 @@ S32 LLVertexBuffer::sWeight4Loc = -1;
std::vector<U32> LLVertexBuffer::sDeleteList;
+#define LL_ALIGNED_VB 1
+
+#if LL_ALIGNED_VB
+
+S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
+{
+ sizeof(LLVector4), // TYPE_VERTEX,
+ sizeof(LLVector4), // TYPE_NORMAL,
+ sizeof(LLVector2), // TYPE_TEXCOORD0,
+ sizeof(LLVector2), // TYPE_TEXCOORD1,
+ sizeof(LLVector2), // TYPE_TEXCOORD2,
+ sizeof(LLVector2), // TYPE_TEXCOORD3,
+ sizeof(LLColor4U), // TYPE_COLOR,
+ sizeof(LLVector4), // TYPE_BINORMAL,
+ sizeof(F32), // TYPE_WEIGHT,
+ sizeof(LLVector4), // TYPE_WEIGHT4,
+ sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
+};
+
+#else
+
S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
{
sizeof(LLVector3), // TYPE_VERTEX,
@@ -81,6 +104,8 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
};
+#endif
+
U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
GL_TRIANGLES,
@@ -237,10 +262,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
}
-void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
+void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
{
- llassert(mRequestedNumVerts >= 0);
-
if (start >= (U32) mRequestedNumVerts ||
end >= (U32) mRequestedNumVerts)
{
@@ -255,6 +278,25 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
}
+ if (gDebugGL && !useVBOs())
+ {
+ U16* idx = ((U16*) getIndicesPointer())+indices_offset;
+ for (U32 i = 0; i < count; ++i)
+ {
+ if (idx[i] < start || idx[i] > end)
+ {
+ llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl;
+ }
+ }
+ }
+}
+
+void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
+{
+ validateRange(start, end, count, indices_offset);
+
+ llassert(mRequestedNumVerts >= 0);
+
if (mGLIndices != sGLRenderIndices)
{
llerrs << "Wrong index buffer bound." << llendl;
@@ -273,17 +315,6 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
- if (gDebugGL && !useVBOs())
- {
- for (U32 i = 0; i < count; ++i)
- {
- if (idx[i] < start || idx[i] > end)
- {
- llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl;
- }
- }
- }
-
stop_glerror();
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
@@ -428,11 +459,42 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mTypeMask = typemask;
mStride = stride;
+ mAlignedOffset = 0;
+ mAlignedIndexOffset = 0;
+
sCount++;
}
+#if LL_ALIGNED_VB
+//static
+S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets, S32 num_vertices)
+{
+ S32 offset = 0;
+ for (S32 i=0; i<TYPE_MAX; i++)
+ {
+ U32 mask = 1<<i;
+ if (typemask & mask)
+ {
+ if (offsets)
+ {
+ offsets[i] = offset;
+ offset += LLVertexBuffer::sTypeOffsets[i]*num_vertices;
+ offset = (offset + 0xF) & ~0xF;
+ }
+ }
+ }
+
+ return offset+16;
+}
+
+S32 LLVertexBuffer::getSize() const
+{
+ return mStride;
+}
+
+#else
//static
-S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
+S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets, S32 num_vertices)
{
S32 stride = 0;
for (S32 i=0; i<TYPE_MAX; i++)
@@ -451,6 +513,12 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
return stride;
}
+S32 LLVertexBuffer::getSize() const
+{
+ return mNumVerts*mStride;
+}
+
+#endif
// protected, use unref()
//virtual
LLVertexBuffer::~LLVertexBuffer()
@@ -560,7 +628,7 @@ void LLVertexBuffer::createGLBuffer()
{
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
- mMappedData = new U8[size];
+ mMappedData = (U8*) ll_aligned_malloc_16(size);
memset(mMappedData, 0, size);
}
}
@@ -582,16 +650,20 @@ void LLVertexBuffer::createGLIndices()
mEmpty = TRUE;
+ //pad by 16 bytes for aligned copies
+ size += 16;
+
if (useVBOs())
{
+ //pad by another 16 bytes for VBO pointer adjustment
+ size += 16;
mMappedIndexData = NULL;
genIndices();
mResized = TRUE;
}
else
{
- mMappedIndexData = new U8[size];
- memset(mMappedIndexData, 0, size);
+ mMappedIndexData = (U8*) ll_aligned_malloc_16(size);
static int gl_buffer_idx = 0;
mGLIndices = ++gl_buffer_idx;
}
@@ -612,7 +684,7 @@ void LLVertexBuffer::destroyGLBuffer()
}
else
{
- delete [] mMappedData;
+ ll_aligned_free_16(mMappedData);
mMappedData = NULL;
mEmpty = TRUE;
}
@@ -639,7 +711,7 @@ void LLVertexBuffer::destroyGLIndices()
}
else
{
- delete [] mMappedIndexData;
+ ll_aligned_free_16(mMappedIndexData);
mMappedIndexData = NULL;
mEmpty = TRUE;
}
@@ -664,7 +736,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
}
mRequestedNumVerts = nverts;
-
+
if (!mDynamicSize)
{
mNumVerts = nverts;
@@ -679,6 +751,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
}
mNumVerts = nverts;
}
+#if LL_ALIGNED_VB
+ mStride = calcStride(mTypeMask, mOffsets, mNumVerts);
+#endif
}
@@ -754,9 +829,6 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
{
sAllocatedBytes -= getSize() + getIndicesSize();
- S32 oldsize = getSize();
- S32 old_index_size = getIndicesSize();
-
updateNumVerts(newnverts);
updateNumIndices(newnindices);
@@ -773,26 +845,10 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
}
else
{
- //delete old buffer, keep GL buffer for now
if (!useVBOs())
{
- U8* old = mMappedData;
- mMappedData = new U8[newsize];
- if (old)
- {
- memcpy(mMappedData, old, llmin(newsize, oldsize));
- if (newsize > oldsize)
- {
- memset(mMappedData+oldsize, 0, newsize-oldsize);
- }
-
- delete [] old;
- }
- else
- {
- memset(mMappedData, 0, newsize);
- mEmpty = TRUE;
- }
+ ll_aligned_free_16(mMappedData);
+ mMappedData = (U8*) ll_aligned_malloc_16(newsize);
}
mResized = TRUE;
}
@@ -812,24 +868,8 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
{
if (!useVBOs())
{
- //delete old buffer, keep GL buffer for now
- U8* old = mMappedIndexData;
- mMappedIndexData = new U8[new_index_size];
-
- if (old)
- {
- memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size));
- if (new_index_size > old_index_size)
- {
- memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size);
- }
- delete [] old;
- }
- else
- {
- memset(mMappedIndexData, 0, new_index_size);
- mEmpty = TRUE;
- }
+ ll_aligned_free_16(mMappedIndexData);
+ mMappedIndexData = (U8*) ll_aligned_malloc_16(new_index_size);
}
mResized = TRUE;
}
@@ -861,7 +901,7 @@ BOOL LLVertexBuffer::useVBOs() const
return FALSE;
}
#endif
- return sEnableVBOs;
+ return TRUE;
}
//----------------------------------------------------------------------------
@@ -886,12 +926,19 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
setBuffer(0);
mLocked = TRUE;
stop_glerror();
- mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+ U8* src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
+ mAlignedOffset = mMappedData - src;
+
stop_glerror();
}
{
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
- mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ U8* src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ mMappedIndexData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
+ mAlignedIndexOffset = mMappedIndexData - src;
+
stop_glerror();
}
@@ -975,6 +1022,45 @@ void LLVertexBuffer::unmapBuffer()
//----------------------------------------------------------------------------
+#if LL_ALIGNED_VB
+
+template <class T,S32 type> struct VertexBufferStrider
+{
+ typedef LLStrider<T> strider_t;
+ static bool get(LLVertexBuffer& vbo,
+ strider_t& strider,
+ S32 index)
+ {
+ if (vbo.mapBuffer() == NULL)
+ {
+ llwarns << "mapBuffer failed!" << llendl;
+ return FALSE;
+ }
+
+ if (type == LLVertexBuffer::TYPE_INDEX)
+ {
+ S32 stride = sizeof(T);
+ strider = (T*)(vbo.getMappedIndices() + index*stride);
+ strider.setStride(0);
+ return TRUE;
+ }
+ else if (vbo.hasDataType(type))
+ {
+ S32 stride = LLVertexBuffer::sTypeOffsets[type];
+ strider = (T*)(vbo.getMappedData() + vbo.getOffset(type)+index*stride);
+ strider.setStride(stride);
+ return TRUE;
+ }
+ else
+ {
+ llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
+ }
+ return FALSE;
+ }
+};
+
+#else
+
template <class T,S32 type> struct VertexBufferStrider
{
typedef LLStrider<T> strider_t;
@@ -1010,6 +1096,7 @@ template <class T,S32 type> struct VertexBufferStrider
}
};
+#endif
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index)
{
@@ -1231,7 +1318,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (mGLBuffer)
{
- if (sEnableVBOs && sVBOActive)
+ if (sVBOActive)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
sBindCount++;
@@ -1243,7 +1330,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
setup = TRUE; // ... or a client memory pointer changed
}
}
- if (sEnableVBOs && mGLIndices && sIBOActive)
+ if (mGLIndices && sIBOActive)
{
/*if (sMapped)
{
@@ -1272,6 +1359,81 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
+#if LL_ALIGNED_VB
+
+// virtual (default)
+void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
+{
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
+ stop_glerror();
+ U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
+
+ if ((data_mask & mTypeMask) != data_mask)
+ {
+ llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
+ }
+
+ if (data_mask & MAP_NORMAL)
+ {
+ glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeOffsets[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+ }
+ if (data_mask & MAP_TEXCOORD3)
+ {
+ glClientActiveTextureARB(GL_TEXTURE3_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeOffsets[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD2)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeOffsets[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD1)
+ {
+ glClientActiveTextureARB(GL_TEXTURE1_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeOffsets[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_BINORMAL)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeOffsets[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD0)
+ {
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeOffsets[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+ }
+ if (data_mask & MAP_COLOR)
+ {
+ glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeOffsets[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
+ }
+
+ if (data_mask & MAP_WEIGHT)
+ {
+ glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeOffsets[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT]));
+ }
+
+ if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
+ {
+ glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeOffsets[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4]));
+ }
+
+ if (data_mask & MAP_CLOTHWEIGHT)
+ {
+ glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeOffsets[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
+ }
+ if (data_mask & MAP_VERTEX)
+ {
+ glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeOffsets[TYPE_VERTEX], (void*)(base + 0));
+ }
+
+ llglassertok();
+}
+
+#else
+
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
{
@@ -1344,6 +1506,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
llglassertok();
}
+#endif
+
void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count)
{
// TODO: use GL_APPLE_flush_buffer_range here
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index d1700aa54a..715309b64a 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -79,6 +79,17 @@ protected:
class LLVertexBuffer : public LLRefCount
{
public:
+ LLVertexBuffer(const LLVertexBuffer& rhs)
+ {
+ *this = rhs;
+ }
+
+ const LLVertexBuffer& operator=(const LLVertexBuffer& rhs)
+ {
+ llerrs << "Illegal operation!" << llendl;
+ return *this;
+ }
+
static LLVBOPool sStreamVBOPool;
static LLVBOPool sDynamicVBOPool;
static LLVBOPool sStreamIBOPool;
@@ -98,7 +109,7 @@ public:
//if offsets is not NULL, its contents will be filled
//with the offset of each vertex component in the buffer,
// indexed by the following enum
- static S32 calcStride(const U32& typemask, S32* offsets = NULL);
+ static S32 calcStride(const U32& typemask, S32* offsets = NULL, S32 num_vertices = 0);
enum {
TYPE_VERTEX,
@@ -187,12 +198,12 @@ public:
S32 getRequestedVerts() const { return mRequestedNumVerts; }
S32 getRequestedIndices() const { return mRequestedNumIndices; }
- U8* getIndicesPointer() const { return useVBOs() ? NULL : mMappedIndexData; }
+ U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
U8* getVerticesPointer() const { return useVBOs() ? NULL : mMappedData; }
S32 getStride() const { return mStride; }
U32 getTypeMask() const { return mTypeMask; }
BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; }
- S32 getSize() const { return mNumVerts*mStride; }
+ S32 getSize() const;
S32 getIndicesSize() const { return mNumIndices * sizeof(U16); }
U8* getMappedData() const { return mMappedData; }
U8* getMappedIndices() const { return mMappedIndexData; }
@@ -207,12 +218,19 @@ public:
void drawArrays(U32 mode, U32 offset, U32 count) const;
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+ //for debugging, validate data in given range is valid
+ void validateRange(U32 start, U32 end, U32 count, U32 offset) const;
+
+
+
protected:
S32 mNumVerts; // Number of vertices allocated
S32 mNumIndices; // Number of indices allocated
S32 mRequestedNumVerts; // Number of vertices requested
S32 mRequestedNumIndices; // Number of indices requested
+ ptrdiff_t mAlignedOffset;
+ ptrdiff_t mAlignedIndexOffset;
S32 mStride;
U32 mTypeMask;
S32 mUsage; // GL usage
@@ -227,7 +245,7 @@ protected:
S32 mOffsets[TYPE_MAX];
BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
-
+
class DirtyRegion
{
public: