merge
commit
ddbd5cee74
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -88,7 +88,9 @@ public:
|
|||
|
||||
// ARB Extensions
|
||||
BOOL mHasVertexBufferObject;
|
||||
BOOL mHasSync;
|
||||
BOOL mHasMapBufferRange;
|
||||
BOOL mHasFlushBufferRange;
|
||||
BOOL mHasPBuffer;
|
||||
BOOL mHasShaderObjects;
|
||||
BOOL mHasVertexShader;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
//
|
||||
|
|
@ -243,13 +243,6 @@ RenderDeferred 0 0
|
|||
RenderDeferredSSAO 0 0
|
||||
RenderShadowDetail 0 0
|
||||
|
||||
//
|
||||
// No GL_ARB_map_buffer_range
|
||||
//
|
||||
list NoMapBufferRange
|
||||
RenderVBOMappingDisable 1 0
|
||||
|
||||
|
||||
//
|
||||
// "Default" setups for safe, low, medium, high
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1524,6 +1524,11 @@ BOOL LLDrawable::isAnimating() const
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (!LLVertexBuffer::sUseStreamDraw && mVObjp->isFlexible())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() &&
|
||||
|
|
|
|||
Loading…
Reference in New Issue