diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index d7d36d901de0e62d36ceaafb4222843adc6c095d..2ff1463b7cd129b24d40aec4ceb678586508b7e4 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -4173,7 +4173,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
 
 	for (S32 i = start_face; i <= end_face; i++)
 	{
-		const LLVolumeFace &face = getVolumeFace((U32)i);
+		LLVolumeFace &face = mVolumeFaces[i];
 
 		LLVector3 box_center = (face.mExtents[0] + face.mExtents[1]) / 2.f;
 		LLVector3 box_size   = face.mExtents[1] - face.mExtents[0];
@@ -4235,6 +4235,10 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
 
 						if (bi_normal != NULL)
 						{
+							if (!face.mBinormals)
+							{
+								face.createBinormals();
+							}
 							LLVector4* binormal = (LLVector4*) face.mBinormals;
 							if (binormal)
 							{
@@ -5174,7 +5178,6 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
 	LLVector4a* binorm = (LLVector4a*) mBinormals;
 	LLVector2* tc = (LLVector2*) mTexCoords;
 
-	S32	vtop = mNumVertices;
 	for(int gx = 0;gx<grid_size+1;gx++){
 		for(int gy = 0;gy<grid_size+1;gy++){
 			VertexData newVert;
@@ -5220,14 +5223,14 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
 				{
 					for(S32 i=5;i>=0;i--)
 					{
-						*out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]);
+						*out++ = ((gy*(grid_size+1))+gx+idxs[i]);
 					}		
 				}
 				else
 				{
 					for(S32 i=0;i<6;i++)
 					{
-						*out++ = (vtop+(gy*(grid_size+1))+gx+idxs[i]);
+						*out++ = ((gy*(grid_size+1))+gx+idxs[i]);
 					}
 				}
 			}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 23303b6d5c50c32663e67296213146f148057e20..18f7557da9772efc6f5bd336d680373e058498d3 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -261,10 +261,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 	}
 }
 
-void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
+void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
 {
-	llassert(mRequestedNumVerts >= 0);
-
 	if (start >= (U32) mRequestedNumVerts ||
 	    end >= (U32) mRequestedNumVerts)
 	{
@@ -279,6 +277,25 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 		llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
 	}
 
+	if (gDebugGL && !useVBOs())
+	{
+		U16* idx = ((U16*) getIndicesPointer())+indices_offset;
+		for (U32 i = 0; i < count; ++i)
+		{
+			if (idx[i] < start || idx[i] > end)
+			{
+				llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl;
+			}
+		}
+	}
+}
+
+void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
+{
+	validateRange(start, end, count, indices_offset);
+
+	llassert(mRequestedNumVerts >= 0);
+
 	if (mGLIndices != sGLRenderIndices)
 	{
 		llerrs << "Wrong index buffer bound." << llendl;
@@ -297,17 +314,6 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 
 	U16* idx = ((U16*) getIndicesPointer())+indices_offset;
 
-	if (gDebugGL && !useVBOs())
-	{
-		for (U32 i = 0; i < count; ++i)
-		{
-			if (idx[i] < start || idx[i] > end)
-			{
-				llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl;
-			}
-		}
-	}
-
 	stop_glerror();
 	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, 
 		idx);
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index c6fd0a9e3caa9384c37630b60feb8f682f43b960..47146a5ec4a237cb2f936303ea8309c1c676f54e 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -207,6 +207,11 @@ class LLVertexBuffer : public LLRefCount
 	void drawArrays(U32 mode, U32 offset, U32 count) const;
 	void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
 
+	//for debugging, validate data in given range is valid
+	void validateRange(U32 start, U32 end, U32 count, U32 offset) const;
+
+	
+
 protected:	
 	S32		mNumVerts;		// Number of vertices allocated
 	S32		mNumIndices;	// Number of indices allocated
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9b7cc041204ab00ebddafa754c409c6824d16f95..b0a4c02a4356fdd2bf0bf5614fde0bf85bb49d75 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6278,7 +6278,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>RenderDebugPipeline</key>
     <map>
@@ -7735,7 +7735,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>1</integer>
+      <integer>0</integer>
     </map>
   <key>RenderUseStreamVBO</key>
   <map>
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 77e8a6fdf9b72185bb6e43b70af6b54947a4f555..a65ee52fa15adb50f54f0f08e084d8237a831357 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -368,10 +368,13 @@ void LLFace::setDrawable(LLDrawable *drawable)
 
 void LLFace::setSize(const S32 num_vertices, const S32 num_indices)
 {
-	if (mGeomCount != num_vertices ||
+	//allocate vertices in blocks of 4 for alignment
+	S32 num_verts = (num_vertices + 0x3) & ~0x3;
+
+	if (mGeomCount != num_verts ||
 		mIndicesCount != num_indices)
 	{
-		mGeomCount    = num_vertices;
+		mGeomCount    = num_verts;
 		mIndicesCount = num_indices;
 		mVertexBuffer = NULL;
 		mLastVertexBuffer = NULL;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 77c38798d129f86a2f0dc1e4d7118fcdb0d61997..470c332b42bfa4d0582b10f0525d81a123e27d70 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -512,50 +512,6 @@ void LLSpatialGroup::checkStates()
 #endif
 }
 
-void validate_draw_info(LLDrawInfo& params)
-{
-#if LL_OCTREE_PARANOIA_CHECK
-	if (params.mVertexBuffer.isNull())
-	{
-		llerrs << "Draw batch has no vertex buffer." << llendl;
-	}
-	
-	//bad range
-	if (params.mStart >= params.mEnd)
-	{
-		llerrs << "Draw batch has invalid range." << llendl;
-	}
-	
-	if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts())
-	{
-		llerrs << "Draw batch has buffer overrun error." << llendl;
-	}
-	
-	if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices())
-	{
-		llerrs << "Draw batch has index buffer ovverrun error." << llendl;
-	}
-	
-	//bad indices
-	U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer();
-	if (indicesp)
-	{
-		for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++)
-		{
-			if (indicesp[i] < (U16)params.mStart)
-			{
-				llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl;
-			}
-			
-			if (indicesp[i] > (U16)params.mEnd)
-			{
-				llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl;
-			}
-		}
-	}
-#endif
-}
-
 void LLSpatialGroup::validateDrawMap()
 {
 #if LL_OCTREE_PARANOIA_CHECK
@@ -565,8 +521,8 @@ void LLSpatialGroup::validateDrawMap()
 		for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
 		{
 			LLDrawInfo& params = **j;
-			
-			validate_draw_info(params);
+		
+			params.validate();
 		}
 	}
 #endif
@@ -3379,18 +3335,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
 	mDistance(0.f),
 	mDrawMode(LLRender::TRIANGLES)
 {
-	mDebugColor = (rand() << 16) + rand();
-	if (mStart >= mVertexBuffer->getRequestedVerts() ||
-		mEnd >= mVertexBuffer->getRequestedVerts())
-	{
-		llerrs << "Invalid draw info vertex range." << llendl;
-	}
+	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
 
-	if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() ||
-		mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices())
-	{
-		llerrs << "Invalid draw info index range." << llendl;
-	}
+	mDebugColor = (rand() << 16) + rand();
 }
 
 LLDrawInfo::~LLDrawInfo()	
@@ -3406,6 +3353,11 @@ LLDrawInfo::~LLDrawInfo()
 	}
 }
 
+void LLDrawInfo::validate()
+{
+	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
+}
+
 LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
 {
 	return new LLVertexBuffer(type_mask, usage);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 67c33d5b0f706043886ff4bf856510e11ef877a4..9b252d1035063bfe3a08dd38cd4f150b018b82e7 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -75,6 +75,8 @@ class LLDrawInfo : public LLRefCount
 				BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
 	
 
+	void validate();
+
 	LLPointer<LLVertexBuffer> mVertexBuffer;
 	LLPointer<LLViewerTexture>     mTexture;
 	LLColor4U mGlowColor;
@@ -676,8 +678,6 @@ class LLHUDPartition : public LLBridgePartition
 	virtual void shift(const LLVector3 &offset);
 };
 
-void validate_draw_info(LLDrawInfo& params);
-
 extern const F32 SG_BOX_SIDE;
 extern const F32 SG_BOX_OFFSET;
 extern const F32 SG_BOX_RAD;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 7d80a66041e7e0c4ab1a6f11634a4e0c0f12c34c..d57a5350507b5e2efb290dbec6b8afddb4a8d88f 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3382,7 +3382,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		draw_vec[idx]->mCount += facep->getIndicesCount();
 		draw_vec[idx]->mEnd += facep->getGeomCount();
 		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
-		validate_draw_info(*draw_vec[idx]);
+		draw_vec[idx]->validate();
 		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
 		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
 	}
@@ -3406,12 +3406,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		}
 		draw_info->mExtents[0] = facep->mExtents[0];
 		draw_info->mExtents[1] = facep->mExtents[1];
-		validate_draw_info(*draw_info);
 
 		if (LLPipeline::sUseTriStrips)
 		{
 			draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;
 		}
+
+		draw_info->validate();
 	}
 }