From 5546041301a67da6e471a433b29374bc75a4f0d0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 21 Dec 2011 15:55:14 -0600 Subject: SH-2794 WIP -- work on getting glMapBuffer and friends to behave --- indra/llrender/llvertexbuffer.cpp | 52 +++++++++++++++++++++++++-------------- indra/llrender/llvertexbuffer.h | 22 ++++++++--------- 2 files changed, 45 insertions(+), 29 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 20a450fbfb..f8c2a55820 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -148,7 +148,7 @@ U32 wpo2(U32 i) return r; } -U8* LLVBOPool::allocate(U32& name, U32 size) +volatile U8* LLVBOPool::allocate(U32& name, U32 size) { llassert(nhpo2(size) == size); @@ -159,7 +159,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size) mFreeList.resize(i+1); } - U8* ret = NULL; + volatile U8* ret = NULL; if (mFreeList[i].empty()) { @@ -188,7 +188,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size) return ret; } -void LLVBOPool::release(U32 name, U8* buffer, U32 size) +void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size) { llassert(nhpo2(size) == size); @@ -221,7 +221,7 @@ void LLVBOPool::cleanup() if (r.mClientData) { - ll_aligned_free_16(r.mClientData); + ll_aligned_free_16((void*) r.mClientData); } l.pop_front(); @@ -1042,7 +1042,7 @@ void LLVertexBuffer::destroyGLBuffer() } else { - FREE_MEM(sPrivatePoolp, mMappedData) ; + FREE_MEM(sPrivatePoolp, (void*) mMappedData) ; mMappedData = NULL; mEmpty = TRUE; } @@ -1063,7 +1063,7 @@ void LLVertexBuffer::destroyGLIndices() } else { - FREE_MEM(sPrivatePoolp, mMappedIndexData) ; + FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ; mMappedIndexData = NULL; mEmpty = TRUE; } @@ -1282,8 +1282,11 @@ 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"); + // Map for data access -U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) +volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) { bindGLBuffer(true); LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); @@ -1346,13 +1349,14 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran } else { - U8* src = NULL; + volatile U8* src = NULL; waitFence(); if (gGLManager.mHasMapBufferRange) { if (map_range) { #ifdef GL_ARB_map_buffer_range + LLFastTimer t(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, @@ -1376,6 +1380,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran } } + LLFastTimer t(FTM_VBO_MAP_BUFFER); src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); @@ -1403,7 +1408,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran llassert(src != NULL); - mMappedData = LL_NEXT_ALIGNED_ADDRESS(src); + mMappedData = LL_NEXT_ALIGNED_ADDRESS(src); mAlignedOffset = mMappedData - src; stop_glerror(); @@ -1458,7 +1463,11 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran } } -U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) + +static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX_RANGE("IBO Map Range"); +static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map"); + +volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); bindGLIndices(true); @@ -1530,13 +1539,14 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } else { - U8* src = NULL; + volatile U8* src = NULL; waitFence(); if (gGLManager.mHasMapBufferRange) { if (map_range) { #ifdef GL_ARB_map_buffer_range + LLFastTimer t(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, @@ -1548,6 +1558,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) else { #ifdef GL_ARB_map_buffer_range + LLFastTimer t(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); @@ -1569,6 +1580,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } else { + LLFastTimer t(FTM_VBO_MAP_INDEX); map_range = false; src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); } @@ -1619,6 +1631,8 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } } +static LLFastTimer::DeclareTimer FTM_VBO_UNMAP("VBO Unmap"); + void LLVertexBuffer::unmapBuffer() { LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); @@ -1627,6 +1641,8 @@ void LLVertexBuffer::unmapBuffer() return ; //nothing to unmap } + LLFastTimer t(FTM_VBO_UNMAP); + bool updated_all = false ; if (mMappedData && mVertexLocked) @@ -1644,7 +1660,7 @@ void LLVertexBuffer::unmapBuffer() 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; - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, mMappedData+offset); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset); stop_glerror(); } @@ -1653,7 +1669,7 @@ void LLVertexBuffer::unmapBuffer() else { stop_glerror(); - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*) mMappedData); stop_glerror(); } } @@ -1708,7 +1724,7 @@ void LLVertexBuffer::unmapBuffer() const MappedRegion& region = mMappedIndexRegions[i]; S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; S32 length = sizeof(U16)*region.mCount; - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, mMappedIndexData+offset); + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset); stop_glerror(); } @@ -1717,7 +1733,7 @@ void LLVertexBuffer::unmapBuffer() else { stop_glerror(); - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*) mMappedIndexData); stop_glerror(); } } @@ -1778,7 +1794,7 @@ template struct VertexBufferStrider { if (type == LLVertexBuffer::TYPE_INDEX) { - U8* ptr = vbo.mapIndexBuffer(index, count, map_range); + volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range); if (ptr == NULL) { @@ -1794,7 +1810,7 @@ template struct VertexBufferStrider { S32 stride = LLVertexBuffer::sTypeSize[type]; - U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range); + volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range); if (ptr == NULL) { @@ -2109,7 +2125,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER); stop_glerror(); - U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; + volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; /*if ((data_mask & mTypeMask) != data_mask) { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 3e6f6a959a..5b93a0389f 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -60,10 +60,10 @@ public: U32 mType; //size MUST be a power of 2 - U8* allocate(U32& name, U32 size); + volatile U8* allocate(U32& name, U32 size); //size MUST be the size provided to allocate that returned the given name - void release(U32 name, U8* buffer, U32 size); + void release(U32 name, volatile U8* buffer, U32 size); //destroy all records in mFreeList void cleanup(); @@ -72,7 +72,7 @@ public: { public: U32 mGLName; - U8* mClientData; + volatile U8* mClientData; }; typedef std::list record_list_t; @@ -208,8 +208,8 @@ public: LLVertexBuffer(U32 typemask, S32 usage); // map for data access - U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); - U8* mapIndexBuffer(S32 index, S32 count, bool map_range); + volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); + volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range); // set for rendering virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 @@ -244,14 +244,14 @@ 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; } + volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; } + volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; } U32 getTypeMask() const { return mTypeMask; } bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); } S32 getSize() const; S32 getIndicesSize() const { return mIndicesSize; } - U8* getMappedData() const { return mMappedData; } - U8* getMappedIndices() const { return mMappedIndexData; } + volatile U8* getMappedData() const { return mMappedData; } + volatile U8* getMappedIndices() const { return mMappedIndexData; } S32 getOffset(S32 type) const { return mOffsets[type]; } S32 getUsage() const { return mUsage; } @@ -278,8 +278,8 @@ protected: 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) + volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) + volatile 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 BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory BOOL mFinal; // if TRUE, buffer can not be mapped again -- cgit v1.2.3 From 0c1fc78bd94014ee19da690f16cef64c13e50771 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 Jan 2012 12:40:11 -0600 Subject: SH-2794 Map buffer now performs as well as buffersubdata --- indra/llrender/llvertexbuffer.cpp | 63 ++++++++++++++++++++++++++------------- indra/llrender/llvertexbuffer.h | 2 ++ 2 files changed, 45 insertions(+), 20 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index f8c2a55820..62be5c7368 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -169,7 +169,7 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size) glBufferDataARB(mType, size, 0, mUsage); LLVertexBuffer::sAllocatedBytes += size; - if (LLVertexBuffer::sDisableVBOMapping) + if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) { ret = (U8*) ll_aligned_malloc_16(size); } @@ -201,8 +201,15 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size) rec.mClientData = buffer; sBytesPooled += size; - - mFreeList[i].push_back(rec); + + if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB) + { + glDeleteBuffersARB(1, &rec.mGLName); + } + else + { + mFreeList[i].push_back(rec); + } } void LLVBOPool::cleanup() @@ -536,7 +543,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of 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); @@ -591,7 +598,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - + mMappable = FALSE; gGL.syncMatrices(); llassert(mNumIndices >= 0); @@ -637,7 +644,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - + mMappable = FALSE; gGL.syncMatrices(); llassert(mNumVerts >= 0); @@ -790,6 +797,15 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mUsage = GL_DYNAMIC_DRAW_ARB; } + if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping) + { + mMappable = TRUE; + } + else + { + mMappable = FALSE; + } + //zero out offsets for (U32 i = 0; i < TYPE_MAX; i++) { @@ -1301,7 +1317,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo if (useVBOs()) { - if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) { if (count == -1) { @@ -1326,7 +1342,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo if (!mapped) { //not already mapped, map new region - MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count); + MappedRegion region(type, mMappable && map_range ? -1 : index, count); mMappedVertexRegions.push_back(region); } } @@ -1343,7 +1359,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo sMappedCount++; stop_glerror(); - if(sDisableVBOMapping) + if(!mMappable) { map_range = false; } @@ -1421,7 +1437,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo //check the availability of memory LLMemory::logMemoryInfo(TRUE) ; - if(!sDisableVBOMapping) + if(mMappable) { //-------------------- //print out more debug info before crash @@ -1453,7 +1469,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping) + if (map_range && gGLManager.mHasMapBufferRange && mMappable) { return mMappedData; } @@ -1482,7 +1498,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range if (useVBOs()) { - if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) { if (count == -1) { @@ -1504,7 +1520,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range if (!mapped) { //not already mapped, map new region - MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count); + MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count); mMappedIndexRegions.push_back(region); } } @@ -1533,7 +1549,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range } } - if(sDisableVBOMapping) + if(!mMappable) { map_range = false; } @@ -1599,7 +1615,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range log_glerror(); LLMemory::logMemoryInfo(TRUE) ; - if(!sDisableVBOMapping) + if(mMappable) { GLint buff; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); @@ -1621,7 +1637,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping) + if (map_range && gGLManager.mHasMapBufferRange && mMappable) { return mMappedIndexData; } @@ -1632,6 +1648,11 @@ 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 LLFastTimer::DeclareTimer FTM_IBO_UNMAP("IBO Unmap"); +static LLFastTimer::DeclareTimer FTM_IBO_FLUSH_RANGE("Flush IBO Range"); void LLVertexBuffer::unmapBuffer() { @@ -1641,16 +1662,15 @@ void LLVertexBuffer::unmapBuffer() return ; //nothing to unmap } - LLFastTimer t(FTM_VBO_UNMAP); - bool updated_all = false ; if (mMappedData && mVertexLocked) { + LLFastTimer t(FTM_VBO_UNMAP); bindGLBuffer(true); updated_all = mIndexLocked; //both vertex and index buffers done updating - if(sDisableVBOMapping) + if(!mMappable) { if (!mMappedVertexRegions.empty()) { @@ -1687,6 +1707,7 @@ void LLVertexBuffer::unmapBuffer() S32 length = sTypeSize[region.mType]*region.mCount; if (gGLManager.mHasMapBufferRange) { + LLFastTimer t(FTM_VBO_FLUSH_RANGE); #ifdef GL_ARB_map_buffer_range glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length); #endif @@ -1714,8 +1735,9 @@ void LLVertexBuffer::unmapBuffer() if (mMappedIndexData && mIndexLocked) { + LLFastTimer t(FTM_IBO_UNMAP); bindGLIndices(); - if(sDisableVBOMapping) + if(!mMappable) { if (!mMappedIndexRegions.empty()) { @@ -1750,6 +1772,7 @@ void LLVertexBuffer::unmapBuffer() S32 length = sizeof(U16)*region.mCount; if (gGLManager.mHasMapBufferRange) { + LLFastTimer t(FTM_IBO_FLUSH_RANGE); #ifdef GL_ARB_map_buffer_range glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length); #endif diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 5b93a0389f..dde2b7e152 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -254,6 +254,7 @@ public: volatile U8* getMappedIndices() const { return mMappedIndexData; } S32 getOffset(S32 type) const { return mOffsets[type]; } S32 getUsage() const { return mUsage; } + BOOL isWriteable() const { return (sDisableVBOMapping || mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; } void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; @@ -284,6 +285,7 @@ protected: BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory BOOL mFinal; // if TRUE, buffer can not be mapped again BOOL mEmpty; // 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 mMappedVertexRegions; -- cgit v1.2.3