Commits

Donald Kjer committed 8805dd3 Merge

Merge with viewer-development

Comments (0)

Files changed (7)

indra/llrender/llvertexbuffer.cpp

 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;
 void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 {
 	llassert(mRequestedNumIndices >= 0);
+
 	if (indices_offset >= (U32) mRequestedNumIndices ||
 	    indices_offset + count > (U32) mRequestedNumIndices)
 	{
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(mRequestedNumVerts >= 0);
+
 	if (first >= (U32) mRequestedNumVerts ||
 	    first + count > (U32) mRequestedNumVerts)
 	{
 }
 
 //static
-void LLVertexBuffer::initClass(bool use_vbo)
+void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 {
 	sEnableVBOs = use_vbo;
+	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
 	LLGLNamePool::registerPool(&sDynamicVBOPool);
 	LLGLNamePool::registerPool(&sDynamicIBOPool);
 	LLGLNamePool::registerPool(&sStreamVBOPool);
 	destroyGLBuffer();
 	destroyGLIndices();
 	sCount--;
+
+	llassert_always(!mMappedData && !mMappedIndexData) ;
 };
 
 //----------------------------------------------------------------------------
 	{
 		if (useVBOs())
 		{
+			freeClientBuffer() ;
+
 			if (mMappedData || mMappedIndexData)
 			{
 				llerrs << "Vertex buffer destroyed while mapped!" << llendl;
 	{
 		if (useVBOs())
 		{
+			freeClientBuffer() ;
+
 			if (mMappedData || mMappedIndexData)
 			{
 				llerrs << "Vertex buffer destroyed while mapped." << llendl;
 			}
-			releaseIndices();
+			releaseIndices();			
 		}
 		else
 		{
 
 	if (mResized && useVBOs())
 	{
+		freeClientBuffer() ;
 		setBuffer(0);
 	}
 }
 }
 
 //----------------------------------------------------------------------------
+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)
 			setBuffer(0);
 			mLocked = 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();
 		}
 		{
 			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
-			mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+			if(sDisableVBOMapping)
+			{
+				allocateClientIndexBuffer() ;
+			}
+			else
+			{
+				mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+			}
 			stop_glerror();
 		}
 
 			llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; 
 			llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
 
-			//--------------------
-			//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 ;
-			//--------------------
+			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)
+				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 << "Invalid GL vertex buffer bound: " << buff << llendl;
+				llerrs << "memory allocation for vertex data failed." << llendl ;
 			}
-
-			
-			llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
 		}
 
 		if (!mMappedIndexData)
 		{
 			log_glerror();
 
-			GLint buff;
-			glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
-			if ((GLuint)buff != mGLIndices)
+			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++;
 	{
 		if (useVBOs() && mLocked)
 		{
-			stop_glerror();
-			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
-			stop_glerror();
-			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
-			stop_glerror();
+			if(sDisableVBOMapping)
+			{
+				if(mMappedData)
+				{
+					stop_glerror();
+					glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
+					stop_glerror();
+				}
+				if(mMappedIndexData)
+				{
+					stop_glerror();
+					glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
+					stop_glerror();
+				}
+			}
+			else
+			{
+				stop_glerror();
+				glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+				stop_glerror();
+				glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+				stop_glerror();
+			}
 
 			/*if (!sMapped)
 			{
 				//throw out client data (we won't be using it again)
 				mEmpty = TRUE;
 				mFinal = TRUE;
+
+				if(sDisableVBOMapping)
+				{
+					freeClientBuffer() ;
+				}
 			}
 			else
 			{
 				mEmpty = FALSE;
 			}
 
-			mMappedIndexData = NULL;
-			mMappedData = NULL;
-			
+			if(!sDisableVBOMapping)
+			{
+				mMappedIndexData = NULL;
+				mMappedData = NULL;
+			}
 			mLocked = FALSE;
 		}
 	}

indra/llrender/llvertexbuffer.h

 
 	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
 	void	allocateBuffer(S32 nverts, S32 nindices, bool create);
 	virtual void resizeBuffer(S32 newnverts, S32 newnindices);
 		
+	void freeClientBuffer() ;
+	void allocateClientVertexBuffer() ;
+	void allocateClientIndexBuffer() ;
+	
 	// Only call each getVertexPointer, etc, once before calling unmapBuffer()
 	// call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
 	// example:
 	S32		mOffsets[TYPE_MAX];
 	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)
-
+	
 	class DirtyRegion
 	{
 	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;

indra/newview/app_settings/settings.xml

       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>RenderVBOMappingDisable</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable VBO glMapBufferARB</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
   <key>RenderUseStreamVBO</key>
   <map>
     <key>Comment</key>

indra/newview/llviewercontrol.cpp

 	return true;
 }
 
+static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue)
+{
+	if (gPipeline.isInit())
+	{
+		gPipeline.setDisableVBOMapping(newvalue.asBoolean());
+	}
+	return true;
+}
+
 static bool handleWLSkyDetailChanged(const LLSD&)
 {
 	if (gSky.mVOWLSkyp.notNull())
 	gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2));
+	gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _2));
 	gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
 	gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));

indra/newview/llviewerwindow.cpp

 	{
 		gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
 	}
-	LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"));
+	LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
 
 	if (LLFeatureManager::getInstance()->isSafe()
 		|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())

indra/newview/pipeline.cpp

 		}
 		
 		resetVertexBuffers();
-		LLVertexBuffer::initClass(use_vbo);
+		LLVertexBuffer::initClass(use_vbo, gSavedSettings.getBOOL("RenderVBOMappingDisable"));
+	}
+}
+
+void LLPipeline::setDisableVBOMapping(BOOL no_vbo_mapping)
+{
+	if (LLVertexBuffer::sEnableVBOs && no_vbo_mapping != LLVertexBuffer::sDisableVBOMapping)
+	{
+		if (no_vbo_mapping)
+		{
+			llinfos << "Disabling VBO glMapBufferARB." << llendl;
+		}
+		else
+		{ 
+			llinfos << "Enabling VBO glMapBufferARB." << llendl;
+		}
+		
+		resetVertexBuffers();
+		LLVertexBuffer::initClass(true, no_vbo_mapping);
 	}
 }
 

indra/newview/pipeline.h

 
 	void resetVertexBuffers(LLDrawable* drawable);
 	void setUseVBO(BOOL use_vbo);
+	void setDisableVBOMapping(BOOL no_vbo_mapping);
 	void generateImpostor(LLVOAvatar* avatar);
 	void bindScreenToTexture();
 	void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);