diff options
Diffstat (limited to 'indra/llrender/llvertexbuffer.cpp')
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 226 |
1 files changed, 144 insertions, 82 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 2eb7c21f77..b522eb5218 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -37,6 +37,10 @@ #include "llglslshader.h" #include "llmemory.h" +#include "llcontrol.h" + +extern LLControlGroup gSavedSettings; + //Next Highest Power Of Two //helper function, returns first number > v that is a power of 2, or v if v is already a power of 2 U32 nhpo2(U32 v) @@ -290,7 +294,7 @@ static GLuint gen_buffer() #define ANALYZE_VBO_POOL 0 -#if LL_DARWIN +#if 0 // LL_DARWIN // experimental -- disable VBO pooling on OS X and use glMapBuffer class LLVBOPool @@ -351,6 +355,8 @@ class LLVBOPool public: typedef std::chrono::steady_clock::time_point Time; + U32 mMappingMode; + struct Entry { U8* mData; @@ -358,8 +364,16 @@ public: Time mAge; }; + /* + LLVBOPool() + { + + } + */ + ~LLVBOPool() { + if(mMappingMode > 1) return; clear(); } @@ -378,7 +392,8 @@ public: U64 getVramBytesUsed() { - return mAllocated + mReserved; + if(mMappingMode > 1) return mAllocated; + else return mAllocated + mReserved; } // increase the size to some common value (e.g. a power of two) to increase hit rate @@ -400,6 +415,20 @@ public: llassert(data == nullptr); // non null data indicates a buffer that wasn't freed llassert(size >= 2); // any buffer size smaller than a single index is nonsensical + if(mMappingMode > 1) + { + mAllocated += size; + + { //allocate a new buffer + LL_PROFILE_GPU_ZONE("vbo alloc"); + // ON OS X, we don't allocate a VBO until the last possible moment + // in unmapBuffer + data = (U8*) ll_aligned_malloc_16(size); + //STOP_GLERROR; + } + return; + } + mDistributed += size; adjustSize(size); mAllocated += size; @@ -453,6 +482,25 @@ public: LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER); llassert(size >= 2); + + if(mMappingMode > 1) + { + if (data) + { + ll_aligned_free_16(data); + } + + mAllocated -= size; + //STOP_GLERROR; + if (name) + { + glDeleteBuffers(1, &name); + } + //STOP_GLERROR; + + return; + } + llassert(name != 0); llassert(data != nullptr); @@ -584,6 +632,7 @@ U32 LLVertexBuffer::sGLRenderIndices = 0; U32 LLVertexBuffer::sLastMask = 0; U32 LLVertexBuffer::sVertexCount = 0; +U32 LLVertexBuffer::sMappingMode = 0; //NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware const U32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = @@ -836,6 +885,9 @@ void LLVertexBuffer::initClass(LLWindow* window) { llassert(sVBOPool == nullptr); sVBOPool = new LLVBOPool(); + sVBOPool->mMappingMode = sMappingMode; + + //LL_INFOS() << "milo sVBOPool intialized with " << sMappingMode << LL_ENDL; #if ENABLE_GL_WORK_QUEUE sQueue = new GLWorkQueue(); @@ -1144,28 +1196,30 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde count = mNumVerts - index; } -#if !LL_DARWIN - U32 start = mOffsets[type] + sTypeSize[type] * index; - U32 end = start + sTypeSize[type] * count-1; - - bool flagged = false; - // flag region as mapped - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + if(sMappingMode < 2) { - MappedRegion& region = mMappedVertexRegions[i]; - if (expand_region(region, start, end)) + U32 start = mOffsets[type] + sTypeSize[type] * index; + U32 end = start + sTypeSize[type] * count-1; + + bool flagged = false; + // flag region as mapped + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { - flagged = true; - break; + MappedRegion& region = mMappedVertexRegions[i]; + if (expand_region(region, start, end)) + { + flagged = true; + break; + } } - } - if (!flagged) - { - //didn't expand an existing region, make a new one - mMappedVertexRegions.push_back({ start, end }); + if (!flagged) + { + //didn't expand an existing region, make a new one + mMappedVertexRegions.push_back({ start, end }); + } } -#endif + return mMappedData+mOffsets[type]+sTypeSize[type]*index; } @@ -1179,28 +1233,29 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) count = mNumIndices-index; } -#if !LL_DARWIN - U32 start = sizeof(U16) * index; - U32 end = start + sizeof(U16) * count-1; - - bool flagged = false; - // flag region as mapped - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + if(sMappingMode < 2) { - MappedRegion& region = mMappedIndexRegions[i]; - if (expand_region(region, start, end)) + U32 start = sizeof(U16) * index; + U32 end = start + sizeof(U16) * count-1; + + bool flagged = false; + // flag region as mapped + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { - flagged = true; - break; + MappedRegion& region = mMappedIndexRegions[i]; + if (expand_region(region, start, end)) + { + flagged = true; + break; + } } - } - if (!flagged) - { - //didn't expand an existing region, make a new one - mMappedIndexRegions.push_back({ start, end }); + if (!flagged) + { + //didn't expand an existing region, make a new one + mMappedIndexRegions.push_back({ start, end }); + } } -#endif return mMappedIndexData + sizeof(U16)*index; } @@ -1213,12 +1268,16 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) // dst -- mMappedData or mMappedIndexData void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst) { -#if LL_DARWIN - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy"); - STOP_GLERROR; - // copy into mapped buffer - memcpy(dst+start, data, end-start+1); -#else + if(sMappingMode > 1) + { + //LL_INFOS() << "milo flush_vbo() NO POOL" << LL_ENDL; + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy"); + //STOP_GLERROR; + // copy into mapped buffer + memcpy(dst+start, data, end-start+1); + return; + } + llassert(target == GL_ARRAY_BUFFER ? sGLRenderBuffer == mGLBuffer : sGLRenderIndices == mGLIndices); // skip mapped data and stream to GPU via glBufferSubData @@ -1240,7 +1299,6 @@ void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8 glBufferSubData(target, i, size, (U8*) data + (i-start)); } } -#endif } void LLVertexBuffer::unmapBuffer() @@ -1254,46 +1312,50 @@ void LLVertexBuffer::unmapBuffer() } }; -#if LL_DARWIN - STOP_GLERROR; - if (mMappedData) + if(sMappingMode > 1) { - if (mGLBuffer) + //STOP_GLERROR; + if (mMappedData) { - glDeleteBuffers(1, &mGLBuffer); + if (mGLBuffer) + { + glDeleteBuffers(1, &mGLBuffer); + } + mGLBuffer = gen_buffer(); + glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + if(sMappingMode==2) glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW); + else glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_DYNAMIC_DRAW); } - mGLBuffer = gen_buffer(); - glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); - sGLRenderBuffer = mGLBuffer; - glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW); - } - else if (mGLBuffer != sGLRenderBuffer) - { - glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); - sGLRenderBuffer = mGLBuffer; - } - STOP_GLERROR; - - if (mMappedIndexData) - { - if (mGLIndices) + else if (mGLBuffer != sGLRenderBuffer) { - glDeleteBuffers(1, &mGLIndices); + glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); + sGLRenderBuffer = mGLBuffer; } + //STOP_GLERROR; - mGLIndices = gen_buffer(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); - sGLRenderIndices = mGLIndices; + if (mMappedIndexData) + { + if (mGLIndices) + { + glDeleteBuffers(1, &mGLIndices); + } - glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW); - } - else if (mGLIndices != sGLRenderIndices) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); - sGLRenderIndices = mGLIndices; + mGLIndices = gen_buffer(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); + sGLRenderIndices = mGLIndices; + + if(sMappingMode==2) glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW); + else glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_DYNAMIC_DRAW); + } + else if (mGLIndices != sGLRenderIndices) + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); + sGLRenderIndices = mGLIndices; + } + //STOP_GLERROR; + return; } - STOP_GLERROR; -#else if (!mMappedVertexRegions.empty()) { @@ -1361,7 +1423,6 @@ void LLVertexBuffer::unmapBuffer() flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData); mMappedIndexRegions.clear(); } -#endif } //---------------------------------------------------------------------------- @@ -1482,13 +1543,14 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, U32 in // Set for rendering void LLVertexBuffer::setBuffer() { - STOP_GLERROR; -#if LL_DARWIN - if (!mGLBuffer) - { // OS X doesn't allocate a buffer until we call unmapBuffer - return; + if(sMappingMode > 1) + { + if (!mGLBuffer) + { // OS X doesn't allocate a buffer until we call unmapBuffer + return; + } } -#endif + // no data may be pending llassert(mMappedVertexRegions.empty()); llassert(mMappedIndexRegions.empty()); |