Added ShyotlRenderVBOStrideMode to toggle between strided and unstrided VBOs.
This commit is contained in:
@@ -66,6 +66,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE;
|
||||
U32 LLVertexBuffer::sAllocatedBytes = 0;
|
||||
BOOL LLVertexBuffer::sMapped = FALSE;
|
||||
BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
|
||||
U32 LLVertexBuffer::sForceStrideMode = 0;
|
||||
BOOL LLVertexBuffer::sOmitBlank = FALSE;
|
||||
BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
|
||||
S32 LLVertexBuffer::sWeight4Loc = -1;
|
||||
@@ -263,7 +264,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
|
||||
{
|
||||
U32 count = pos.size();
|
||||
llassert(norm.size() >= pos.size());
|
||||
llassert_always(norm.size() >= pos.size());
|
||||
llassert_always(count > 0) ;
|
||||
|
||||
unbind();
|
||||
|
||||
@@ -448,7 +450,7 @@ void LLVertexBuffer::clientCopy(F64 max_time)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage, bool strided) :
|
||||
LLRefCount(),
|
||||
|
||||
mNumVerts(0),
|
||||
@@ -466,7 +468,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
mFilthy(FALSE),
|
||||
mEmpty(TRUE),
|
||||
mResized(FALSE),
|
||||
mDynamicSize(FALSE)
|
||||
mDynamicSize(FALSE),
|
||||
mIsStrided(strided),
|
||||
mStride(0)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (!sEnableVBOs)
|
||||
@@ -483,20 +487,27 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
{
|
||||
mUsage = GL_STREAM_DRAW_ARB;
|
||||
}
|
||||
|
||||
S32 stride = calcStride(typemask, mOffsets);
|
||||
|
||||
//zero out offsets
|
||||
for (U32 i = 0; i < TYPE_MAX; i++)
|
||||
{
|
||||
mOffsets[i] = 0;
|
||||
}
|
||||
|
||||
mTypeMask = typemask;
|
||||
mStride = stride;
|
||||
mSize = 0;
|
||||
mAlignedOffset = 0;
|
||||
mAlignedIndexOffset = 0;
|
||||
|
||||
if(sForceStrideMode)
|
||||
mIsStrided = sForceStrideMode == 1;
|
||||
|
||||
sCount++;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
|
||||
S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices)
|
||||
{
|
||||
S32 stride = 0;
|
||||
S32 offset = 0;
|
||||
for (S32 i=0; i<TYPE_MAX; i++)
|
||||
{
|
||||
U32 mask = 1<<i;
|
||||
@@ -504,13 +515,50 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
|
||||
{
|
||||
if (offsets)
|
||||
{
|
||||
offsets[i] = stride;
|
||||
offsets[i] = offset;
|
||||
}
|
||||
stride += sTypeSize[i];
|
||||
if(mIsStrided)
|
||||
{
|
||||
offset += sTypeSize[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += LLVertexBuffer::sTypeSize[i]*num_vertices;
|
||||
offset = (offset + 0xF) & ~0xF;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mIsStrided)
|
||||
{
|
||||
mStride = offset;
|
||||
return mStride * num_vertices + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
mStride = -1; //Stride is invalid with unstrided arrays.
|
||||
return offset + 16;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLVertexBuffer::calcVertexSize(const U32& typemask)
|
||||
{
|
||||
S32 size = 0;
|
||||
for (S32 i = 0; i < TYPE_MAX; i++)
|
||||
{
|
||||
U32 mask = 1<<i;
|
||||
if (typemask & mask)
|
||||
{
|
||||
size += LLVertexBuffer::sTypeSize[i];
|
||||
}
|
||||
}
|
||||
|
||||
return stride;
|
||||
return size;
|
||||
}
|
||||
|
||||
S32 LLVertexBuffer::getSize() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
// protected, use unref()
|
||||
@@ -750,7 +798,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
|
||||
}
|
||||
mNumVerts = nverts;
|
||||
}
|
||||
|
||||
mSize = calcOffsets(mTypeMask, mOffsets, mNumVerts);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::updateNumIndices(S32 nindices)
|
||||
@@ -958,7 +1006,7 @@ void LLVertexBuffer::allocateClientIndexBuffer()
|
||||
}
|
||||
|
||||
// Map for data access
|
||||
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
||||
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mFinal)
|
||||
@@ -1031,10 +1079,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
||||
sMappedCount++;
|
||||
}
|
||||
|
||||
return mMappedData;
|
||||
return mMappedData+mOffsets[type]+ (mIsStrided ? mStride : sTypeSize[type])*index;
|
||||
}
|
||||
|
||||
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mFinal)
|
||||
@@ -1065,6 +1113,9 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
}
|
||||
|
||||
llassert(src != NULL);
|
||||
|
||||
|
||||
mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);
|
||||
mAlignedIndexOffset = mMappedIndexData - src;
|
||||
stop_glerror();
|
||||
@@ -1095,7 +1146,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
sMappedCount++;
|
||||
}
|
||||
|
||||
return mMappedIndexData ;
|
||||
return mMappedIndexData + sizeof(U16)*index;
|
||||
}
|
||||
|
||||
void LLVertexBuffer::unmapBuffer(S32 type)
|
||||
@@ -1182,7 +1233,7 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
{
|
||||
if (type == LLVertexBuffer::TYPE_INDEX)
|
||||
{
|
||||
volatile U8* ptr = vbo.mapIndexBuffer();
|
||||
volatile U8* ptr = vbo.mapIndexBuffer(index);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
@@ -1190,16 +1241,16 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(ptr + index*sizeof(T));
|
||||
strider = (T*)ptr;
|
||||
strider.setStride(0);
|
||||
strider.setTypeSize(0);
|
||||
return TRUE;
|
||||
}
|
||||
else if (vbo.hasDataType(type))
|
||||
{
|
||||
S32 stride = vbo.getStride();
|
||||
volatile U8* ptr = vbo.mapVertexBuffer(type);
|
||||
S32 size = LLVertexBuffer::sTypeSize[type];
|
||||
S32 stride = vbo.getStride(type);
|
||||
|
||||
volatile U8* ptr = vbo.mapVertexBuffer(type,index);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
@@ -1207,9 +1258,11 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(ptr + vbo.getOffset(type) + index*stride);
|
||||
|
||||
strider = (T*)ptr;
|
||||
|
||||
strider.setStride(stride);
|
||||
strider.setTypeSize(size);
|
||||
strider.setTypeSize(LLVertexBuffer::sTypeSize[type]);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@@ -1272,25 +1325,6 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
|
||||
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::setStride(S32 type, S32 new_stride)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mNumVerts)
|
||||
{
|
||||
llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl;
|
||||
}
|
||||
// This code assumes that setStride() will only be called once per VBO per type.
|
||||
S32 delta = new_stride - sTypeSize[type];
|
||||
for (S32 i=type+1; i<TYPE_MAX; i++)
|
||||
{
|
||||
if (mTypeMask & (1<<i))
|
||||
{
|
||||
mOffsets[i] += delta;
|
||||
}
|
||||
}
|
||||
mStride += delta;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Set for rendering
|
||||
@@ -1488,7 +1522,6 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
stop_glerror();
|
||||
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
|
||||
S32 stride = mStride;
|
||||
|
||||
if ((data_mask & mTypeMask) != data_mask)
|
||||
{
|
||||
@@ -1521,58 +1554,58 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
||||
|
||||
if (data_mask & MAP_NORMAL)
|
||||
{
|
||||
glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD3)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE3_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD3]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD3), (void*)(base + mOffsets[TYPE_TEXCOORD3]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD2)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD2), (void*)(base + mOffsets[TYPE_TEXCOORD2]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD1)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(3,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD0)
|
||||
{
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
}
|
||||
if (data_mask & MAP_COLOR)
|
||||
{
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR]));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
|
||||
{
|
||||
glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, stride, (void*)(base+mOffsets[TYPE_WEIGHT4]));
|
||||
glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_CLOTHWEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
{
|
||||
glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0));
|
||||
glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
|
||||
}
|
||||
|
||||
llglassertok();
|
||||
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
static S32 sWeight4Loc;
|
||||
|
||||
static BOOL sUseStreamDraw;
|
||||
static U32 sForceStrideMode;
|
||||
static BOOL sOmitBlank;
|
||||
static BOOL sPreferStreamDraw;
|
||||
|
||||
@@ -102,11 +103,15 @@ public:
|
||||
static void unbind(); //unbind any bound vertex buffer
|
||||
|
||||
//get the size of a vertex with the given typemask
|
||||
//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 calcVertexSize(const U32& typemask);
|
||||
|
||||
//get the size of a buffer with the given typemask and vertex count
|
||||
//fill offsets with the offset of each vertex component array into the buffer
|
||||
// indexed by the following enum
|
||||
//If strided, num_vertices will be ignored.
|
||||
S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
|
||||
|
||||
|
||||
enum {
|
||||
TYPE_VERTEX,
|
||||
TYPE_NORMAL,
|
||||
@@ -162,11 +167,11 @@ protected:
|
||||
void allocateClientIndexBuffer() ;
|
||||
|
||||
public:
|
||||
LLVertexBuffer(U32 typemask, S32 usage);
|
||||
LLVertexBuffer(U32 typemask, S32 usage, bool strided=true);
|
||||
|
||||
// map for data access
|
||||
volatile U8* mapVertexBuffer(S32 type = -1, S32 access = -1);
|
||||
volatile U8* mapIndexBuffer(S32 access = -1);
|
||||
volatile U8* mapVertexBuffer(S32 type, S32 index);
|
||||
volatile U8* mapIndexBuffer(S32 index);
|
||||
|
||||
// set for rendering
|
||||
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
|
||||
@@ -201,17 +206,15 @@ public:
|
||||
|
||||
volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
|
||||
volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
|
||||
S32 getStride() const { return mStride; }
|
||||
S32 getTypeMask() const { return mTypeMask; }
|
||||
BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; }
|
||||
S32 getSize() const { return mNumVerts*mStride; }
|
||||
S32 getStride(S32 type) const { return mIsStrided ? mStride : sTypeSize[type]; }
|
||||
U32 getTypeMask() const { return mTypeMask; }
|
||||
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
|
||||
S32 getSize() const;
|
||||
S32 getIndicesSize() const { return mNumIndices * sizeof(U16); }
|
||||
volatile U8* getMappedData() const { return mMappedData; }
|
||||
volatile U8* getMappedIndices() const { return mMappedIndexData; }
|
||||
S32 getOffset(S32 type) const { return mOffsets[type]; }
|
||||
S32 getUsage() const { return mUsage; }
|
||||
|
||||
void setStride(S32 type, S32 new_stride);
|
||||
|
||||
void draw(U32 mode, U32 count, U32 indices_offset) const;
|
||||
void drawArrays(U32 mode, U32 offset, U32 count) const;
|
||||
@@ -230,7 +233,9 @@ protected:
|
||||
|
||||
ptrdiff_t mAlignedOffset;
|
||||
ptrdiff_t mAlignedIndexOffset;
|
||||
S32 mStride;
|
||||
bool mIsStrided;
|
||||
S32 mStride; // Vertex size.
|
||||
S32 mSize; // Full array size
|
||||
U32 mTypeMask;
|
||||
S32 mUsage; // GL usage
|
||||
U32 mGLBuffer; // GL VBO handle
|
||||
|
||||
Reference in New Issue
Block a user