diff options
author | Oz Linden <oz@lindenlab.com> | 2011-04-02 07:07:49 -0400 |
---|---|---|
committer | Oz Linden <oz@lindenlab.com> | 2011-04-02 07:07:49 -0400 |
commit | e58c809a5816383674d0f1957440fad728e88893 (patch) | |
tree | 83f1ff2c4bee8237c4557793143b2133623943a4 /indra/llrender | |
parent | f9af1f4fca028709b0262c0e8c40eefc2ab13d00 (diff) | |
parent | e6c0615b97019cf9c8aee267513757c0c2510420 (diff) |
merge changes for STORM-1131
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llfontfreetype.cpp | 2 | ||||
-rw-r--r-- | indra/llrender/llgl.cpp | 53 | ||||
-rw-r--r-- | indra/llrender/llgl.h | 8 | ||||
-rw-r--r-- | indra/llrender/llglheaders.h | 10 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 8 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 3 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 299 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 33 |
8 files changed, 313 insertions, 103 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index b84e696e2d..91c8a37022 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -482,7 +482,7 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const if (mFTFace == NULL) return; - int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT ); + int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT ); llassert(!error); error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode); diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c0edd92bc1..6ea63809f8 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -610,41 +610,46 @@ void LLGLManager::shutdownGL() void LLGLManager::initExtensions() { #if LL_MESA_HEADLESS -# if GL_ARB_multitexture +# ifdef GL_ARB_multitexture mHasMultitexture = TRUE; # else mHasMultitexture = FALSE; # endif -# if GL_ARB_texture_env_combine +# ifdef GL_ARB_texture_env_combine mHasARBEnvCombine = TRUE; # else mHasARBEnvCombine = FALSE; # endif -# if GL_ARB_texture_compression +# ifdef GL_ARB_texture_compression mHasCompressedTextures = TRUE; # else mHasCompressedTextures = FALSE; # endif -# if GL_ARB_vertex_buffer_object +# ifdef GL_ARB_vertex_buffer_object mHasVertexBufferObject = TRUE; # else mHasVertexBufferObject = FALSE; # endif -# if GL_EXT_framebuffer_object +# ifdef GL_EXT_framebuffer_object mHasFramebufferObject = TRUE; # else mHasFramebufferObject = FALSE; # endif -# if GL_EXT_framebuffer_multisample +# ifdef GL_EXT_framebuffer_multisample mHasFramebufferMultisample = TRUE; # else mHasFramebufferMultisample = FALSE; # endif -# if GL_ARB_draw_buffers +# ifdef GL_ARB_draw_buffers mHasDrawBuffers = TRUE; #else mHasDrawBuffers = FALSE; # endif +# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) + mHasDepthClamp = TRUE; +#else + mHasDepthClamp = FALSE; +#endif # if GL_EXT_blend_func_separate mHasBlendFuncSeparate = TRUE; #else @@ -671,6 +676,7 @@ void LLGLManager::initExtensions() mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression"); mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", 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 mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts) && ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts); @@ -694,6 +700,7 @@ void LLGLManager::initExtensions() if (getenv("LL_GL_NOEXT")) { //mHasMultitexture = FALSE; // NEEDED! + mHasDepthClamp = FALSE; mHasARBEnvCombine = FALSE; mHasCompressedTextures = FALSE; mHasVertexBufferObject = FALSE; @@ -755,6 +762,7 @@ void LLGLManager::initExtensions() if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE; if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE; if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S + if (strchr(blacklist,'v')) mHasDepthClamp = FALSE; } #endif // LL_LINUX || LL_SOLARIS @@ -1047,6 +1055,33 @@ void flush_glerror() glGetError(); } +//this function outputs gl error to the log file, does not crash the code. +void log_glerror() +{ + if (LL_UNLIKELY(!gGLManager.mInited)) + { + return ; + } + // Create or update texture to be used with this data + GLenum error; + error = glGetError(); + while (LL_UNLIKELY(error)) + { + GLubyte const * gl_error_msg = gluErrorString(error); + if (NULL != gl_error_msg) + { + llwarns << "GL Error: " << error << " GL Error String: " << gl_error_msg << llendl ; + } + else + { + // gluErrorString returns NULL for some extensions' error codes. + // you'll probably have to grep for the number in glext.h. + llwarns << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << llendl; + } + error = glGetError(); + } +} + void do_assert_glerror() { if (LL_UNLIKELY(!gGLManager.mInited)) @@ -2037,7 +2072,7 @@ void LLGLDepthTest::checkState() } } -LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P) +LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P) { for (U32 i = 0; i < 4; i++) { @@ -2050,7 +2085,7 @@ LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P) glMatrixMode(GL_MODELVIEW); } -LLGLClampToFarClip::~LLGLClampToFarClip() +LLGLSquashToFarClip::~LLGLSquashToFarClip() { glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 5e8965c06a..85fab7a0f8 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -92,6 +92,7 @@ public: BOOL mHasOcclusionQuery; BOOL mHasPointParameters; BOOL mHasDrawBuffers; + BOOL mHasDepthClamp; BOOL mHasTextureRectangle; // Other extensions. @@ -157,6 +158,7 @@ void rotate_quat(LLQuaternion& rotation); void flush_glerror(); // Flush GL errors when we know we're handling them correctly. +void log_glerror(); void assert_glerror(); void clear_glerror(); @@ -315,11 +317,11 @@ private: leaves this class. Does not stack. */ -class LLGLClampToFarClip +class LLGLSquashToFarClip { public: - LLGLClampToFarClip(glh::matrix4f projection); - ~LLGLClampToFarClip(); + LLGLSquashToFarClip(glh::matrix4f projection); + ~LLGLSquashToFarClip(); }; /* diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 5a34b46d0c..576969b81a 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -829,5 +829,15 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif // LL_MESA / LL_WINDOWS / LL_DARWIN +// Even when GL_ARB_depth_clamp is available in the driver, the (correct) +// headers, and therefore GL_DEPTH_CLAMP might not be defined. +// In that case GL_DEPTH_CLAMP_NV should be defined, but why not just +// use the known numeric. +// +// To avoid #ifdef's in the code. Just define this here. +#ifndef GL_DEPTH_CLAMP +// Probably (still) called GL_DEPTH_CLAMP_NV. +#define GL_DEPTH_CLAMP 0x864F +#endif #endif // LL_LLGLHEADERS_H diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 72dd283bc7..e8e98211f1 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1063,14 +1063,6 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ { if (gGL.getTexUnit(0)->bind(this, false, true)) { - if(gGLManager.mDebugGPU) - { - llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ; - checkTexSize(true) ; - llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << - " : " << (S32)mComponents << llcallstacksendl ; - } - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); mGLTextureCreated = true; stop_glerror(); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index e26acd53a3..8eb160f4e7 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -431,6 +431,9 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio if (gGL.mMaxAnisotropy < 1.f) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy); + + llinfos << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << llendl ; + gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ; } glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy); } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index de4501dd0f..1beb74eca6 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -27,7 +27,7 @@ #include "linden_common.h" #include <boost/static_assert.hpp> - +#include "llsys.h" #include "llvertexbuffer.h" // #include "llrender.h" #include "llglheaders.h" @@ -47,6 +47,7 @@ U32 LLVertexBuffer::sSetCount = 0; S32 LLVertexBuffer::sCount = 0; S32 LLVertexBuffer::sGLCount = 0; S32 LLVertexBuffer::sMappedCount = 0; +BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ; BOOL LLVertexBuffer::sEnableVBOs = TRUE; U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; @@ -251,6 +252,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(mRequestedNumIndices >= 0); + if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { @@ -282,6 +284,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { llassert(mRequestedNumVerts >= 0); + if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) { @@ -305,9 +308,21 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const } //static -void LLVertexBuffer::initClass(bool use_vbo) +void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { - sEnableVBOs = use_vbo; + sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ; + if(sEnableVBOs) + { + //llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded. + + llinfos << "VBO is enabled." << llendl ; + } + else + { + llinfos << "VBO is disabled." << llendl ; + } + + sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; LLGLNamePool::registerPool(&sDynamicVBOPool); LLGLNamePool::registerPool(&sDynamicIBOPool); LLGLNamePool::registerPool(&sStreamVBOPool); @@ -364,7 +379,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mGLBuffer(0), mGLIndices(0), mMappedData(NULL), - mMappedIndexData(NULL), mLocked(FALSE), + mMappedIndexData(NULL), + mVertexLocked(FALSE), + mIndexLocked(FALSE), mFinal(FALSE), mFilthy(FALSE), mEmpty(TRUE), @@ -422,6 +439,8 @@ LLVertexBuffer::~LLVertexBuffer() destroyGLBuffer(); destroyGLIndices(); sCount--; + + llassert_always(!mMappedData && !mMappedIndexData) ; }; //---------------------------------------------------------------------------- @@ -567,6 +586,8 @@ void LLVertexBuffer::destroyGLBuffer() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped!" << llendl; @@ -594,11 +615,13 @@ void LLVertexBuffer::destroyGLIndices() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped." << llendl; } - releaseIndices(); + releaseIndices(); } else { @@ -799,6 +822,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (mResized && useVBOs()) { + freeClientBuffer() ; setBuffer(0); } } @@ -822,110 +846,239 @@ BOOL LLVertexBuffer::useVBOs() const } //---------------------------------------------------------------------------- +void LLVertexBuffer::freeClientBuffer() +{ + if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData)) + { + delete[] mMappedData ; + delete[] mMappedIndexData ; + mMappedData = NULL ; + mMappedIndexData = NULL ; + } +} + +void LLVertexBuffer::allocateClientVertexBuffer() +{ + if(!mMappedData) + { + U32 size = getSize() ; + mMappedData = new U8[size]; + memset(mMappedData, 0, size); + } +} + +void LLVertexBuffer::allocateClientIndexBuffer() +{ + if(!mMappedIndexData) + { + U32 size = getIndicesSize(); + mMappedIndexData = new U8[size]; + memset(mMappedIndexData, 0, size); + } +} // Map for data access -U8* LLVertexBuffer::mapBuffer(S32 access) +U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) { LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); if (mFinal) { - llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; + llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl; } if (!useVBOs() && !mMappedData && !mMappedIndexData) { - llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; + llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl; } - if (!mLocked && useVBOs()) + if (!mVertexLocked && useVBOs()) { { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES); - setBuffer(0); - mLocked = TRUE; + setBuffer(0, type); + mVertexLocked = TRUE; stop_glerror(); - mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + + if(sDisableVBOMapping) + { + allocateClientVertexBuffer() ; + } + else + { + mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } stop_glerror(); } + + if (!mMappedData) { - LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); - mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - stop_glerror(); + log_glerror(); + + //check the availability of memory + U32 avail_phy_mem, avail_vir_mem; + LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ; + llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; + llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl; + + if(!sDisableVBOMapping) + { + //-------------------- + //print out more debug info before crash + llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; + GLint size ; + glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; + llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; + //-------------------- + + GLint buff; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLBuffer) + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } + + + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; + } + else + { + llerrs << "memory allocation for vertex data failed." << llendl ; + } } + sMappedCount++; + } + + return mMappedData; +} - if (!mMappedData) +U8* LLVertexBuffer::mapIndexBuffer(S32 access) +{ + LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); + if (mFinal) + { + llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; + } + if (!useVBOs() && !mMappedData && !mMappedIndexData) + { + llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl; + } + + if (!mIndexLocked && useVBOs()) + { { - //-------------------- - //print out more debug info before crash - llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; - GLint size ; - glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; - llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; - //-------------------- + LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) + setBuffer(0, TYPE_INDEX); + mIndexLocked = TRUE; + stop_glerror(); + + if(sDisableVBOMapping) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + allocateClientIndexBuffer() ; } - - - llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; + else + { + mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + stop_glerror(); } if (!mMappedIndexData) { - GLint buff; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) + log_glerror(); + + if(!sDisableVBOMapping) { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; - } + GLint buff; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLIndices) + { + llerrs << "Invalid GL index buffer bound: " << buff << llendl; + } - llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + } + else + { + llerrs << "memory allocation for Index data failed. " << llendl ; + } } sMappedCount++; } - - return mMappedData; + + return mMappedIndexData ; } -void LLVertexBuffer::unmapBuffer() +void LLVertexBuffer::unmapBuffer(S32 type) { LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); - if (mMappedData || mMappedIndexData) + if (!useVBOs()) + { + return ; //nothing to unmap + } + + bool updated_all = false ; + if (mMappedData && mVertexLocked && type != TYPE_INDEX) { - if (useVBOs() && mLocked) + updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating + + if(sDisableVBOMapping) + { + stop_glerror(); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); + stop_glerror(); + } + else { stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); stop_glerror(); + + mMappedData = NULL; + } + + mVertexLocked = FALSE ; + sMappedCount--; + } + + if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) + { + if(sDisableVBOMapping) + { + stop_glerror(); + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); + stop_glerror(); + } + else + { + stop_glerror(); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); stop_glerror(); - /*if (!sMapped) - { - llerrs << "Redundantly unmapped VBO!" << llendl; - } - sMapped = FALSE;*/ - sMappedCount--; - - if (mUsage == GL_STATIC_DRAW_ARB) - { //static draw buffers can only be mapped a single time - //throw out client data (we won't be using it again) - mEmpty = TRUE; - mFinal = TRUE; - } - else + mMappedIndexData = NULL ; + } + + mIndexLocked = FALSE ; + sMappedCount--; + } + + if(updated_all) + { + if(mUsage == GL_STATIC_DRAW_ARB) + { + //static draw buffers can only be mapped a single time + //throw out client data (we won't be using it again) + mEmpty = TRUE; + mFinal = TRUE; + + if(sDisableVBOMapping) { - mEmpty = FALSE; + freeClientBuffer() ; } - - mMappedIndexData = NULL; - mMappedData = NULL; - - mLocked = FALSE; + } + else + { + mEmpty = FALSE; } } } @@ -939,15 +1092,16 @@ template <class T,S32 type> struct VertexBufferStrider strider_t& strider, S32 index) { - if (vbo.mapBuffer() == NULL) - { - llwarns << "mapBuffer failed!" << llendl; - return FALSE; - } - if (type == LLVertexBuffer::TYPE_INDEX) { S32 stride = sizeof(T); + + if (vbo.mapIndexBuffer() == NULL) + { + llwarns << "mapIndexBuffer failed!" << llendl; + return FALSE; + } + strider = (T*)(vbo.getMappedIndices() + index*stride); strider.setStride(0); return TRUE; @@ -955,6 +1109,13 @@ template <class T,S32 type> struct VertexBufferStrider else if (vbo.hasDataType(type)) { S32 stride = vbo.getStride(); + + if (vbo.mapVertexBuffer(type) == NULL) + { + llwarns << "mapVertexBuffer failed!" << llendl; + return FALSE; + } + strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride); strider.setStride(stride); return TRUE; @@ -1035,7 +1196,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride) //---------------------------------------------------------------------------- // Set for rendering -void LLVertexBuffer::setBuffer(U32 data_mask) +void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) { LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER); //set up pointers if the data mask is different ... @@ -1176,7 +1337,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { ll_fail("LLVertexBuffer::mapBuffer failed"); } - unmapBuffer(); + unmapBuffer(type); } else { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 94fa790957..c51ce7ac4e 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -80,7 +80,7 @@ public: static BOOL sUseStreamDraw; - static void initClass(bool use_vbo); + static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); static void clientCopy(F64 max_time = 0.005); //copy data from client to GL @@ -139,19 +139,24 @@ protected: void updateNumVerts(S32 nverts); void updateNumIndices(S32 nindices); virtual BOOL useVBOs() const; - void unmapBuffer(); - + void unmapBuffer(S32 type); + void freeClientBuffer() ; + void allocateClientVertexBuffer() ; + void allocateClientIndexBuffer() ; + public: LLVertexBuffer(U32 typemask, S32 usage); // map for data access - U8* mapBuffer(S32 access = -1); + U8* mapVertexBuffer(S32 type = -1, S32 access = -1); + U8* mapIndexBuffer(S32 access = -1); + // set for rendering - virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 + virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0 // allocate buffer void allocateBuffer(S32 nverts, S32 nindices, bool create); virtual void resizeBuffer(S32 newnverts, S32 newnindices); - + // Only call each getVertexPointer, etc, once before calling unmapBuffer() // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() // example: @@ -170,7 +175,7 @@ public: bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0); BOOL isEmpty() const { return mEmpty; } - BOOL isLocked() const { return mLocked; } + BOOL isLocked() const { return mVertexLocked || mIndexLocked; } S32 getNumVerts() const { return mNumVerts; } S32 getNumIndices() const { return mNumIndices; } S32 getRequestedVerts() const { return mRequestedNumVerts; } @@ -209,13 +214,14 @@ protected: U32 mGLIndices; // GL IBO handle U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) - BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory + 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 BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags) - BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. - S32 mOffsets[TYPE_MAX]; + BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) + S32 mOffsets[TYPE_MAX]; class DirtyRegion { @@ -240,13 +246,14 @@ public: static std::vector<U32> sDeleteList; typedef std::list<LLVertexBuffer*> buffer_list_t; + static BOOL sDisableVBOMapping; //disable glMapBufferARB static BOOL sEnableVBOs; + static BOOL sVBOActive; + static BOOL sIBOActive; static S32 sTypeOffsets[TYPE_MAX]; static U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLRenderBuffer; - static U32 sGLRenderIndices; - static BOOL sVBOActive; - static BOOL sIBOActive; + static U32 sGLRenderIndices; static U32 sLastMask; static U32 sAllocatedBytes; static U32 sBindCount; |