diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llrender/llgl.cpp | 33 | ||||
-rw-r--r-- | indra/llrender/llgl.h | 2 | ||||
-rw-r--r-- | indra/llrender/llglheaders.h | 39 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 221 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 12 | ||||
-rw-r--r-- | indra/newview/featuretable.txt | 6 | ||||
-rw-r--r-- | indra/newview/featuretable_linux.txt | 6 | ||||
-rw-r--r-- | indra/newview/featuretable_mac.txt | 13 | ||||
-rw-r--r-- | indra/newview/featuretable_xp.txt | 6 | ||||
-rw-r--r-- | indra/newview/lldrawable.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llface.cpp | 64 | ||||
-rw-r--r-- | indra/newview/llfeaturemanager.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 38 |
13 files changed, 348 insertions, 101 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c224ab0e9b..e07ff0015c 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -128,9 +128,21 @@ PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL; PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL; // GL_ARB_map_buffer_range -PFNGLMAPBUFFERRANGEPROC glMapBufferRange; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; - +PFNGLMAPBUFFERRANGEPROC glMapBufferRange = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange = NULL; + +// GL_ARB_sync +PFNGLFENCESYNCPROC glFenceSync = NULL; +PFNGLISSYNCPROC glIsSync = NULL; +PFNGLDELETESYNCPROC glDeleteSync = NULL; +PFNGLCLIENTWAITSYNCPROC glClientWaitSync = NULL; +PFNGLWAITSYNCPROC glWaitSync = NULL; +PFNGLGETINTEGER64VPROC glGetInteger64v = NULL; +PFNGLGETSYNCIVPROC glGetSynciv = NULL; + +// GL_APPLE_flush_buffer_range +PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE = NULL; // vertex object prototypes PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL; @@ -334,9 +346,10 @@ LLGLManager::LLGLManager() : mHasFramebufferObject(FALSE), mMaxSamples(0), mHasBlendFuncSeparate(FALSE), - + mHasSync(FALSE), mHasVertexBufferObject(FALSE), mHasMapBufferRange(FALSE), + mHasFlushBufferRange(FALSE), mHasPBuffer(FALSE), mHasShaderObjects(FALSE), mHasVertexShader(FALSE), @@ -774,7 +787,9 @@ void LLGLManager::initExtensions() mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts); mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); + mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts); mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts); + mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts); mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad #ifdef GL_ARB_framebuffer_object @@ -969,6 +984,16 @@ void LLGLManager::initExtensions() mHasVertexBufferObject = FALSE; } } + if (mHasSync) + { + glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
+ glIsSync = (PFNGLISSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glIsSync");
+ glDeleteSync = (PFNGLDELETESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteSync");
+ glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glClientWaitSync");
+ glWaitSync = (PFNGLWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glWaitSync");
+ glGetInteger64v = (PFNGLGETINTEGER64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInteger64v");
+ glGetSynciv = (PFNGLGETSYNCIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetSynciv"); + } if (mHasMapBufferRange) { glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange"); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index d1bee00161..d736133f3f 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -88,7 +88,9 @@ public: // ARB Extensions BOOL mHasVertexBufferObject; + BOOL mHasSync; BOOL mHasMapBufferRange; + BOOL mHasFlushBufferRange; BOOL mHasPBuffer; BOOL mHasShaderObjects; BOOL mHasVertexShader; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f35f329f00..851a75629e 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -68,6 +68,19 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB; extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB; extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC glFenceSync; +extern PFNGLISSYNCPROC glIsSync; +extern PFNGLDELETESYNCPROC glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync; +extern PFNGLWAITSYNCPROC glWaitSync; +extern PFNGLGETINTEGER64VPROC glGetInteger64v; +extern PFNGLGETSYNCIVPROC glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; + // GL_ARB_map_buffer_range extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; @@ -310,6 +323,19 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB; extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB; extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC glFenceSync; +extern PFNGLISSYNCPROC glIsSync; +extern PFNGLDELETESYNCPROC glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync; +extern PFNGLWAITSYNCPROC glWaitSync; +extern PFNGLGETINTEGER64VPROC glGetInteger64v; +extern PFNGLGETSYNCIVPROC glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; + // GL_ARB_map_buffer_range extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; @@ -519,6 +545,19 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB; extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB; extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC glFenceSync; +extern PFNGLISSYNCPROC glIsSync; +extern PFNGLDELETESYNCPROC glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync; +extern PFNGLWAITSYNCPROC glWaitSync; +extern PFNGLGETINTEGER64VPROC glGetInteger64v; +extern PFNGLGETSYNCIVPROC glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; + // GL_ARB_map_buffer_range extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4a0b964e61..82c5efe0ac 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -65,6 +65,60 @@ S32 LLVertexBuffer::sWeight4Loc = -1; std::vector<U32> LLVertexBuffer::sDeleteList; +const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms + +class LLGLSyncFence : public LLGLFence +{ +public: +#ifdef GL_ARB_sync + GLsync mSync; +#endif + + LLGLSyncFence() + { +#ifdef GL_ARB_sync + mSync = 0; +#endif + } + + ~LLGLSyncFence() + { +#ifdef GL_ARB_sync + if (mSync) + { + glDeleteSync(mSync); + } +#endif + } + + void placeFence() + { +#ifdef GL_ARB_sync + if (mSync) + { + glDeleteSync(mSync); + } + mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +#endif + } + + void wait() + { +#ifdef GL_ARB_sync + if (mSync) + { + while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED) + { //track the number of times we've waited here + static S32 waits = 0; + waits++; + } + } +#endif + } + + +}; + S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = { sizeof(LLVector4), // TYPE_VERTEX, @@ -309,6 +363,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, idx); stop_glerror(); + placeFence(); } void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const @@ -340,6 +395,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT, ((U16*) getIndicesPointer()) + indices_offset); stop_glerror(); + placeFence(); } void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const @@ -365,6 +421,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const stop_glerror(); glDrawArrays(sGLMode[mode], first, count); stop_glerror(); + placeFence(); } //static @@ -444,9 +501,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mFilthy(FALSE), mEmpty(TRUE), mResized(FALSE), - mDynamicSize(FALSE) + mDynamicSize(FALSE), + mFence(NULL) { LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR); + mFence = NULL; if (!sEnableVBOs) { mUsage = 0 ; @@ -527,9 +586,40 @@ LLVertexBuffer::~LLVertexBuffer() destroyGLIndices(); sCount--; + if (mFence) + { + delete mFence; + } + + mFence = NULL; + llassert_always(!mMappedData && !mMappedIndexData) ; }; +void LLVertexBuffer::placeFence() const +{ + /*if (!mFence && useVBOs()) + { + if (gGLManager.mHasSync) + { + mFence = new LLGLSyncFence(); + } + } + + if (mFence) + { + mFence->placeFence(); + }*/ +} + +void LLVertexBuffer::waitFence() const +{ + /*if (mFence) + { + mFence->wait(); + }*/ +} + //---------------------------------------------------------------------------- void LLVertexBuffer::genBuffer() @@ -892,17 +982,11 @@ BOOL LLVertexBuffer::useVBOs() const { //it's generally ineffective to use VBO for things that are streaming on apple -#if LL_DARWIN - if (!mUsage || mUsage == GL_STREAM_DRAW_ARB) - { - return FALSE; - } -#else if (!mUsage) { return FALSE; } -#endif + return TRUE; } @@ -967,8 +1051,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (useVBOs()) { - - if (sDisableVBOMapping || gGLManager.mHasMapBufferRange) + if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) { if (count == -1) { @@ -1008,6 +1091,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES); setBuffer(0, type); mVertexLocked = TRUE; + sMappedCount++; stop_glerror(); if(sDisableVBOMapping) @@ -1018,29 +1102,52 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran else { U8* src = NULL; -#ifdef GL_ARB_map_buffer_range + waitFence(); if (gGLManager.mHasMapBufferRange) { if (map_range) { +#ifdef GL_ARB_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, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT | + GL_MAP_UNSYNCHRONIZED_BIT); +#endif } else { - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); +#ifdef GL_ARB_map_buffer_range + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_UNSYNCHRONIZED_BIT); +#endif + } + } + else if (gGLManager.mHasFlushBufferRange) + { + if (map_range) + { + glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE); + glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); + src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + else + { + src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); } } else -#else - llassert_always(!gGLManager.mHasMapBufferRange); -#endif { map_range = false; src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); } + llassert(src != NULL); + mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src); mAlignedOffset = mMappedData - src; @@ -1082,7 +1189,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran llerrs << "memory allocation for vertex data failed." << llendl ; } } - sMappedCount++; } } else @@ -1090,7 +1196,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran map_range = false; } - if (map_range && !sDisableVBOMapping) + if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping) { return mMappedData; } @@ -1114,7 +1220,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (useVBOs()) { - if (sDisableVBOMapping || gGLManager.mHasMapBufferRange) + if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) { if (count == -1) { @@ -1152,6 +1258,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) setBuffer(0, TYPE_INDEX); mIndexLocked = TRUE; + sMappedCount++; stop_glerror(); if(sDisableVBOMapping) @@ -1162,29 +1269,53 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) else { U8* src = NULL; -#ifdef GL_ARB_map_buffer_range + waitFence(); if (gGLManager.mHasMapBufferRange) { if (map_range) { +#ifdef GL_ARB_map_buffer_range S32 offset = sizeof(U16)*index; S32 length = sizeof(U16)*count; - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT | + GL_MAP_UNSYNCHRONIZED_BIT); +#endif } else { - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); +#ifdef GL_ARB_map_buffer_range + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_UNSYNCHRONIZED_BIT); +#endif + } + } + else if (gGLManager.mHasFlushBufferRange) + { + if (map_range) + { + glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE); + glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); + src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + else + { + src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); } } else -#else - llassert_always(!gGLManager.mHasMapBufferRange); -#endif { map_range = false; src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); } + llassert(src != NULL); + + mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); @@ -1211,15 +1342,13 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) llerrs << "memory allocation for Index data failed. " << llendl ; } } - - sMappedCount++; } else { map_range = false; } - if (map_range && !sDisableVBOMapping) + if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping) { return mMappedIndexData; } @@ -1268,8 +1397,7 @@ void LLVertexBuffer::unmapBuffer(S32 type) } else { -#ifdef GL_ARB_map_buffer_range - if (gGLManager.mHasMapBufferRange) + if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) { if (!mMappedVertexRegions.empty()) { @@ -1279,16 +1407,22 @@ void LLVertexBuffer::unmapBuffer(S32 type) 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_ARB, offset, length); + if (gGLManager.mHasMapBufferRange) + { +#ifdef GL_ARB_map_buffer_range + glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length); +#endif + } + else if (gGLManager.mHasFlushBufferRange) + { + glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length); + } stop_glerror(); } mMappedVertexRegions.clear(); } } -#else - llassert_always(!gGLManager.mHasMapBufferRange); -#endif stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); stop_glerror(); @@ -1326,8 +1460,7 @@ void LLVertexBuffer::unmapBuffer(S32 type) } else { -#ifdef GL_ARB_map_buffer_range - if (gGLManager.mHasMapBufferRange) + if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) { if (!mMappedIndexRegions.empty()) { @@ -1336,16 +1469,24 @@ void LLVertexBuffer::unmapBuffer(S32 type) 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_ARB, offset, length); + if (gGLManager.mHasMapBufferRange) + { +#ifdef GL_ARB_map_buffer_range + glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length); +#endif + } + else if (gGLManager.mHasFlushBufferRange) + { +#ifdef GL_APPLE_flush_buffer_range + glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length); +#endif + } stop_glerror(); } mMappedIndexRegions.clear(); } } -#else - llassert_always(!gGLManager.mHasMapBufferRange); -#endif stop_glerror(); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); stop_glerror(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index aa5df305a6..cc5d11e1c2 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -70,6 +70,12 @@ protected: } }; +class LLGLFence +{ +public: + virtual void placeFence() = 0; + virtual void wait() = 0; +}; //============================================================================ // base class @@ -270,6 +276,12 @@ protected: std::vector<MappedRegion> mMappedVertexRegions; std::vector<MappedRegion> mMappedIndexRegions; + mutable LLGLFence* mFence; + + void placeFence() const; + void waitFence() const; + + public: static S32 sCount; static S32 sGLCount; diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 22c79a4cbd..d2d0227f62 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 30 +version 31 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -244,9 +244,9 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists // -list NoMapBufferRange +list MapBufferRange RenderVBOMappingDisable 1 0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 649f5ebd18..d9b4083016 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 25 +version 26 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -242,9 +242,9 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists // -list NoMapBufferRange +list MapBufferRange RenderVBOMappingDisable 1 0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index ee08e78af5..f0b1f532a9 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 26 +version 28 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -48,7 +48,7 @@ RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 -RenderVBOMappingDisable 1 1 +RenderVBOMappingDisable 1 0 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 UseOcclusion 1 1 @@ -63,7 +63,7 @@ RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 WatchdogDisabled 1 1 -RenderUseStreamVBO 1 1 +RenderUseStreamVBO 1 0 RenderFSAASamples 1 16 // @@ -244,13 +244,6 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 // -// No GL_ARB_map_buffer_range -// -list NoMapBufferRange -RenderVBOMappingDisable 1 0 - - -// // "Default" setups for safe, low, medium, high // list safe diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index ba74f9a6c2..6477dab35a 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 30 +version 31 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -244,9 +244,9 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists // -list NoMapBufferRange +list MapBufferRange RenderVBOMappingDisable 1 0 diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index debac9dcbf..a5168fd897 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1524,6 +1524,11 @@ BOOL LLDrawable::isAnimating() const return TRUE; } + if (!LLVertexBuffer::sUseStreamDraw && mVObjp->isFlexible()) + { + return TRUE; + } + return FALSE; } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b6566fcbd0..59c6e904a1 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1064,6 +1064,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, S32 num_vertices = (S32)vf.mNumVertices; S32 num_indices = (S32) vf.mNumIndices; + bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; + if (mVertexBuffer.notNull()) { if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) @@ -1182,7 +1184,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, // INDICES if (full_rebuild) { - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, true); + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range); __m128i* dst = (__m128i*) indicesp.get(); __m128i* src = (__m128i*) vf.mIndices; @@ -1201,7 +1203,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, indicesp[i] = vf.mIndices[i]+index_offset; } - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } LLMatrix4a mat_normal; @@ -1422,11 +1427,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } else { //either bump mapped or in atlas, just do the whole expensive loop - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, true); + mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range); std::vector<LLVector2> bump_tc; @@ -1566,12 +1574,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - mVertexBuffer->setBuffer(0); - + if (map_range) + { + mVertexBuffer->setBuffer(0); + } if (do_bump) { - mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, true); + mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); for (S32 i = 0; i < num_vertices; i++) { @@ -1601,14 +1611,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, *tex_coords2++ = tc; } - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } } } if (rebuild_pos) { - mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, true); + mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); vertices = (LLVector4a*) vert.get(); LLMatrix4a mat_vert; @@ -1637,12 +1650,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } while (index_dst < index_end); - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } if (rebuild_normal) { - mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, true); + mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); normals = (LLVector4a*) norm.get(); for (S32 i = 0; i < num_vertices; i++) @@ -1653,12 +1669,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, normals[i] = normal; } - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } if (rebuild_binormal) { - mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, true); + mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); binormals = (LLVector4a*) binorm.get(); for (S32 i = 0; i < num_vertices; i++) @@ -1669,20 +1688,26 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, binormals[i] = binormal; } - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } if (rebuild_weights && vf.mWeights) { - mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, true); + mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); weights = (LLVector4a*) wght.get(); LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } if (rebuild_color) { - mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, true); + mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range); LLVector4a src; @@ -1703,7 +1728,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, dst[i] = src; } - mVertexBuffer->setBuffer(0); + if (map_range) + { + mVertexBuffer->setBuffer(0); + } } if (rebuild_tcoord) diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 83844048d1..0ea0e41dfa 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -769,6 +769,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("TexUnit8orLess"); } + if (gGLManager.mHasMapBufferRange) + { + maskFeatures("MapBufferRange"); + } // now mask by gpu string // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e6da8eb89d..40afabdb65 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4361,6 +4361,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) group->mBuilt = 1.f; + std::set<LLVertexBuffer*> mapped_buffers; + for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL); @@ -4375,35 +4377,31 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); - if (face && face->getVertexBuffer()) + if (face) { - face->getGeometryVolume(*volume, face->getTEOffset(), - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { + face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); + + if (buff->isLocked()) + { + mapped_buffers.insert(buff); + } + } } } - + drawablep->clearState(LLDrawable::REBUILD_ALL); } } - //unmap all the buffers - for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) + for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter) { - LLSpatialGroup::buffer_texture_map_t& map = i->second; - for (LLSpatialGroup::buffer_texture_map_t::iterator j = map.begin(); j != map.end(); ++j) - { - LLSpatialGroup::buffer_list_t& list = j->second; - for (LLSpatialGroup::buffer_list_t::iterator k = list.begin(); k != list.end(); ++k) - { - LLVertexBuffer* buffer = *k; - if (buffer->isLocked()) - { - buffer->setBuffer(0); - } - } - } + (*iter)->setBuffer(0); } - + // don't forget alpha if(group != NULL && !group->mVertexBuffer.isNull() && |