diff options
author | Dave Parks <davep@lindenlab.com> | 2023-01-09 13:05:32 -0600 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2023-01-09 13:05:32 -0600 |
commit | b3fc82ff1da0c869f0b1dd841647a120a1ae56af (patch) | |
tree | 165ef606a17cb1263bc7aaa61065ed5e39b4f3b6 /indra | |
parent | 9add99b31aabf00af78cb4b999c3cbbff1a36847 (diff) |
SL-18869 Optimizations -- decruftify LLVertexBuffer and make an optimal "renderShadowSimple" utility function for pushing vertex buffers only.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 667 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 35 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 73 | ||||
-rw-r--r-- | indra/newview/pipeline.h | 2 |
4 files changed, 197 insertions, 580 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 6122681c09..7b8f85acba 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -436,12 +436,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) if (sLastMask != data_mask) { - if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30) - { - //make sure texture index is disabled - data_mask = data_mask & ~MAP_TEXTURE_INDEX; - } - for (U32 i = 0; i < TYPE_MAX; ++i) { S32 loc = i; @@ -584,33 +578,22 @@ void LLVertexBuffer::setLabel(const char* label) { void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const { validateRange(start, end, count, indices_offset); - mMappable = false; gGL.syncMatrices(); llassert(mNumVerts >= 0); llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); - if (mGLArray) + if (mGLIndices != sGLRenderIndices) { - if (mGLArray != sGLRenderArray) - { - LL_ERRS() << "Wrong vertex array bound." << LL_ENDL; - } + LL_ERRS() << "Wrong index buffer bound." << LL_ENDL; } - else - { - if (mGLIndices != sGLRenderIndices) - { - LL_ERRS() << "Wrong index buffer bound." << LL_ENDL; - } - if (mGLBuffer != sGLRenderBuffer) - { - LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; - } + if (mGLBuffer != sGLRenderBuffer) + { + LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; } - if (gDebugGL && !mGLArray && useVBOs()) + if (gDebugGL && useVBOs()) { GLint elem = 0; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); @@ -635,15 +618,10 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi idx); LLGLSLShader::stopProfile(count, mode); stop_glerror(); - - - - placeFence(); } void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const { - mMappable = false; gGL.syncMatrices(); U16* idx = ((U16*)getIndicesPointer()) + indices_offset; @@ -655,7 +633,6 @@ void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); - mMappable = false; gGL.syncMatrices(); llassert(mNumIndices >= 0); @@ -665,24 +642,15 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL; } - if (mGLArray) + + if (mGLIndices != sGLRenderIndices) { - if (mGLArray != sGLRenderArray) - { - LL_ERRS() << "Wrong vertex array bound." << LL_ENDL; - } + LL_ERRS() << "Wrong index buffer bound." << LL_ENDL; } - else - { - if (mGLIndices != sGLRenderIndices) - { - LL_ERRS() << "Wrong index buffer bound." << LL_ENDL; - } - if (mGLBuffer != sGLRenderBuffer) - { - LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; - } + if (mGLBuffer != sGLRenderBuffer) + { + LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; } if (mode >= LLRender::NUM_MODES) @@ -697,7 +665,6 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const ((U16*) getIndicesPointer()) + indices_offset); LLGLSLShader::stopProfile(count, mode); stop_glerror(); - placeFence(); } @@ -705,7 +672,6 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); - mMappable = false; gGL.syncMatrices(); #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -716,19 +682,9 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL; } - if (mGLArray) + if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) { - if (mGLArray != sGLRenderArray) - { - LL_ERRS() << "Wrong vertex array bound." << LL_ENDL; - } - } - else - { - if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) - { - LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; - } + LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; } if (mode >= LLRender::NUM_MODES) @@ -745,7 +701,6 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const LLGLSLShader::stopProfile(count, mode); stop_glerror(); - placeFence(); } //static @@ -849,15 +804,12 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) mNumVerts(0), mNumIndices(0), - mAlignedOffset(0), - mAlignedIndexOffset(0), mSize(0), mIndicesSize(0), mTypeMask(typemask), mUsage(LLVertexBuffer::determineUsage(usage)), mGLBuffer(0), mGLIndices(0), - mGLArray(0), mMappedData(NULL), mMappedIndexData(NULL), mMappedDataUsingVBOs(false), @@ -865,12 +817,8 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) mVertexLocked(false), mIndexLocked(false), mFinal(false), - mEmpty(true), - mMappable(false), - mFence(NULL) + mEmpty(true) { - mMappable = (mUsage == GL_DYNAMIC_DRAW && !sDisableVBOMapping); - //zero out offsets for (U32 i = 0; i < TYPE_MAX; i++) { @@ -931,22 +879,8 @@ LLVertexBuffer::~LLVertexBuffer() destroyGLBuffer(); destroyGLIndices(); - if (mGLArray) - { - releaseVAOName(mGLArray); - } - sCount--; - if (mFence) - { - // Sanity check. We have weird crashes in this destructor (on delete). Yet mFence is disabled. - // TODO: mFence was added in scope of SH-2038, but was never enabled, consider removing mFence. - LL_ERRS() << "LLVertexBuffer destruction failed" << LL_ENDL; - delete mFence; - mFence = NULL; - } - sVertexCount -= mNumVerts; sIndexCount -= mNumIndices; @@ -960,27 +894,6 @@ LLVertexBuffer::~LLVertexBuffer() } }; -void LLVertexBuffer::placeFence() const -{ - /*if (!mFence && useVBOs()) - { - mFence = new LLGLSyncFence(); - } - - if (mFence) - { - mFence->placeFence(); - }*/ -} - -void LLVertexBuffer::waitFence() const -{ - /*if (mFence) - { - mFence->wait(); - }*/ -} - //---------------------------------------------------------------------------- void LLVertexBuffer::genBuffer(U32 size) @@ -1239,144 +1152,11 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { //actually allocate space for the vertex buffer if using VBO mapping flush(); //unmap - - if (useVBOs() && sUseVAO) - { - mGLArray = getVAOName(); - setupVertexArray(); - } } return success; } -void LLVertexBuffer::setupVertexArray() -{ - if (!mGLArray) - { - return; - } - - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - glBindVertexArray(mGLArray); - sGLRenderArray = mGLArray; - - static const U32 attrib_size[] = - { - 3, //TYPE_VERTEX, - 3, //TYPE_NORMAL, - 2, //TYPE_TEXCOORD0, - 2, //TYPE_TEXCOORD1, - 2, //TYPE_TEXCOORD2, - 2, //TYPE_TEXCOORD3, - 4, //TYPE_COLOR, - 4, //TYPE_EMISSIVE, - 4, //TYPE_TANGENT, - 1, //TYPE_WEIGHT, - 4, //TYPE_WEIGHT4, - 4, //TYPE_CLOTHWEIGHT, - 1, //TYPE_TEXTURE_INDEX - }; - - static const 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_TANGENT, - GL_FLOAT, //TYPE_WEIGHT, - GL_FLOAT, //TYPE_WEIGHT4, - GL_FLOAT, //TYPE_CLOTHWEIGHT, - GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX - }; - - static const bool attrib_integer[] = - { - false, //TYPE_VERTEX, - false, //TYPE_NORMAL, - false, //TYPE_TEXCOORD0, - false, //TYPE_TEXCOORD1, - false, //TYPE_TEXCOORD2, - false, //TYPE_TEXCOORD3, - false, //TYPE_COLOR, - false, //TYPE_EMISSIVE, - false, //TYPE_TANGENT, - false, //TYPE_WEIGHT, - false, //TYPE_WEIGHT4, - false, //TYPE_CLOTHWEIGHT, - true, //TYPE_TEXTURE_INDEX - }; - - static const 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_TANGENT, - GL_FALSE, //TYPE_WEIGHT, - GL_FALSE, //TYPE_WEIGHT4, - GL_FALSE, //TYPE_CLOTHWEIGHT, - GL_FALSE, //TYPE_TEXTURE_INDEX - }; - - bindGLBuffer(true); - bindGLIndices(true); - - for (U32 i = 0; i < TYPE_MAX; ++i) - { - if (mTypeMask & (1 << i)) - { - glEnableVertexAttribArray(i); - - if (attrib_integer[i]) - { - //glVertexattribIPointer requires GLSL 1.30 or later - if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) - { - // nat 2018-10-24: VS 2017 also notices the issue - // described below, and warns even with reinterpret_cast. - // Cast via intptr_t to make it painfully obvious to the - // compiler that we're doing this intentionally. - glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], - reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i]))); - } - } - else - { - // nat 2016-12-16: With 64-bit clang compile, the compiler - // produces an error if we simply cast mOffsets[i] -- an S32 - // -- to (GLvoid *), the type of the parameter. It correctly - // points out that there's no way an S32 could fit a real - // pointer value. Ruslan asserts that in this case the last - // param is interpreted as an array data offset within the VBO - // rather than as an actual pointer, so it's okay. - glVertexAttribPointer(i, attrib_size[i], attrib_type[i], - attrib_normalized[i], sTypeSize[i], - reinterpret_cast<GLvoid*>(intptr_t(mOffsets[i]))); - } - } - else - { - glDisableVertexAttribArray(i); - } - } - - //draw a dummy triangle to set index array pointer - //glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, NULL); - - unbind(); -} - bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { llassert(newnverts >= 0); @@ -1390,11 +1170,6 @@ bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (useVBOs()) { flush(); //unmap - - if (mGLArray) - { //if size changed, offsets changed - setupVertexArray(); - } } return success; @@ -1443,34 +1218,31 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (useVBOs()) { - if (!mMappable) + if (count == -1) { - if (count == -1) - { - count = mNumVerts-index; - } + count = mNumVerts-index; + } - bool mapped = false; - //see if range is already mapped - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + bool mapped = false; + //see if range is already mapped + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + MappedRegion& region = mMappedVertexRegions[i]; + if (region.mType == type) { - MappedRegion& region = mMappedVertexRegions[i]; - if (region.mType == type) + if (expand_region(region, index, count)) { - if (expand_region(region, index, count)) - { - mapped = true; - break; - } + mapped = true; + break; } } + } - if (!mapped) - { - //not already mapped, map new region - MappedRegion region(type, mMappable && map_range ? -1 : index, count); - mMappedVertexRegions.push_back(region); - } + if (!mapped) + { + //not already mapped, map new region + MappedRegion region(type, index, count); + mMappedVertexRegions.push_back(region); } if (mVertexLocked && map_range) @@ -1484,48 +1256,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran sMappedCount++; stop_glerror(); - if(!mMappable) - { - map_range = false; - } - else - { - U8* src = NULL; - waitFence(); - if (map_range) - { - S32 offset = mOffsets[type] + sTypeSize[type]*index; - S32 length = (sTypeSize[type]*count+0xF) & ~0xF; - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); - } - else - { - if (gDebugGL) - { - GLint size = 0; - glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - - if (size < mSize) - { - LL_ERRS() << "Invalid buffer size." << LL_ENDL; - } - } - - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); - } - - llassert(src != NULL); - - mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src); - mAlignedOffset = mMappedData - src; - - stop_glerror(); - } + map_range = false; if (!mMappedData) { @@ -1533,31 +1264,9 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran //check the availability of memory LLMemory::logMemoryInfo(true); - - if(mMappable) - { - //-------------------- - //print out more debug info before crash - LL_INFOS() << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << LL_ENDL; - GLint size; - glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - LL_INFOS() << "GL_ARRAY_BUFFER size is " << size << LL_ENDL; - //-------------------- - - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); - if ((GLuint)buff != mGLBuffer) - { - LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL; - } + + LL_ERRS() << "memory allocation for vertex data failed." << LL_ENDL; - - LL_ERRS() << "glMapBuffer returned NULL (no vertex data)" << LL_ENDL; - } - else - { - LL_ERRS() << "memory allocation for vertex data failed." << LL_ENDL; - } } } } @@ -1566,14 +1275,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran map_range = false; } - if (map_range && mMappable) - { - return mMappedData; - } - else - { - return mMappedData+mOffsets[type]+sTypeSize[type]*index; - } + return mMappedData+mOffsets[type]+sTypeSize[type]*index; } @@ -1592,32 +1294,30 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (useVBOs()) { - if (!mMappable) + if (count == -1) { - if (count == -1) - { - count = mNumIndices-index; - } + count = mNumIndices-index; + } - bool mapped = false; - //see if range is already mapped - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + bool mapped = false; + //see if range is already mapped + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + { + MappedRegion& region = mMappedIndexRegions[i]; + if (expand_region(region, index, count)) { - MappedRegion& region = mMappedIndexRegions[i]; - if (expand_region(region, index, count)) - { - mapped = true; - break; - } + mapped = true; + break; } + } - if (!mapped) - { - //not already mapped, map new region - MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count); - mMappedIndexRegions.push_back(region); - } + if (!mapped) + { + //not already mapped, map new region + MappedRegion region(TYPE_INDEX, index, count); + mMappedIndexRegions.push_back(region); } + if (mIndexLocked && map_range) { @@ -1641,36 +1341,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } } - if(!mMappable) - { - map_range = false; - } - else - { - U8* src = NULL; - waitFence(); - if (map_range) - { - S32 offset = sizeof(U16)*index; - S32 length = sizeof(U16)*count; - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); - } - else - { - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); - } - - llassert(src != NULL); - - mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src); - mAlignedIndexOffset = mMappedIndexData - src; - stop_glerror(); - } + map_range = false; } if (!mMappedIndexData) @@ -1678,21 +1349,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) log_glerror(); LLMemory::logMemoryInfo(true); - if(mMappable) - { - GLint buff; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); - if ((GLuint)buff != mGLIndices) - { - LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL; - } - - LL_ERRS() << "glMapBuffer returned NULL (no index data)" << LL_ENDL; - } - else - { - LL_ERRS() << "memory allocation for Index data failed. " << LL_ENDL; - } + LL_ERRS() << "memory allocation for Index data failed. " << LL_ENDL; } } else @@ -1700,14 +1357,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) map_range = false; } - if (map_range && mMappable) - { - return mMappedIndexData; - } - else - { - return mMappedIndexData + sizeof(U16)*index; - } + return mMappedIndexData + sizeof(U16)*index; } void LLVertexBuffer::unmapBuffer() @@ -1725,66 +1375,41 @@ void LLVertexBuffer::unmapBuffer() bindGLBuffer(true); updated_all = mIndexLocked; //both vertex and index buffers done updating - if(!mMappable) + if (!mMappedVertexRegions.empty()) { - if (!mMappedVertexRegions.empty()) + stop_glerror(); + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { - stop_glerror(); - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + const MappedRegion& region = mMappedVertexRegions[i]; + S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; + S32 length = sTypeSize[region.mType]*region.mCount; + if (mSize >= length + offset) { - const MappedRegion& region = mMappedVertexRegions[i]; - S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; - S32 length = sTypeSize[region.mType]*region.mCount; - if (mSize >= length + offset) - { - glBufferSubData(GL_ARRAY_BUFFER, offset, length, (U8*)mMappedData + offset); - } - else - { - GLint size = 0; - glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - LL_WARNS() << "Attempted to map regions to a buffer that is too small, " - << "mapped size: " << mSize - << ", gl buffer size: " << size - << ", length: " << length - << ", offset: " << offset - << LL_ENDL; - } - stop_glerror(); + glBufferSubData(GL_ARRAY_BUFFER, offset, length, (U8*)mMappedData + offset); + } + else + { + GLint size = 0; + glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); + LL_WARNS() << "Attempted to map regions to a buffer that is too small, " + << "mapped size: " << mSize + << ", gl buffer size: " << size + << ", length: " << length + << ", offset: " << offset + << LL_ENDL; } - - mMappedVertexRegions.clear(); - } - else - { - stop_glerror(); - glBufferSubData(GL_ARRAY_BUFFER, 0, getSize(), (U8*) mMappedData); stop_glerror(); } + + mMappedVertexRegions.clear(); } else { - if (!mMappedVertexRegions.empty()) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - const MappedRegion& region = mMappedVertexRegions[i]; - S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; - S32 length = sTypeSize[region.mType]*region.mCount; - glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); - } - - mMappedVertexRegions.clear(); - } - stop_glerror(); - glUnmapBuffer(GL_ARRAY_BUFFER); + glBufferSubData(GL_ARRAY_BUFFER, 0, getSize(), (U8*) mMappedData); stop_glerror(); - - mMappedData = NULL; } - + mVertexLocked = false; sMappedCount--; } @@ -1793,64 +1418,41 @@ void LLVertexBuffer::unmapBuffer() { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index"); bindGLIndices(); - if(!mMappable) + + if (!mMappedIndexRegions.empty()) { - if (!mMappedIndexRegions.empty()) + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + const MappedRegion& region = mMappedIndexRegions[i]; + S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; + S32 length = sizeof(U16)*region.mCount; + if (mIndicesSize >= length + offset) { - const MappedRegion& region = mMappedIndexRegions[i]; - S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; - S32 length = sizeof(U16)*region.mCount; - if (mIndicesSize >= length + offset) - { - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, (U8*) mMappedIndexData+offset); - } - else - { - GLint size = 0; - glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - LL_WARNS() << "Attempted to map regions to a buffer that is too small, " - << "mapped size: " << mIndicesSize - << ", gl buffer size: " << size - << ", length: " << length - << ", offset: " << offset - << LL_ENDL; - } - stop_glerror(); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, (U8*) mMappedIndexData+offset); + } + else + { + GLint size = 0; + glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); + LL_WARNS() << "Attempted to map regions to a buffer that is too small, " + << "mapped size: " << mIndicesSize + << ", gl buffer size: " << size + << ", length: " << length + << ", offset: " << offset + << LL_ENDL; } - - mMappedIndexRegions.clear(); - } - else - { - stop_glerror(); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, getIndicesSize(), (U8*) mMappedIndexData); stop_glerror(); } + + mMappedIndexRegions.clear(); } else { - if (!mMappedIndexRegions.empty()) - { - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); - const MappedRegion& region = mMappedIndexRegions[i]; - S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; - S32 length = sizeof(U16)*region.mCount; - glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); - stop_glerror(); - } - - mMappedIndexRegions.clear(); - } - - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - mMappedIndexData = NULL; + stop_glerror(); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, getIndicesSize(), (U8*) mMappedIndexData); + stop_glerror(); } - + mIndexLocked = false; sMappedCount--; } @@ -1969,30 +1571,8 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in //---------------------------------------------------------------------------- -bool LLVertexBuffer::bindGLArray() -{ - if (mGLArray && sGLRenderArray != mGLArray) - { - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - glBindVertexArray(mGLArray); - sGLRenderArray = mGLArray; - } - - //really shouldn't be necessary, but some drivers don't properly restore the - //state of GL_ELEMENT_ARRAY_BUFFER_BINDING - bindGLIndices(); - - return true; - } - - return false; -} - bool LLVertexBuffer::bindGLBuffer(bool force_bind) { - bindGLArray(); - bool ret = false; if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)))) @@ -2002,9 +1582,6 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind) sGLRenderBuffer = mGLBuffer; sBindCount++; sVBOActive = true; - - llassert(!mGLArray || sGLRenderArray == mGLArray); - ret = true; } @@ -2029,9 +1606,8 @@ bool LLVertexBuffer::bindGLBufferFast() bool LLVertexBuffer::bindGLIndices(bool force_bind) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - bindGLArray(); - bool ret = false; + bool ret = false; if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)))) { /*if (sMapped) @@ -2151,20 +1727,12 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (useVBOs()) { - if (mGLArray) - { - bindGLArray(); - setup = false; //do NOT perform pointer setup if using VAO - } - else - { - const bool bindBuffer = bindGLBuffer(); - const bool bindIndices = bindGLIndices(); + const bool bindBuffer = bindGLBuffer(); + const bool bindIndices = bindGLIndices(); - setup = setup || bindBuffer || bindIndices; - } + setup = setup || bindBuffer || bindIndices; - if (gDebugGL && !mGLArray) + if (gDebugGL) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); @@ -2237,11 +1805,8 @@ void LLVertexBuffer::setBuffer(U32 data_mask) } } - if (!mGLArray) - { - setupClientArrays(data_mask); - } - + setupClientArrays(data_mask); + if (mGLBuffer) { if (data_mask && setup) @@ -2284,7 +1849,7 @@ void LLVertexBuffer::setBufferFast(U32 data_mask) void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { stop_glerror(); - U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; + U8* base = useVBOs() ? nullptr: mMappedData; if (gDebugGL && ((data_mask & mTypeMask) != data_mask)) { @@ -2390,8 +1955,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) } void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) - { - U8* base = (U8*)mAlignedOffset; +{ + U8* base = nullptr; if (data_mask & MAP_NORMAL) { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 4d73cf07c0..bb7460fb2a 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -166,8 +166,7 @@ public: // 4 - modify LLVertexBuffer::setupVertexBuffer // 5 - modify LLVertexBuffer::setupVertexBufferFast // 6 - modify LLViewerShaderMgr::mReservedAttribs - // 7 - update LLVertexBuffer::setupVertexArray - + // clang-format off enum { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms() TYPE_VERTEX = 0, // "position" @@ -212,15 +211,12 @@ protected: virtual void setupVertexBuffer(U32 data_mask); void setupVertexBufferFast(U32 data_mask); - void setupVertexArray(); - void genBuffer(U32 size); void genIndices(U32 size); bool bindGLBuffer(bool force_bind = false); bool bindGLBufferFast(); bool bindGLIndices(bool force_bind = false); bool bindGLIndicesFast(); - bool bindGLArray(); void releaseBuffer(); void releaseIndices(); bool createGLBuffer(U32 size); @@ -282,8 +278,8 @@ public: S32 getNumVerts() const { return mNumVerts; } S32 getNumIndices() const { return mNumIndices; } - U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; } - U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; } + U8* getIndicesPointer() const { return useVBOs() ? nullptr : mMappedIndexData; } + U8* getVerticesPointer() const { return useVBOs() ? nullptr : mMappedData; } U32 getTypeMask() const { return mTypeMask; } bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); } S32 getSize() const; @@ -292,7 +288,7 @@ public: U8* getMappedIndices() const { return mMappedIndexData; } S32 getOffset(S32 type) const { return mOffsets[type]; } S32 getUsage() const { return mUsage; } - bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW) ? true : false; } + bool isWriteable() const { return (mUsage == GL_STREAM_DRAW) ? true : false; } void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; @@ -310,21 +306,19 @@ public: protected: + U32 mGLBuffer; // GL VBO handle + U32 mGLIndices; // GL IBO handle + + U32 mTypeMask; + S32 mNumVerts; // Number of vertices allocated S32 mNumIndices; // Number of indices allocated - - ptrdiff_t mAlignedOffset; - ptrdiff_t mAlignedIndexOffset; + S32 mSize; S32 mIndicesSize; - U32 mTypeMask; const S32 mUsage; // GL usage - - U32 mGLBuffer; // GL VBO handle - U32 mGLIndices; // GL IBO handle - U32 mGLArray; // GL VAO handle - + U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) @@ -335,18 +329,11 @@ protected: U32 mFinal : 1; // if true, buffer can not be mapped again U32 mEmpty : 1; // if true, client buffer is empty (or NULL). Old values have been discarded. - mutable bool mMappable; // if true, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData) - S32 mOffsets[TYPE_MAX]; std::vector<MappedRegion> mMappedVertexRegions; std::vector<MappedRegion> mMappedIndexRegions; - mutable LLGLFence* mFence; - - void placeFence() const; - void waitFence() const; - static S32 determineUsage(S32 usage); private: diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4edc092271..10c271cddc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7396,6 +7396,49 @@ void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_text gGLLastMatrix = NULL; } +void LLPipeline::renderShadowSimple(U32 type) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + + LLVertexBuffer* last_vb = nullptr; + + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); + + for (LLCullResult::drawinfo_iterator i = begin; i != end; ) + { + LLDrawInfo& params = **i; + + ++i; + + if (i != end) + { + _mm_prefetch((char*) (*i)->mVertexBuffer.get(), _MM_HINT_NTA); + + auto* ni = i + 1; + if (ni != end) + { + _mm_prefetch((char*)*ni, _MM_HINT_NTA); + } + } + + LLVertexBuffer* vb = params.mVertexBuffer; + if (vb != last_vb) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("push shadow simple"); + mSimplePool->applyModelMatrix(params); + vb->setBufferFast(LLVertexBuffer::MAP_VERTEX); + vb->drawRangeFast(LLRender::TRIANGLES, 0, vb->getNumVerts()-1, vb->getNumIndices(), 0); + vb = last_vb; + } + } + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; +} + void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, bool rigged) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -9561,8 +9604,16 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLEnvironment& environment = LLEnvironment::instance(); - LLVertexBuffer::unbind(); + struct CompareVertexBuffer + { + bool operator()(const LLDrawInfo* const& lhs, const LLDrawInfo* const& rhs) + { + return lhs->mVertexBuffer > rhs->mVertexBuffer; + } + }; + + LLVertexBuffer::unbind(); for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged { bool rigged = j == 1; @@ -9589,17 +9640,29 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); LL_PROFILE_GPU_ZONE("shadow simple"); gGL.getTexUnit(0)->disable(); - for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i) + + for (U32 type : types) { - renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged); + if (rigged) + { + renderObjects(type, LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged); + } + else + { + //{ sort should not be necessary because each entry in sCull should already + // be sorted by vertex buffer + // LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("sort shadow simple"); + // std::sort(sCull->beginRenderMap(type), sCull->endRenderMap(type), CompareVertexBuffer()); + //} + renderShadowSimple(type); + } } + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); if (!use_shader) { gOcclusionProgram.unbind(); } - - } if (use_shader) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index bac68cfff0..c698374c8b 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -272,6 +272,8 @@ public: void forAllVisibleDrawables(void (*func)(LLDrawable*)); void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderShadowSimple(U32 type); + void renderAlphaObjects(U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); |