summaryrefslogtreecommitdiff
path: root/indra/llrender/llvertexbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llvertexbuffer.cpp')
-rwxr-xr-x[-rw-r--r--]indra/llrender/llvertexbuffer.cpp364
1 files changed, 229 insertions, 135 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index dfbd8cd4ee..0fae600a90 100644..100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -26,7 +26,7 @@
#include "linden_common.h"
-#include <boost/static_assert.hpp>
+#include "llfasttimer.h"
#include "llsys.h"
#include "llvertexbuffer.h"
// #include "llrender.h"
@@ -85,12 +85,12 @@ const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
//static
LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
U32 LLVBOPool::sBytesPooled = 0;
U32 LLVBOPool::sIndexBytesPooled = 0;
-U32 LLVBOPool::sCurGLName = 1;
std::list<U32> LLVertexBuffer::sAvailableVAOName;
U32 LLVertexBuffer::sCurVAOName = 1;
@@ -124,16 +124,8 @@ U32 LLVBOPool::genBuffer()
{
U32 ret = 0;
- if (mGLNamePool.empty())
- {
- ret = sCurGLName++;
- }
- else
- {
- ret = mGLNamePool.front();
- mGLNamePool.pop_front();
- }
-
+ glGenBuffersARB(1, &ret);
+
return ret;
}
@@ -145,12 +137,9 @@ void LLVBOPool::deleteBuffer(U32 name)
glBindBufferARB(mType, name);
glBufferDataARB(mType, 0, NULL, mUsage);
-
- llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
-
- mGLNamePool.push_back(name);
-
glBindBufferARB(mType, 0);
+
+ glDeleteBuffersARB(1, &name);
}
}
@@ -199,7 +188,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
glBufferDataARB(mType, size, 0, mUsage);
- ret = (U8*) ll_aligned_malloc_16(size);
+ if (mUsage != GL_DYNAMIC_COPY_ARB)
+ { //data will be provided by application
+ ret = (U8*) ll_aligned_malloc<64>(size);
+ }
}
else
{ //always use a true hint of static draw when allocating non-client-backed buffers
@@ -252,7 +244,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
llassert(vbo_block_size(size) == size);
deleteBuffer(name);
- ll_aligned_free_16((U8*) buffer);
+ ll_aligned_free_fallback((U8*) buffer);
if (mType == GL_ARRAY_BUFFER_ARB)
{
@@ -306,7 +298,7 @@ void LLVBOPool::cleanup()
if (r.mClientData)
{
- ll_aligned_free_16((void*) r.mClientData);
+ ll_aligned_free<64>((void*) r.mClientData);
}
l.pop_front();
@@ -342,13 +334,32 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector2), // TYPE_TEXCOORD3,
sizeof(LLColor4U), // TYPE_COLOR,
sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
- sizeof(LLVector4), // TYPE_BINORMAL,
+ sizeof(LLVector4), // TYPE_TANGENT,
sizeof(F32), // TYPE_WEIGHT,
sizeof(LLVector4), // TYPE_WEIGHT4,
sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
+static std::string vb_type_name[] =
+{
+ "TYPE_VERTEX",
+ "TYPE_NORMAL",
+ "TYPE_TEXCOORD0",
+ "TYPE_TEXCOORD1",
+ "TYPE_TEXCOORD2",
+ "TYPE_TEXCOORD3",
+ "TYPE_COLOR",
+ "TYPE_EMISSIVE",
+ "TYPE_TANGENT",
+ "TYPE_WEIGHT",
+ "TYPE_WEIGHT4",
+ "TYPE_CLOTHWEIGHT",
+ "TYPE_TEXTURE_INDEX",
+ "TYPE_MAX",
+ "TYPE_INDEX",
+};
+
U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
GL_TRIANGLES,
@@ -393,6 +404,7 @@ void LLVertexBuffer::seedPools()
{
sStreamVBOPool.seedPool();
sDynamicVBOPool.seedPool();
+ sDynamicCopyVBOPool.seedPool();
sStreamIBOPool.seedPool();
sDynamicIBOPool.seedPool();
}
@@ -402,7 +414,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (sLastMask != data_mask)
{
- bool error = false;
if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)
{
@@ -469,12 +480,11 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (gDebugSession)
{
- error = true;
gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
}
else
{
- llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ LL_ERRS() << "Bad client state! " << array[i] << " disabled." << LL_ENDL;
}
}
}
@@ -489,12 +499,11 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
- error = true;
gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
}
else
{
- llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
+ LL_ERRS() << "Bad client state! " << array[i] << " enabled." << LL_ENDL;
}
}
}
@@ -526,16 +535,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
}
- if (sLastMask & MAP_BINORMAL)
+ if (sLastMask & MAP_TANGENT)
{
- if (!(data_mask & MAP_BINORMAL))
+ if (!(data_mask & MAP_TANGENT))
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
- else if (data_mask & MAP_BINORMAL)
+ else if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -548,8 +557,10 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
//static
+static LLTrace::BlockTimerStatHandle FTM_VB_DRAW_ARRAYS("drawArrays");
void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
{
+ LL_RECORD_BLOCK_TIME(FTM_VB_DRAW_ARRAYS);
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
gGL.syncMatrices();
@@ -560,13 +571,13 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
if( count == 0 )
{
- llwarns << "Called drawArrays with 0 vertices" << llendl;
+ LL_WARNS() << "Called drawArrays with 0 vertices" << LL_ENDL;
return;
}
if( norm.size() < pos.size() )
{
- llwarns << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << llendl;
+ LL_WARNS() << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << LL_ENDL;
return;
}
@@ -594,8 +605,9 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
glNormalPointer(GL_FLOAT, 0, norm[0].mV);
}
-
+ LLGLSLShader::startProfile();
glDrawArrays(sGLMode[mode], 0, count);
+ LLGLSLShader::stopProfile(count, mode);
}
//static
@@ -632,7 +644,9 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
glVertexPointer(3, GL_FLOAT, 16, pos);
}
+ LLGLSLShader::startProfile();
glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
+ LLGLSLShader::stopProfile(num_indices, mode);
}
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -640,7 +654,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
if (start >= (U32) mNumVerts ||
end >= (U32) mNumVerts)
{
- llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << llendl;
+ LL_ERRS() << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << LL_ENDL;
}
llassert(mNumIndices >= 0);
@@ -648,7 +662,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
if (indices_offset >= (U32) mNumIndices ||
indices_offset + count > (U32) mNumIndices)
{
- llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
+ LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL;
}
if (gDebugGL && !useVBOs())
@@ -658,7 +672,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
{
if (idx[i] < start || idx[i] > end)
{
- llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl;
+ LL_ERRS() << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << LL_ENDL;
}
}
@@ -676,7 +690,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
S32 idx = (S32) (v[i][3]+0.25f);
if (idx < 0 || idx >= shader->mFeatures.mIndexedTextureChannels)
{
- llerrs << "Bad texture index found in vertex data stream." << llendl;
+ LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL;
}
}
}
@@ -696,19 +710,19 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
{
if (mGLArray != sGLRenderArray)
{
- llerrs << "Wrong vertex array bound." << llendl;
+ LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
}
}
else
{
if (mGLIndices != sGLRenderIndices)
{
- llerrs << "Wrong index buffer bound." << llendl;
+ LL_ERRS() << "Wrong index buffer bound." << LL_ENDL;
}
if (mGLBuffer != sGLRenderBuffer)
{
- llerrs << "Wrong vertex buffer bound." << llendl;
+ LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
}
}
@@ -719,22 +733,27 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
if (elem != mGLIndices)
{
- llerrs << "Wrong index buffer bound!" << llendl;
+ LL_ERRS() << "Wrong index buffer bound!" << LL_ENDL;
}
}
if (mode >= LLRender::NUM_MODES)
{
- llerrs << "Invalid draw mode: " << mode << llendl;
+ LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
return;
}
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
stop_glerror();
+ LLGLSLShader::startProfile();
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
+ LLGLSLShader::stopProfile(count, mode);
stop_glerror();
+
+
+
placeFence();
}
@@ -748,42 +767,45 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
if (indices_offset >= (U32) mNumIndices ||
indices_offset + count > (U32) mNumIndices)
{
- llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
+ LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL;
}
if (mGLArray)
{
if (mGLArray != sGLRenderArray)
{
- llerrs << "Wrong vertex array bound." << llendl;
+ LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
}
}
else
{
if (mGLIndices != sGLRenderIndices)
{
- llerrs << "Wrong index buffer bound." << llendl;
+ LL_ERRS() << "Wrong index buffer bound." << LL_ENDL;
}
if (mGLBuffer != sGLRenderBuffer)
{
- llerrs << "Wrong vertex buffer bound." << llendl;
+ LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
}
}
if (mode >= LLRender::NUM_MODES)
{
- llerrs << "Invalid draw mode: " << mode << llendl;
+ LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
return;
}
stop_glerror();
+ LLGLSLShader::startProfile();
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
+ LLGLSLShader::stopProfile(count, mode);
stop_glerror();
placeFence();
}
+static LLTrace::BlockTimerStatHandle FTM_GL_DRAW_ARRAYS("GL draw arrays");
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
@@ -794,32 +816,40 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
if (first >= (U32) mNumVerts ||
first + count > (U32) mNumVerts)
{
- llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;
+ LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL;
}
if (mGLArray)
{
if (mGLArray != sGLRenderArray)
{
- llerrs << "Wrong vertex array bound." << llendl;
+ LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
}
}
else
{
if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
{
- llerrs << "Wrong vertex buffer bound." << llendl;
+ LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
}
}
if (mode >= LLRender::NUM_MODES)
{
- llerrs << "Invalid draw mode: " << mode << llendl;
+ LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
return;
}
- stop_glerror();
- glDrawArrays(sGLMode[mode], first, count);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS);
+ stop_glerror();
+ LLGLSLShader::startProfile();
+ stop_glerror();
+ glDrawArrays(sGLMode[mode], first, count);
+ stop_glerror();
+ LLGLSLShader::stopProfile(count, mode);
+ }
+
stop_glerror();
placeFence();
}
@@ -875,6 +905,7 @@ void LLVertexBuffer::cleanupClass()
sDynamicIBOPool.cleanup();
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
+ sDynamicCopyVBOPool.cleanup();
if(sPrivatePoolp)
{
@@ -911,6 +942,8 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
+ if (ret_usage != GL_DYNAMIC_COPY_ARB)
+ {
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
ret_usage = GL_STREAM_DRAW_ARB;
@@ -920,11 +953,13 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
ret_usage = GL_DYNAMIC_DRAW_ARB;
}
}
+ }
return ret_usage;
}
-LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
+LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage)
+: LLTrace::MemTrackable<LLVertexBuffer>("LLVertexBuffer"),
LLRefCount(),
mNumVerts(0),
@@ -1061,16 +1096,23 @@ void LLVertexBuffer::waitFence() const
void LLVertexBuffer::genBuffer(U32 size)
{
+ disclaimMem(mSize);
mSize = vbo_block_size(size);
+ claimMem(mSize);
if (mUsage == GL_STREAM_DRAW_ARB)
{
mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
}
- else
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
{
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
}
+ else
+ {
+ mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize);
+ }
+
sGLCount++;
}
@@ -1150,7 +1192,9 @@ void LLVertexBuffer::createGLBuffer(U32 size)
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
+ disclaimMem(mSize);
mSize = size;
+ claimMem(mSize);
}
}
@@ -1234,7 +1278,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
if (nverts > 65536)
{
- llwarns << "Vertex buffer overflow!" << llendl;
+ LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
nverts = 65536;
}
@@ -1273,7 +1317,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
if (nverts < 0 || nindices < 0 ||
nverts > 65536)
{
- llerrs << "Bad vertex buffer allocation: " << nverts << " : " << nindices << llendl;
+ LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
}
updateNumVerts(nverts);
@@ -1284,7 +1328,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
//actually allocate space for the vertex buffer if using VBO mapping
flush();
- if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
+ if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO)
{
#if GL_ARB_vertex_array_object
mGLArray = getVAOName();
@@ -1294,7 +1338,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
}
}
-static LLFastTimer::DeclareTimer FTM_SETUP_VERTEX_ARRAY("Setup VAO");
+static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO");
void LLVertexBuffer::setupVertexArray()
{
@@ -1303,7 +1347,7 @@ void LLVertexBuffer::setupVertexArray()
return;
}
- LLFastTimer t(FTM_SETUP_VERTEX_ARRAY);
+ LL_RECORD_BLOCK_TIME(FTM_SETUP_VERTEX_ARRAY);
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
#endif
@@ -1319,7 +1363,7 @@ void LLVertexBuffer::setupVertexArray()
2, //TYPE_TEXCOORD3,
4, //TYPE_COLOR,
4, //TYPE_EMISSIVE,
- 3, //TYPE_BINORMAL,
+ 4, //TYPE_TANGENT,
1, //TYPE_WEIGHT,
4, //TYPE_WEIGHT4,
4, //TYPE_CLOTHWEIGHT,
@@ -1336,7 +1380,7 @@ void LLVertexBuffer::setupVertexArray()
GL_FLOAT, //TYPE_TEXCOORD3,
GL_UNSIGNED_BYTE, //TYPE_COLOR,
GL_UNSIGNED_BYTE, //TYPE_EMISSIVE,
- GL_FLOAT, //TYPE_BINORMAL,
+ GL_FLOAT, //TYPE_TANGENT,
GL_FLOAT, //TYPE_WEIGHT,
GL_FLOAT, //TYPE_WEIGHT4,
GL_FLOAT, //TYPE_CLOTHWEIGHT,
@@ -1353,7 +1397,7 @@ void LLVertexBuffer::setupVertexArray()
false, //TYPE_TEXCOORD3,
false, //TYPE_COLOR,
false, //TYPE_EMISSIVE,
- false, //TYPE_BINORMAL,
+ false, //TYPE_TANGENT,
false, //TYPE_WEIGHT,
false, //TYPE_WEIGHT4,
false, //TYPE_CLOTHWEIGHT,
@@ -1370,7 +1414,7 @@ void LLVertexBuffer::setupVertexArray()
GL_FALSE, //TYPE_TEXCOORD3,
GL_TRUE, //TYPE_COLOR,
GL_TRUE, //TYPE_EMISSIVE,
- GL_FALSE, //TYPE_BINORMAL,
+ GL_FALSE, //TYPE_TANGENT,
GL_FALSE, //TYPE_WEIGHT,
GL_FALSE, //TYPE_WEIGHT4,
GL_FALSE, //TYPE_CLOTHWEIGHT,
@@ -1458,8 +1502,8 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
return true;
}
-static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range");
-static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");
+static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range");
+static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER("VBO Map");
// Map for data access
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
@@ -1467,11 +1511,11 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
bindGLBuffer(true);
if (mFinal)
{
- llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
+ LL_ERRS() << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << LL_ENDL;
}
if (!useVBOs() && !mMappedData && !mMappedIndexData)
{
- llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
+ LL_ERRS() << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << LL_ENDL;
}
if (useVBOs())
@@ -1508,7 +1552,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (mVertexLocked && map_range)
{
- llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl;
+ LL_ERRS() << "Attempted to map a specific range of a buffer that was already mapped." << LL_ENDL;
}
if (!mVertexLocked)
@@ -1530,7 +1574,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
- LLFastTimer t(FTM_VBO_MAP_BUFFER_RANGE);
+ LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER_RANGE);
S32 offset = mOffsets[type] + sTypeSize[type]*index;
S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,
@@ -1550,11 +1594,11 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (size < mSize)
{
- llerrs << "Invalid buffer size." << llendl;
+ LL_ERRS() << "Invalid buffer size." << LL_ENDL;
}
}
- LLFastTimer t(FTM_VBO_MAP_BUFFER);
+ LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER);
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1565,8 +1609,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
{
if (map_range)
{
+#ifndef LL_MESA_HEADLESS
glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
else
@@ -1599,25 +1645,25 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
{
//--------------------
//print out more debug info before crash
- llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl;
+ LL_INFOS() << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << LL_ENDL;
GLint size;
glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
- llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl;
+ LL_INFOS() << "GL_ARRAY_BUFFER_ARB size is " << size << LL_ENDL;
//--------------------
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL;
}
- llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
+ LL_ERRS() << "glMapBuffer returned NULL (no vertex data)" << LL_ENDL;
}
else
{
- llerrs << "memory allocation for vertex data failed." << llendl;
+ LL_ERRS() << "memory allocation for vertex data failed." << LL_ENDL;
}
}
}
@@ -1638,19 +1684,19 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
-static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
-static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");
+static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
+static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX("IBO Map");
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
bindGLIndices(true);
if (mFinal)
{
- llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
+ LL_ERRS() << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << LL_ENDL;
}
if (!useVBOs() && !mMappedData && !mMappedIndexData)
{
- llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
+ LL_ERRS() << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << LL_ENDL;
}
if (useVBOs())
@@ -1684,7 +1730,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (mIndexLocked && map_range)
{
- llerrs << "Attempted to map a specific range of a buffer that was already mapped." << llendl;
+ LL_ERRS() << "Attempted to map a specific range of a buffer that was already mapped." << LL_ENDL;
}
if (!mIndexLocked)
@@ -1700,7 +1746,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (elem != mGLIndices)
{
- llerrs << "Wrong index buffer bound!" << llendl;
+ LL_ERRS() << "Wrong index buffer bound!" << LL_ENDL;
}
}
@@ -1717,7 +1763,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
- LLFastTimer t(FTM_VBO_MAP_INDEX_RANGE);
+ LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX_RANGE);
S32 offset = sizeof(U16)*index;
S32 length = sizeof(U16)*count;
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,
@@ -1729,7 +1775,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
else
{
#ifdef GL_ARB_map_buffer_range
- LLFastTimer t(FTM_VBO_MAP_INDEX);
+ LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX);
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1740,8 +1786,10 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
{
if (map_range)
{
+#ifndef LL_MESA_HEADLESS
glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
else
@@ -1751,7 +1799,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
else
{
- LLFastTimer t(FTM_VBO_MAP_INDEX);
+ LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX);
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
@@ -1776,14 +1824,14 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL;
}
- llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
+ LL_ERRS() << "glMapBuffer returned NULL (no index data)" << LL_ENDL;
}
else
{
- llerrs << "memory allocation for Index data failed. " << llendl;
+ LL_ERRS() << "memory allocation for Index data failed. " << LL_ENDL;
}
}
}
@@ -1802,12 +1850,12 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
}
-static LLFastTimer::DeclareTimer FTM_VBO_UNMAP("VBO Unmap");
-static LLFastTimer::DeclareTimer FTM_VBO_FLUSH_RANGE("Flush VBO Range");
+static LLTrace::BlockTimerStatHandle FTM_VBO_UNMAP("VBO Unmap");
+static LLTrace::BlockTimerStatHandle FTM_VBO_FLUSH_RANGE("Flush VBO Range");
-static LLFastTimer::DeclareTimer FTM_IBO_UNMAP("IBO Unmap");
-static LLFastTimer::DeclareTimer FTM_IBO_FLUSH_RANGE("Flush IBO Range");
+static LLTrace::BlockTimerStatHandle FTM_IBO_UNMAP("IBO Unmap");
+static LLTrace::BlockTimerStatHandle FTM_IBO_FLUSH_RANGE("Flush IBO Range");
void LLVertexBuffer::unmapBuffer()
{
@@ -1820,7 +1868,7 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedData && mVertexLocked)
{
- LLFastTimer t(FTM_VBO_UNMAP);
+ LL_RECORD_BLOCK_TIME(FTM_VBO_UNMAP);
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
@@ -1861,14 +1909,16 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sTypeSize[region.mType]*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
- LLFastTimer t(FTM_VBO_FLUSH_RANGE);
+ LL_RECORD_BLOCK_TIME(FTM_VBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
}
else if (gGLManager.mHasFlushBufferRange)
{
+#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
+#endif
}
stop_glerror();
}
@@ -1889,7 +1939,7 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedIndexData && mIndexLocked)
{
- LLFastTimer t(FTM_IBO_UNMAP);
+ LL_RECORD_BLOCK_TIME(FTM_IBO_UNMAP);
bindGLIndices();
if(!mMappable)
{
@@ -1926,7 +1976,7 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sizeof(U16)*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
- LLFastTimer t(FTM_IBO_FLUSH_RANGE);
+ LL_RECORD_BLOCK_TIME(FTM_IBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1934,8 +1984,10 @@ void LLVertexBuffer::unmapBuffer()
else if (gGLManager.mHasFlushBufferRange)
{
#ifdef GL_APPLE_flush_buffer_range
+#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
+#endif
}
stop_glerror();
}
@@ -1975,7 +2027,7 @@ template <class T,S32 type> struct VertexBufferStrider
if (ptr == NULL)
{
- llwarns << "mapIndexBuffer failed!" << llendl;
+ LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL;
return false;
}
@@ -1991,7 +2043,7 @@ template <class T,S32 type> struct VertexBufferStrider
if (ptr == NULL)
{
- llwarns << "mapVertexBuffer failed!" << llendl;
+ LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL;
return false;
}
@@ -2001,7 +2053,7 @@ template <class T,S32 type> struct VertexBufferStrider
}
else
{
- llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
+ LL_ERRS() << "VertexBufferStrider could not find valid vertex data." << LL_ENDL;
}
return false;
}
@@ -2027,14 +2079,21 @@ bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 inde
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
}
-
+bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
+{
+ return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range);
+}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
}
-bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
+bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
+{
+ return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
+}
+bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
{
- return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);
+ return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
{
@@ -2061,13 +2120,13 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
//----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_BIND_GL_ARRAY("Bind Array");
+static LLTrace::BlockTimerStatHandle FTM_BIND_GL_ARRAY("Bind Array");
bool LLVertexBuffer::bindGLArray()
{
if (mGLArray && sGLRenderArray != mGLArray)
{
{
- LLFastTimer t(FTM_BIND_GL_ARRAY);
+ LL_RECORD_BLOCK_TIME(FTM_BIND_GL_ARRAY);
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
#endif
@@ -2084,7 +2143,7 @@ bool LLVertexBuffer::bindGLArray()
return false;
}
-static LLFastTimer::DeclareTimer FTM_BIND_GL_BUFFER("Bind Buffer");
+static LLTrace::BlockTimerStatHandle FTM_BIND_GL_BUFFER("Bind Buffer");
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
{
@@ -2094,21 +2153,14 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
- LLFastTimer t(FTM_BIND_GL_BUFFER);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
+ //LL_RECORD_BLOCK_TIME(FTM_BIND_GL_BUFFER);
+
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
sVBOActive = true;
- if (mGLArray)
- {
- llassert(sGLRenderArray == mGLArray);
- //mCachedRenderBuffer = mGLBuffer;
- }
+ llassert(!mGLArray || sGLRenderArray == mGLArray);
ret = true;
}
@@ -2116,7 +2168,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
return ret;
}
-static LLFastTimer::DeclareTimer FTM_BIND_GL_INDICES("Bind Indices");
+static LLTrace::BlockTimerStatHandle FTM_BIND_GL_INDICES("Bind Indices");
bool LLVertexBuffer::bindGLIndices(bool force_bind)
{
@@ -2125,10 +2177,10 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
bool ret = false;
if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))))
{
- LLFastTimer t(FTM_BIND_GL_INDICES);
+ LL_RECORD_BLOCK_TIME(FTM_BIND_GL_INDICES);
/*if (sMapped)
{
- llerrs << "VBO bound while another VBO mapped!" << llendl;
+ LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL;
}*/
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
sGLRenderIndices = mGLIndices;
@@ -2180,7 +2232,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
U32 required = 1 << i;
if ((data_mask & required) == 0)
{
- llwarns << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << llendl;
+ LL_WARNS() << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << LL_ENDL;
}
required_mask |= required;
@@ -2189,7 +2241,38 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if ((data_mask & required_mask) != required_mask)
{
- llerrs << "Shader consumption mismatches data provision." << llendl;
+
+ U32 unsatisfied_mask = (required_mask & ~data_mask);
+ U32 i = 0;
+
+ while (i < TYPE_MAX)
+ {
+ U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
+ switch (unsatisfied_flag)
+ {
+ case MAP_VERTEX: LL_INFOS() << "Missing vert pos" << LL_ENDL; break;
+ case MAP_NORMAL: LL_INFOS() << "Missing normals" << LL_ENDL; break;
+ case MAP_TEXCOORD0: LL_INFOS() << "Missing TC 0" << LL_ENDL; break;
+ case MAP_TEXCOORD1: LL_INFOS() << "Missing TC 1" << LL_ENDL; break;
+ case MAP_TEXCOORD2: LL_INFOS() << "Missing TC 2" << LL_ENDL; break;
+ case MAP_TEXCOORD3: LL_INFOS() << "Missing TC 3" << LL_ENDL; break;
+ case MAP_COLOR: LL_INFOS() << "Missing vert color" << LL_ENDL; break;
+ case MAP_EMISSIVE: LL_INFOS() << "Missing emissive" << LL_ENDL; break;
+ case MAP_TANGENT: LL_INFOS() << "Missing tangent" << LL_ENDL; break;
+ case MAP_WEIGHT: LL_INFOS() << "Missing weight" << LL_ENDL; break;
+ case MAP_WEIGHT4: LL_INFOS() << "Missing weightx4" << LL_ENDL; break;
+ case MAP_CLOTHWEIGHT: LL_INFOS() << "Missing clothweight" << LL_ENDL; break;
+ case MAP_TEXTURE_INDEX: LL_INFOS() << "Missing tex index" << LL_ENDL; break;
+ default: LL_INFOS() << "Missing who effin knows: " << unsatisfied_flag << LL_ENDL;
+ }
+ }
+
+ if (unsatisfied_mask & (1 << TYPE_INDEX))
+ {
+ LL_INFOS() << "Missing indices" << LL_ENDL;
+ }
+
+ LL_ERRS() << "Shader consumption mismatches data provision." << LL_ENDL;
}
}
}
@@ -2209,7 +2292,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
setup = setup || bindBuffer || bindIndices;
}
- bool error = false;
if (gDebugGL && !mGLArray)
{
GLint buff;
@@ -2218,12 +2300,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = true;
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
}
else
{
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL;
}
}
@@ -2234,12 +2315,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = true;
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
}
else
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL;
}
}
}
@@ -2310,7 +2390,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
- llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
+ for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
+ {
+ U32 mask = 1 << i;
+ if (mask & data_mask && !(mask & mTypeMask))
+ { //bit set in data_mask, but not set in mTypeMask
+ LL_WARNS() << "Missing required component " << vb_type_name[i] << LL_ENDL;
+ }
+ }
+ LL_ERRS() << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << LL_ENDL;
}
if (LLGLSLShader::sNoFixedFunction)
@@ -2339,11 +2427,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
- S32 loc = TYPE_BINORMAL;
- void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]);
- glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr);
+ S32 loc = TYPE_TANGENT;
+ void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
+ glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
}
if (data_mask & MAP_TEXCOORD0)
{
@@ -2354,7 +2442,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
if (data_mask & MAP_COLOR)
{
S32 loc = TYPE_COLOR;
- void* ptr = (void*)(base + mOffsets[TYPE_COLOR]);
+ //bind emissive instead of color pointer if emissive is present
+ void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
}
if (data_mask & MAP_EMISSIVE)
@@ -2362,6 +2451,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
S32 loc = TYPE_EMISSIVE;
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+
+ if (!(data_mask & MAP_COLOR))
+ { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
+ loc = TYPE_COLOR;
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ }
}
if (data_mask & MAP_WEIGHT)
{
@@ -2421,10 +2516,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
if (data_mask & MAP_TEXCOORD0)
@@ -2447,8 +2542,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{
- llassert(mType == LLVertexBuffer::TYPE_INDEX ||
- mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);
+ mEnd = mIndex+mCount;
}