diff options
| author | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-01 19:36:13 +0200 | 
|---|---|---|
| committer | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-01 19:36:13 +0200 | 
| commit | 149b2d88dd75bddf1cb3e9927c4e8fcc84e263e1 (patch) | |
| tree | b02a4d2775cec34281b637a6f4d1ae0c40faa976 | |
| parent | fec6bbddc371b2d1e0aa41d39a1b3dfaa8fb2016 (diff) | |
MAINT-7228 Vertex buffer allocation failure handling
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 64 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 12 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llfloaterimagepreview.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 50 | ||||
| -rw-r--r-- | indra/newview/llvoground.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llvopartgroup.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llvosky.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llvotree.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 35 | ||||
| -rw-r--r-- | indra/newview/llvowater.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llvowlsky.cpp | 19 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 9 | 
15 files changed, 266 insertions, 66 deletions
| diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 607bbf3b3b..d4dfb373f0 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1167,7 +1167,7 @@ void LLVertexBuffer::releaseIndices()  	sGLCount--;  } -void LLVertexBuffer::createGLBuffer(U32 size) +bool LLVertexBuffer::createGLBuffer(U32 size)  {  	if (mGLBuffer)  	{ @@ -1176,9 +1176,11 @@ void LLVertexBuffer::createGLBuffer(U32 size)  	if (size == 0)  	{ -		return; +		return true;  	} +	bool sucsess = true; +  	mEmpty = true;  	mMappedDataUsingVBOs = useVBOs(); @@ -1196,9 +1198,15 @@ void LLVertexBuffer::createGLBuffer(U32 size)  		mSize = size;  		claimMem(mSize);  	} + +	if (!mMappedData) +	{ +		sucsess = false; +	} +	return sucsess;  } -void LLVertexBuffer::createGLIndices(U32 size) +bool LLVertexBuffer::createGLIndices(U32 size)  {  	if (mGLIndices)  	{ @@ -1207,9 +1215,11 @@ void LLVertexBuffer::createGLIndices(U32 size)  	if (size == 0)  	{ -		return; +		return true;  	} +	bool sucsess = true; +  	mEmpty = true;  	//pad by 16 bytes for aligned copies @@ -1230,6 +1240,12 @@ void LLVertexBuffer::createGLIndices(U32 size)  		mGLIndices = ++gl_buffer_idx;  		mIndicesSize = size;  	} + +	if (!mMappedIndexData) +	{ +		sucsess = false; +	} +	return sucsess;  }  void LLVertexBuffer::destroyGLBuffer() @@ -1272,10 +1288,12 @@ void LLVertexBuffer::destroyGLIndices()  	//unbind();  } -void LLVertexBuffer::updateNumVerts(S32 nverts) +bool LLVertexBuffer::updateNumVerts(S32 nverts)  {  	llassert(nverts >= 0); +	bool sucsess = true; +  	if (nverts > 65536)  	{  		LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL; @@ -1286,31 +1304,37 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)  	if (needed_size > mSize || needed_size <= mSize/2)  	{ -		createGLBuffer(needed_size); +		sucsess &= createGLBuffer(needed_size);  	}  	sVertexCount -= mNumVerts;  	mNumVerts = nverts;  	sVertexCount += mNumVerts; + +	return sucsess;  } -void LLVertexBuffer::updateNumIndices(S32 nindices) +bool LLVertexBuffer::updateNumIndices(S32 nindices)  {  	llassert(nindices >= 0); +	bool sucsess = true; +  	U32 needed_size = sizeof(U16) * nindices;  	if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)  	{ -		createGLIndices(needed_size); +		sucsess &= createGLIndices(needed_size);  	}  	sIndexCount -= mNumIndices;  	mNumIndices = nindices;  	sIndexCount += mNumIndices; + +	return sucsess;  } -void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) +bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  {  	stop_glerror(); @@ -1320,10 +1344,12 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  		LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;  	} -	updateNumVerts(nverts); -	updateNumIndices(nindices); +	bool sucsess = true; + +	sucsess &= updateNumVerts(nverts); +	sucsess &= updateNumIndices(nindices); -	if (create && (nverts || nindices)) +	if (sucsess && create && (nverts || nindices))  	{  		//actually allocate space for the vertex buffer if using VBO mapping  		flush(); @@ -1336,6 +1362,8 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  			setupVertexArray();  		}  	} + +	return sucsess;  }  static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO"); @@ -1457,15 +1485,17 @@ void LLVertexBuffer::setupVertexArray()  	unbind();  } -void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) +bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)  {  	llassert(newnverts >= 0);  	llassert(newnindices >= 0); -	updateNumVerts(newnverts);		 -	updateNumIndices(newnindices); +	bool sucsess = true; + +	sucsess &= updateNumVerts(newnverts);		 +	sucsess &= updateNumIndices(newnindices); -	if (useVBOs()) +	if (sucsess && useVBOs())  	{  		flush(); @@ -1474,6 +1504,8 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)  			setupVertexArray();  		}  	} + +	return sucsess;  }  bool LLVertexBuffer::useVBOs() const diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index c05fd01595..bd27296eb6 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -214,12 +214,12 @@ protected:  	bool	bindGLArray();  	void	releaseBuffer();  	void	releaseIndices(); -	void	createGLBuffer(U32 size); -	void	createGLIndices(U32 size); +	bool	createGLBuffer(U32 size); +	bool	createGLIndices(U32 size);  	void 	destroyGLBuffer();  	void 	destroyGLIndices(); -	void	updateNumVerts(S32 nverts); -	void	updateNumIndices(S32 nindices);  +	bool	updateNumVerts(S32 nverts); +	bool	updateNumIndices(S32 nindices);   	void	unmapBuffer();  public: @@ -235,8 +235,8 @@ public:  	virtual void	setBuffer(U32 data_mask); 	// calls  setupVertexBuffer() if data_mask is not 0  	void flush(); //flush pending data to GL memory  	// allocate buffer -	void	allocateBuffer(S32 nverts, S32 nindices, bool create); -	virtual void resizeBuffer(S32 newnverts, S32 newnindices); +	bool	allocateBuffer(S32 nverts, S32 nindices, bool create); +	virtual bool 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() diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index b221221f16..bb5c86f705 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1485,15 +1485,34 @@ void LLDrawPoolAvatar::getRiggedGeometry(  		{  			buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);  		} -		buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); + +		if (!buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true)) +		{ +			LL_WARNS("LLDrawPoolAvatar") << "Failed to allocate Vertex Buffer to " +				<< vol_face.mNumVertices << " vertices and " +				<< vol_face.mNumIndices << " indices" << LL_ENDL; +			// allocate dummy triangle +			buffer->allocateBuffer(1, 3, true); +			memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); +			memset((U8*)buffer->getIndicesPointer(), 0, buffer->getIndicesSize()); +		}  	}  	else  	{          //resize existing buffer -		buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); +		if(!buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices)) +		{ +			LL_WARNS("LLDrawPoolAvatar") << "Failed to resize Vertex Buffer to " +				<< vol_face.mNumVertices << " vertices and " +				<< vol_face.mNumIndices << " indices" << LL_ENDL; +			// allocate dummy triangle +			buffer->resizeBuffer(1, 3); +			memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); +			memset((U8*)buffer->getIndicesPointer(), 0, buffer->getIndicesSize()); +		}  	} -	face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); +	face->setSize(buffer->getNumVerts(), buffer->getNumIndices());  	face->setVertexBuffer(buffer);  	U16 offset = 0; diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 52e678ce24..a9e4d752ac 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -801,7 +801,13 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)  	U32 num_vertices = vf.mNumVertices;  	mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0, 0); -	mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); +	if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE)) +	{ +		LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to" +			<< num_vertices << " vertices and " +			<< num_indices << " indices" << LL_ENDL; +		// We are likely to crash on getTexCoord0Strider() +	}  	LLStrider<LLVector3> vertex_strider;  	LLStrider<LLVector3> normal_strider; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index b3885bf36c..da84a6b8f8 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -2568,13 +2568,21 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  				if (sizes[i*2+1] > 0 && sizes[i*2] > 0)  				{ -					buff->allocateBuffer(sizes[i*2+1], sizes[i*2], true); +					if (!buff->allocateBuffer(sizes[i * 2 + 1], sizes[i * 2], true)) +					{ +						// Todo: find a way to stop preview in this case instead of crashing +						LL_ERRS() << "Failed buffer allocation during preview LOD generation." +							<< " Vertices: " << sizes[i * 2 + 1] +							<< " Indices: " << sizes[i * 2] << LL_ENDL; +					}  					buff->setBuffer(type_mask);  					glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, (U8*) buff->getIndicesPointer());  					stop_gloderror();  				}  				else -				{ //this face was eliminated, create a dummy triangle (one vertex, 3 indices, all 0) +				{ +					// This face was eliminated or we failed to allocate buffer, +					// attempt to create a dummy triangle (one vertex, 3 indices, all 0)  					buff->allocateBuffer(1, 3, true);  					memset((U8*) buff->getMappedData(), 0, buff->getSize());  					memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize()); @@ -3322,7 +3330,13 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  			vb = new LLVertexBuffer(mask, 0); -			vb->allocateBuffer(num_vertices, num_indices, TRUE); +			if (!vb->allocateBuffer(num_vertices, num_indices, TRUE)) +			{ +				// We are likely to crash due this failure, if this happens, find a way to gracefully stop preview +				LL_WARNS() << "Failed to allocate Vertex Buffer for model preview " +					<< num_vertices << " vertices and " +					<< num_indices << " indices" << LL_ENDL; +			}  			LLStrider<LLVector3> vertex_strider;  			LLStrider<LLVector3> normal_strider; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 0fd36766b3..df5756cf11 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -451,16 +451,32 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)  				(group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))  			{  				group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); -				group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); +				if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true)) +				{ +					LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to " +						<< vertex_count << " vertices and " +						<< index_count << " indices" << LL_ENDL; +					group->mVertexBuffer = NULL; +					group->mBufferMap.clear(); +				}  				stop_glerror();  			}  			else  			{ -				group->mVertexBuffer->resizeBuffer(vertex_count, index_count); +				if (!group->mVertexBuffer->resizeBuffer(vertex_count, index_count)) +				{ +					// Is likely to cause a crash. If this gets triggered find a way to avoid it (don't forget to reset face) +					LL_WARNS() << "Failed to resize Vertex Buffer on rebuild to " +						<< vertex_count << " vertices and " +						<< index_count << " indices" << LL_ENDL; +					group->mVertexBuffer = NULL; +					group->mBufferMap.clear(); +				}  				stop_glerror();  			}  		} +		if (group->mVertexBuffer)  		{  			LL_RECORD_BLOCK_TIME(FTM_GET_GEOMETRY);  			getGeometry(group); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cc708ea275..33ab188704 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2085,7 +2085,17 @@ void LLVOAvatar::updateMeshData()  			if(!facep->getVertexBuffer())  			{  				buff = new LLVertexBufferAvatar(); -				buff->allocateBuffer(num_vertices, num_indices, TRUE); +				if (!buff->allocateBuffer(num_vertices, num_indices, TRUE)) +				{ +					LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to " +						<< num_vertices << " vertices and " +						<< num_indices << " indices" << LL_ENDL; +					// Attempt to create a dummy triangle (one vertex, 3 indices, all 0) +					facep->setSize(1, 3); +					buff->allocateBuffer(1, 3, true); +					memset((U8*) buff->getMappedData(), 0, buff->getSize()); +					memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize()); +				}  				facep->setVertexBuffer(buff);  			}  			else @@ -2097,7 +2107,15 @@ void LLVOAvatar::updateMeshData()  				}  				else  				{ -					buff->resizeBuffer(num_vertices, num_indices); +					if (!buff->resizeBuffer(num_vertices, num_indices)) +					{ +						LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL; +						// Attempt to create a dummy triangle (one vertex, 3 indices, all 0) +						facep->setSize(1, 3); +						buff->resizeBuffer(1, 3); +						memset((U8*) buff->getMappedData(), 0, buff->getSize()); +						memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize()); +					}  				}  			} @@ -2109,20 +2127,24 @@ void LLVOAvatar::updateMeshData()  				LL_ERRS() << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << LL_ENDL;  			} -			for(S32 k = j ; k < part_index ; k++) +			if (num_vertices == buff->getNumVerts() && num_indices == buff->getNumIndices())  			{ -				bool rigid = false; -				if (k == MESH_ID_EYEBALL_LEFT || -					k == MESH_ID_EYEBALL_RIGHT) -				{ //eyeballs can't have terse updates since they're never rendered with -					//the hardware skinning shader -					rigid = true; -				} -				 -				LLViewerJoint* mesh = getViewerJoint(k); -				if (mesh) +				for(S32 k = j ; k < part_index ; k++)  				{ -					mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); +					bool rigid = false; +					if (k == MESH_ID_EYEBALL_LEFT || +						k == MESH_ID_EYEBALL_RIGHT) +					{ +						//eyeballs can't have terse updates since they're never rendered with +						//the hardware skinning shader +						rigid = true; +					} +				 +					LLViewerJoint* mesh = getViewerJoint(k); +					if (mesh) +					{ +						mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); +					}  				}  			} diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index c1273e684c..71a7623fb4 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -94,7 +94,12 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)  	{  		face->setSize(5, 12);  		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); -		buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); +		if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer for VOGround to " +				<< face->getGeomCount() << " vertices and " +				<< face->getIndicesCount() << " indices" << LL_ENDL; +		}  		face->setGeomIndex(0);  		face->setIndicesIndex(0);  		face->setVertexBuffer(buff); diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 6e5db526b0..f7b21338f8 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -61,7 +61,15 @@ void LLVOPartGroup::restoreGL()  	//TODO: optimize out binormal mask here.  Specular and normal coords as well.  	sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);  	U32 count = LL_MAX_PARTICLE_COUNT; -	sVB->allocateBuffer(count*4, count*6, true); +	if (!sVB->allocateBuffer(count*4, count*6, true)) +	{ +		LL_WARNS() << "Failed to allocate Vertex Buffer to " +			<< count*4 << " vertices and " +			<< count * 6 << " indices" << LL_ENDL; +		// we are likelly to crash at following getTexCoord0Strider(), so unref and return +		sVB = NULL; +		return; +	}  	//indices and texcoords are always the same, set once  	LLStrider<U16> indicesp; @@ -764,7 +772,7 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)  	addGeometryCount(group, vertex_count, index_count); -	if (vertex_count > 0 && index_count > 0) +	if (vertex_count > 0 && index_count > 0 && LLVOPartGroup::sVB)  	{   		group->mBuilt = 1.f;  		//use one vertex buffer for all groups diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 4dab213fa0..86b380087a 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1462,7 +1462,12 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons  	{  		facep->setSize(4, 6);	  		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); -		buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); +		if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " +				<< facep->getGeomCount() << " vertices and " +				<< facep->getIndicesCount() << " indices" << LL_ENDL; +		}  		facep->setGeomIndex(0);  		facep->setIndicesIndex(0);  		facep->setVertexBuffer(buff); @@ -1869,7 +1874,12 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	{  		face->setSize(quads * 4, quads * 6);  		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); -		buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); +		if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " +				<< face->getGeomCount() << " vertices and " +				<< face->getIndicesCount() << " indices" << LL_ENDL; +		}  		face->setIndicesIndex(0);  		face->setGeomIndex(0);  		face->setVertexBuffer(buff); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 4dcc267e96..5193d3bb0e 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -525,7 +525,14 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)  		}  		mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, 0); -		mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE); +		if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer on update to " +				<< max_vertices << " vertices and " +				<< max_indices << " indices" << LL_ENDL; +			mReferenceBuffer = NULL; //unref +			return TRUE; +		}  		LLStrider<LLVector3> vertices;  		LLStrider<LLVector3> normals; @@ -883,7 +890,21 @@ void LLVOTree::updateMesh()  	LLFace* facep = mDrawable->getFace(0);  	if (!facep) return;  	LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); -	buff->allocateBuffer(vert_count, index_count, TRUE); +	if (!buff->allocateBuffer(vert_count, index_count, TRUE)) +	{ +		LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to " +			<< vert_count << " vertices and " +			<< index_count << " indices" << LL_ENDL; +		buff->allocateBuffer(1, 3, true); +		memset((U8*)buff->getMappedData(), 0, buff->getSize()); +		memset((U8*)buff->getIndicesPointer(), 0, buff->getIndicesSize()); +		facep->setSize(1, 3); +		facep->setVertexBuffer(buff); +		mReferenceBuffer->flush(); +		buff->flush(); +		return; +	} +  	facep->setVertexBuffer(buff);  	LLStrider<LLVector3> vertices; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 90ba814a15..f77b48ff80 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5638,18 +5638,25 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac  		}  		//create vertex buffer -		LLVertexBuffer* buffer = NULL; +		LLPointer<LLVertexBuffer> buffer;  		{  			LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_ALLOCATE);  			buffer = createVertexBuffer(mask, buffer_usage); -			buffer->allocateBuffer(geom_count, index_count, TRUE); +			if(!buffer->allocateBuffer(geom_count, index_count, TRUE)) +			{ +				LL_WARNS() << "Failed to allocate group Vertex Buffer to " +					<< geom_count << " vertices and " +					<< index_count << " indices" << LL_ENDL; +				buffer = NULL; +			}  		} -		group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); - - -		buffer_map[mask][*face_iter].push_back(buffer); +		if (buffer) +		{ +			group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); +			buffer_map[mask][*face_iter].push_back(buffer); +		}  		//add face geometry @@ -5657,8 +5664,17 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac  		U16 index_offset = 0;  		while (face_iter < i) -		{ //update face indices for new buffer +		{ +			//update face indices for new buffer  			facep = *face_iter; +			if (buffer.isNull()) +			{ +				// Bulk allocation failed +				facep->setVertexBuffer(buffer); +				facep->setSize(0, 0); // mark as no geometry +				++face_iter; +				continue; +			}  			facep->setIndicesIndex(indices_index);  			facep->setGeomIndex(index_offset);  			facep->setVertexBuffer(buffer);	 @@ -5983,7 +5999,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac  			++face_iter;  		} -		buffer->flush(); +		if (buffer) +		{ +			buffer->flush(); +		}  	}  	group->mBufferMap[mask].clear(); diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 9ce16a1674..ccda92810e 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -155,14 +155,22 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)  	if (!buff || !buff->isWriteable())  	{  		buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); -		buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); +		if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer on water update to " +				<< face->getGeomCount() << " vertices and " +				<< face->getIndicesCount() << " indices" << LL_ENDL; +		}  		face->setIndicesIndex(0);  		face->setGeomIndex(0);  		face->setVertexBuffer(buff);  	}  	else  	{ -		buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount()); +		if (!buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount())) +		{ +			LL_WARNS() << "Failed to resize Vertex Buffer" << LL_ENDL; +		}  	}  	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 16130b5ca7..3b9b96e9f1 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -313,7 +313,12 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)  #if DOME_SLICES  	{  		mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); -		mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE); +		if (!mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer on sky update to " +				<< getFanNumVerts() << " vertices and " +				<< getFanNumIndices() << " indices" << LL_ENDL; +		}  		BOOL success = mFanVerts->getVertexStrider(vertices)  			&& mFanVerts->getTexCoord0Strider(texCoords) @@ -375,7 +380,12 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)  			const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack);  			llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes); -			segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE); +			if (!segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE)) +			{ +				LL_WARNS() << "Failed to allocate Vertex Buffer on update to " +					<< num_verts_this_seg << " vertices and " +					<< num_indices_this_seg << " indices" << LL_ENDL; +			}  			// lock the buffer  			BOOL success = segment->getVertexStrider(vertices) @@ -777,7 +787,10 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)  	if (mStarsVerts.isNull() || !mStarsVerts->isWriteable())  	{  		mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); -		mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE); +		if (!mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer for Sky to " << getStarsNumVerts() * 6 << " vertices" << LL_ENDL; +		}  	}  	BOOL success = mStarsVerts->getVertexStrider(verticesp) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 19487c3230..d3be5fea1a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3903,7 +3903,14 @@ void LLPipeline::postSort(LLCamera& camera)  	}  	//flush particle VB -	LLVOPartGroup::sVB->flush(); +	if (LLVOPartGroup::sVB) +	{ +		LLVOPartGroup::sVB->flush(); +	} +	else +	{ +		LL_WARNS_ONCE() << "Missing particle buffer" << LL_ENDL; +	}  	/*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty(); | 
