diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llrender.cpp | 2 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 862 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 19 |
3 files changed, 438 insertions, 445 deletions
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index daeb58b279..685334555a 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1821,7 +1821,7 @@ void LLRender::flush() mBuffer->getColorStrider(mColorsp, 0, count); } - //only flush the part of the + mBuffer->flush(); mBuffer->setBuffer(immediate_mask); if (mMode == LLRender::QUADS && sGLCoreProfile) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 40a96eb407..a48669a300 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -150,19 +150,18 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = //static -void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) +void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& sLastMask) { /*if (LLGLImmediate::sStarted) { llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; }*/ - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (ref_mask != data_mask) + if (sLastMask != data_mask) { - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); - + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + U32 mask[] = { MAP_VERTEX, @@ -174,6 +173,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) MAP_WEIGHT4, MAP_BINORMAL, MAP_CLOTHWEIGHT, + MAP_TEXTURE_INDEX, }; U32 type[] = @@ -187,6 +187,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) TYPE_WEIGHT4, TYPE_BINORMAL, TYPE_CLOTHWEIGHT, + TYPE_TEXTURE_INDEX-1, }; GLenum array[] = @@ -200,18 +201,20 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) 0, 0, 0, + 0, }; BOOL error = FALSE; - for (U32 i = 0; i < 9; ++i) + for (U32 i = 0; i < 10; ++i) { S32 loc = -1; - if (shader) + + if (LLGLSLShader::sNoFixedFunction) { - loc = shader->getAttribLocation(type[i]); + loc = type[i]; } - - if (ref_mask & mask[i]) + + if (sLastMask & mask[i]) { //was enabled if (!(data_mask & mask[i])) { //needs to be disabled @@ -219,12 +222,12 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glDisableVertexAttribArrayARB(loc); } - else if (!shader) + else { glDisableClientState(array[i]); } } - else if (gDebugGL && !shader && array[i]) + else if (gDebugGL && !LLGLSLShader::sNoFixedFunction && array[i]) { //needs to be enabled, make sure it was (DEBUG) if (loc < 0 && !glIsEnabled(array[i])) { @@ -248,12 +251,12 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glEnableVertexAttribArrayARB(loc); } - else if (!shader) + else { glEnableClientState(array[i]); } } - else if (!shader && array[i] && gDebugGL && glIsEnabled(array[i])) + else if (!LLGLSLShader::sNoFixedFunction && array[i] && gDebugGL && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) if (gDebugSession) { @@ -290,12 +293,13 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) for (U32 i = 0; i < 3; i++) { S32 loc = -1; - if (shader) + + if (LLGLSLShader::sNoFixedFunction) { - loc = shader->getAttribLocation(type_tc[i]); + loc = type_tc[i]; } - if (ref_mask & map_tc[i]) + if (sLastMask & map_tc[i]) { if (!(data_mask & map_tc[i])) { //disable @@ -303,7 +307,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glDisableVertexAttribArrayARB(loc); } - else if (!shader) + else { glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -317,7 +321,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glEnableVertexAttribArrayARB(loc); } - else if (!shader) + else { glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -326,9 +330,9 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) } } - if (!shader) + if (!LLGLSLShader::sNoFixedFunction) { - if (ref_mask & MAP_BINORMAL) + if (sLastMask & MAP_BINORMAL) { if (!(data_mask & MAP_BINORMAL)) { @@ -345,7 +349,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) } } - ref_mask = data_mask; + sLastMask = data_mask; } } @@ -367,12 +371,12 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con if (shader) { - S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); + S32 loc = LLVertexBuffer::TYPE_VERTEX; if (loc > -1) { glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV); } - loc = shader->getAttribLocation(LLVertexBuffer::TYPE_NORMAL); + loc = LLVertexBuffer::TYPE_NORMAL; if (loc > -1) { glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV); @@ -404,23 +408,15 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto setupClientArrays(mask); - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (shader) + if (LLGLSLShader::sNoFixedFunction) { - S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); - if (loc > -1) - { - glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); + S32 loc = LLVertexBuffer::TYPE_VERTEX; + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); - if (tc) - { - loc = shader->getAttribLocation(LLVertexBuffer::TYPE_TEXCOORD0); - if (loc > -1) - { - glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); - } - } + if (tc) + { + loc = LLVertexBuffer::TYPE_TEXCOORD0; + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); } } else @@ -470,14 +466,35 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi llassert(mRequestedNumVerts >= 0); llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - if (mGLIndices != sGLRenderIndices) + if (mGLArray) { - llerrs << "Wrong index buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } } + else + { + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } - if (mGLBuffer != sGLRenderBuffer) + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } + } + + if (gDebugGL && useVBOs()) { - llerrs << "Wrong vertex buffer bound." << llendl; + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -508,14 +525,24 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } - if (mGLIndices != sGLRenderIndices) + if (mGLArray) { - llerrs << "Wrong index buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } } - - if (mGLBuffer != sGLRenderBuffer) + else { - llerrs << "Wrong vertex buffer bound." << llendl; + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -544,9 +571,19 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; } - if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + if (mGLArray) { - llerrs << "Wrong vertex buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } + } + else + { + if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -645,7 +682,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mUsage(usage), mGLBuffer(0), mGLArray(0), - mLastMask(0), mGLIndices(0), mMappedData(NULL), mMappedIndexData(NULL), @@ -686,12 +722,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mOffsets[i] = 0; } - //initialize cached attrib pointers - for (U32 i = 0; i < LL_MAX_VERTEX_ATTRIB_LOCATION; i++) - { - mLastPointer[i] = (void*) 0xFFFFFFFF; - } - mTypeMask = typemask; mSize = 0; mAlignedOffset = 0; @@ -1065,15 +1095,98 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) createGLBuffer(); createGLIndices(); + if (gGLManager.mHasVertexArrayObject && useVBOs() && LLRender::sGLCoreProfile) { glGenVertexArrays(1, &mGLArray); + setupVertexArray(); } } sAllocatedBytes += getSize() + getIndicesSize(); } +void LLVertexBuffer::setupVertexArray() +{ + bindGLArray(); + + U32 attrib_size[] = + { + 3, //TYPE_VERTEX, + 3, //TYPE_NORMAL, + 2, //TYPE_TEXCOORD0, + 2, //TYPE_TEXCOORD1, + 2, //TYPE_TEXCOORD2, + 2, //TYPE_TEXCOORD3, + 4, //TYPE_COLOR, + 1, //TYPE_EMISSIVE, + 3, //TYPE_BINORMAL, + 1, //TYPE_WEIGHT, + 4, //TYPE_WEIGHT4, + 4, //TYPE_CLOTHWEIGHT, + }; + + U32 attrib_type[] = + { + GL_FLOAT, //TYPE_VERTEX, + GL_FLOAT, //TYPE_NORMAL, + GL_FLOAT, //TYPE_TEXCOORD0, + GL_FLOAT, //TYPE_TEXCOORD1, + GL_FLOAT, //TYPE_TEXCOORD2, + GL_FLOAT, //TYPE_TEXCOORD3, + GL_UNSIGNED_BYTE, //TYPE_COLOR, + GL_UNSIGNED_BYTE, //TYPE_EMISSIVE, + GL_FLOAT, //TYPE_BINORMAL, + GL_FLOAT, //TYPE_WEIGHT, + GL_FLOAT, //TYPE_WEIGHT4, + GL_FLOAT, //TYPE_CLOTHWEIGHT, + }; + + U32 attrib_normalized[] = + { + GL_FALSE, //TYPE_VERTEX, + GL_FALSE, //TYPE_NORMAL, + GL_FALSE, //TYPE_TEXCOORD0, + GL_FALSE, //TYPE_TEXCOORD1, + GL_FALSE, //TYPE_TEXCOORD2, + GL_FALSE, //TYPE_TEXCOORD3, + GL_TRUE, //TYPE_COLOR, + GL_TRUE, //TYPE_EMISSIVE, + GL_FALSE, //TYPE_BINORMAL, + GL_FALSE, //TYPE_WEIGHT, + GL_FALSE, //TYPE_WEIGHT4, + GL_FALSE, //TYPE_CLOTHWEIGHT, + }; + + bindGLBuffer(true); + bindGLIndices(true); + + for (U32 i = 0; i < TYPE_MAX; ++i) + { + if (mTypeMask & (1 << i)) + { + glEnableVertexAttribArrayARB(i); + glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]); + } + else + { + glDisableVertexAttribArrayARB(i); + } + } + + if (mTypeMask & MAP_VERTEX) + { //special handling for texture index + S32 loc = TYPE_TEXTURE_INDEX-1; + glEnableVertexAttribArrayARB(loc); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, sTypeSize[TYPE_VERTEX], (void*) (mOffsets[TYPE_VERTEX]+12)); + } + else + { + glDisableVertexAttribArrayARB(TYPE_TEXTURE_INDEX-1); + } + glBindVertexArray(0); +} + void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { llassert(newnverts >= 0); @@ -1149,8 +1262,13 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (mResized && useVBOs()) { - freeClientBuffer() ; - setBuffer(0); + freeClientBuffer(); + flush(); + + if (mGLArray) + { //if size changed, offsets changed + setupVertexArray(); + } } } @@ -1215,6 +1333,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) // Map for data access U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) { + bindGLBuffer(true); LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); if (mFinal) { @@ -1265,7 +1384,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (!mVertexLocked) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES); - setBuffer(0, type); mVertexLocked = TRUE; sMappedCount++; stop_glerror(); @@ -1380,6 +1498,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); + bindGLIndices(true); if (mFinal) { llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; @@ -1427,11 +1546,21 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); - setBuffer(0, TYPE_INDEX); mIndexLocked = TRUE; sMappedCount++; stop_glerror(); + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } + } + if(sDisableVBOMapping) { map_range = false; @@ -1528,19 +1657,20 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } } -void LLVertexBuffer::unmapBuffer(S32 type) +void LLVertexBuffer::unmapBuffer() { LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); - if (!useVBOs() || type == -2) + if (!useVBOs()) { return ; //nothing to unmap } bool updated_all = false ; - if (mMappedData && mVertexLocked && type != TYPE_INDEX) + if (mMappedData && mVertexLocked) { - updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating + bindGLBuffer(true); + updated_all = mIndexLocked; //both vertex and index buffers done updating if(sDisableVBOMapping) { @@ -1604,8 +1734,9 @@ void LLVertexBuffer::unmapBuffer(S32 type) sMappedCount--; } - if (mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) + if (mMappedIndexData && mIndexLocked) { + bindGLIndices(); if(sDisableVBOMapping) { if (!mMappedIndexRegions.empty()) @@ -1785,16 +1916,131 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in //---------------------------------------------------------------------------- +bool LLVertexBuffer::bindGLArray() +{ + if (mGLArray && sGLRenderArray != mGLArray) + { + glBindVertexArray(mGLArray); + sGLRenderArray = mGLArray; + return true; + } + + return false; +} + +bool LLVertexBuffer::bindGLBuffer(bool force_bind) +{ + bindGLArray(); + + bool ret = false; + + if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)))) + { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + sBindCount++; + sVBOActive = TRUE; + + if (mGLArray) + { + llassert(sGLRenderArray == mGLArray); + //mCachedRenderBuffer = mGLBuffer; + } + + ret = true; + } + + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLBuffer) + { + llerrs << "Wrong vertex buffer bound!" << llendl; + } + } + + return ret; +} + +bool LLVertexBuffer::bindGLIndices(bool force_bind) +{ + bindGLArray(); + + bool ret = false; + if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)))) + { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); + sGLRenderIndices = mGLIndices; + stop_glerror(); + sBindCount++; + sIBOActive = TRUE; + ret = true; + } + + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } + } + + return ret; +} + +void LLVertexBuffer::flush() +{ + if (useVBOs()) + { + if (mResized) + { + if (mGLBuffer) + { + stop_glerror(); + bindGLBuffer(true); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); + stop_glerror(); + } + if (mGLIndices) + { + stop_glerror(); + bindGLIndices(true); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); + stop_glerror(); + } + + mEmpty = TRUE; + mResized = FALSE; + } + + unmapBuffer(); + } +} + // Set for rendering -void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) +void LLVertexBuffer::setBuffer(U32 data_mask) { + flush(); + LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER); //set up pointers if the data mask is different ... - U32& ref_mask = mGLArray ? mLastMask : sLastMask; - BOOL setup = (ref_mask != data_mask); + BOOL setup = (sLastMask != data_mask); if (gDebugGL && data_mask != 0) - { + { //make sure data requirements are fulfilled LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; if (shader) { @@ -1823,37 +2069,25 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) if (useVBOs()) { - if (mGLArray && mGLArray != sGLRenderArray) + if (mGLArray) { - glBindVertexArray(mGLArray); - sGLRenderArray = mGLArray; + bindGLArray(); + setup = FALSE; //do NOT perform pointer setup if using VAO } - - if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) + else { - /*if (sMapped) + if (bindGLBuffer()) { - llerrs << "VBO bound while another VBO mapped!" << llendl; - }*/ - glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); - sBindCount++; - sVBOActive = TRUE; - setup = TRUE; // ... or the bound buffer changed - } - if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)) - { - /*if (sMapped) + setup = TRUE; + } + if (bindGLIndices()) { - llerrs << "VBO bound while another VBO mapped!" << llendl; - }*/ - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); - stop_glerror(); - sBindCount++; - sIBOActive = TRUE; + setup = TRUE; + } } BOOL error = FALSE; - if (gDebugGL) + if (gDebugGL && !mGLArray) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); @@ -1888,81 +2122,16 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } } - if (mResized) + + } + else + { + if (sGLRenderArray) { - if (gDebugGL) - { - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Invalid GL vertex buffer bound: " << std::endl; - } - else - { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; - } - } - - if (mGLIndices != 0) - { - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Invalid GL index buffer bound: "<< std::endl; - } - else - { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; - } - } - } - } - - if (mGLBuffer) - { - stop_glerror(); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); - stop_glerror(); - } - if (mGLIndices) - { - stop_glerror(); - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); - stop_glerror(); - } - - mEmpty = TRUE; - mResized = FALSE; - - if (data_mask != 0) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Buffer set for rendering before being filled after resize." << std::endl; - } - else - { - llerrs << "Buffer set for rendering before being filled after resize." << llendl; - } - } + glBindVertexArray(0); + sGLRenderArray = 0; } - if (error) - { - ll_fail("LLVertexBuffer::mapBuffer failed"); - } - unmapBuffer(type); - } - else - { if (mGLBuffer) { if (sVBOActive) @@ -1974,30 +2143,30 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } if (sGLRenderBuffer != mGLBuffer) { + sGLRenderBuffer = mGLBuffer; setup = TRUE; // ... or a client memory pointer changed } } - if (mGLIndices && sIBOActive) + if (mGLIndices) { - /*if (sMapped) + if (sIBOActive) { - llerrs << "VBO unbound while potentially mapped!" << llendl; - }*/ - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - sBindCount++; - sIBOActive = FALSE; + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + sBindCount++; + sIBOActive = FALSE; + } + + sGLRenderIndices = mGLIndices; } } - setupClientArrays(data_mask, ref_mask); - - if (mGLIndices) + if (!mGLArray) { - sGLRenderIndices = mGLIndices; + setupClientArrays(data_mask, sLastMask); } + if (mGLBuffer) { - sGLRenderBuffer = mGLBuffer; if (data_mask && setup) { setupVertexBuffer(data_mask); // subclass specific setup (virtual function) @@ -2007,319 +2176,140 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } // virtual (default) -void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const +void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER); stop_glerror(); U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - if ((data_mask & mTypeMask) != data_mask) + /*if ((data_mask & mTypeMask) != data_mask) { llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; - } - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - //assert that fixed function is allowed OR a shader is currently bound - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + }*/ - if (data_mask & MAP_NORMAL) + if (LLGLSLShader::sNoFixedFunction) { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_NORMAL); - } - - if (loc >= 0) + if (data_mask & MAP_NORMAL) { + S32 loc = TYPE_NORMAL; void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); - } - } - if (data_mask & MAP_TEXCOORD3) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD3); + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD3) { + S32 loc = TYPE_TEXCOORD3; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE3_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); } - } - if (data_mask & MAP_TEXCOORD2) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD2); - } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD2) { + S32 loc = TYPE_TEXCOORD2; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); } - } - if (data_mask & MAP_TEXCOORD1) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD1); - } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD1) { + S32 loc = TYPE_TEXCOORD1; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); } - } - if (data_mask & MAP_BINORMAL) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_BINORMAL); - } - - if (loc >= 0) + if (data_mask & MAP_BINORMAL) { + S32 loc = TYPE_BINORMAL; void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); } - } - if (data_mask & MAP_TEXCOORD0) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD0); - } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD0) { + S32 loc = TYPE_TEXCOORD0; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); } - else if (!shader) + if (data_mask & MAP_COLOR) { - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + S32 loc = TYPE_COLOR; + void* ptr = (void*)(base + mOffsets[TYPE_COLOR]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); } - } - if (data_mask & MAP_COLOR) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_EMISSIVE) { - loc = shader->getAttribLocation(TYPE_COLOR); + S32 loc = TYPE_EMISSIVE; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); } - - if (loc >= 0) + if (data_mask & MAP_WEIGHT) { - void* ptr = (void*)(base + mOffsets[TYPE_COLOR]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + S32 loc = TYPE_WEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); } - else if (!shader) + if (data_mask & MAP_WEIGHT4) { - glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); + S32 loc = TYPE_WEIGHT4; + void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); } - } - if (data_mask & MAP_EMISSIVE) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_CLOTHWEIGHT) { - loc = shader->getAttribLocation(TYPE_EMISSIVE); + S32 loc = TYPE_CLOTHWEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); } - - if (loc >= 0) + if (data_mask & MAP_TEXTURE_INDEX) { - void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + S32 loc = TYPE_TEXTURE_INDEX-1; //hack, texture index attrib location is off by one + void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } - } - if (data_mask & MAP_WEIGHT) + if (data_mask & MAP_VERTEX) + { + S32 loc = TYPE_VERTEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } + } + else { - S32 loc = -1; - if (shader) + if (data_mask & MAP_NORMAL) { - loc = shader->getAttribLocation(TYPE_WEIGHT); + glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); } - - if (loc > -1) + if (data_mask & MAP_TEXCOORD3) { - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - } - - if (data_mask & MAP_WEIGHT4) - { - if (shader) + if (data_mask & MAP_TEXCOORD2) { - S32 loc = shader->getAttribLocation(TYPE_WEIGHT4); - if (loc > -1) - { - void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - } - - if (data_mask & MAP_CLOTHWEIGHT) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_TEXCOORD1) { - loc = shader->getAttribLocation(TYPE_CLOTHWEIGHT); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - - if (loc > -1) + if (data_mask & MAP_BINORMAL) { - void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - } - if (data_mask & MAP_VERTEX) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_TEXCOORD0) { - loc = shader->getAttribLocation(TYPE_VERTEX); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); } - - if (loc >= 0) + if (data_mask & MAP_COLOR) { - if (data_mask & MAP_TEXTURE_INDEX) - { - glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - else - { - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } + glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); } - else if (!shader) + if (data_mask & MAP_VERTEX) { - if (data_mask & MAP_TEXTURE_INDEX) - { - glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - else - { - glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - } + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } } llglassertok(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 60cfde39f5..eba10dbaa5 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -139,6 +139,7 @@ public: // 3 - modify LLVertexBuffer::setupVertexBuffer // 4 - modify LLVertexBuffer::setupClientArray // 5 - modify LLViewerShaderMgr::mReservedAttribs + // 6 - update LLVertexBuffer::setupVertexArray enum { TYPE_VERTEX, TYPE_NORMAL, @@ -154,10 +155,9 @@ public: TYPE_WEIGHT4, TYPE_CLOTHWEIGHT, TYPE_MAX, - TYPE_INDEX, - //no actual additional data, but indicates position.w is texture index TYPE_TEXTURE_INDEX, + TYPE_INDEX, }; enum { MAP_VERTEX = (1<<TYPE_VERTEX), @@ -181,10 +181,14 @@ protected: virtual ~LLVertexBuffer(); // use unref() - virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer() + virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer() + void setupVertexArray(); void genBuffer(); void genIndices(); + bool bindGLBuffer(bool force_bind = false); + bool bindGLIndices(bool force_bind = false); + bool bindGLArray(); void releaseBuffer(); void releaseIndices(); void createGLBuffer(); @@ -194,7 +198,7 @@ protected: void updateNumVerts(S32 nverts); void updateNumIndices(S32 nindices); virtual BOOL useVBOs() const; - void unmapBuffer(S32 type); + void unmapBuffer(); void freeClientBuffer() ; void allocateClientVertexBuffer() ; void allocateClientIndexBuffer() ; @@ -207,7 +211,8 @@ public: U8* mapIndexBuffer(S32 index, S32 count, bool map_range); // set for rendering - virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0 + virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 + void flush(); //flush pending data to GL memory // allocate buffer void allocateBuffer(S32 nverts, S32 nindices, bool create); virtual void resizeBuffer(S32 newnverts, S32 newnindices); @@ -273,9 +278,7 @@ protected: U32 mGLBuffer; // GL VBO handle U32 mGLIndices; // GL IBO handle U32 mGLArray; // GL VAO handle - U32 mLastMask; - mutable void* mLastPointer[LL_MAX_VERTEX_ATTRIB_LOCATION]; - + U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory |