Potential optimization for dense VBO arrays.

This commit is contained in:
Shyotl
2011-08-19 01:29:04 -05:00
parent d2ae02a855
commit e4b640887a

View File

@@ -1080,15 +1080,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
} }
} }
LLStrider<LLVector3> vertices; LLStrider<LLVector3> vert;
LLStrider<LLVector2> tex_coords; LLStrider<LLVector2> tex_coords;
LLStrider<LLVector2> tex_coords2; LLStrider<LLVector2> tex_coords2;
LLStrider<LLVector3> normals; LLStrider<LLVector3> norm;
LLStrider<LLColor4U> colors; LLStrider<LLColor4U> colors;
LLStrider<LLVector3> binormals; LLStrider<LLVector3> binorm;
LLStrider<U16> indicesp; LLStrider<U16> indicesp;
#if MESH_ENABLED #if MESH_ENABLED
LLStrider<LLVector4> weights; LLStrider<LLVector4> wght;
#endif //MESH_ENABLED #endif //MESH_ENABLED
BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME);
@@ -1117,8 +1117,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (!tep) rebuild_color = FALSE; // can't get color when tep is NULL if (!tep) rebuild_color = FALSE; // can't get color when tep is NULL
U8 bump_code = tep ? tep->getBumpmap() : 0; U8 bump_code = tep ? tep->getBumpmap() : 0;
BOOL is_static = mDrawablep->isStatic(); BOOL is_static = mDrawablep->isStatic();
BOOL is_global = is_static; BOOL is_global = is_static;
@@ -1157,7 +1155,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
// INDICES // INDICES
if (full_rebuild) if (full_rebuild)
{ {
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range); mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
__m128i* dst = (__m128i*) indicesp.get(); __m128i* dst = (__m128i*) indicesp.get();
__m128i* src = (__m128i*) vf.mIndices; __m128i* src = (__m128i*) vf.mIndices;
@@ -1175,11 +1173,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{ {
indicesp[i] = vf.mIndices[i]+index_offset; indicesp[i] = vf.mIndices[i]+index_offset;
} }
if (map_range)
{
mVertexBuffer->setBuffer(0);
}
} }
LLMatrix4a mat_normal; LLMatrix4a mat_normal;
@@ -1400,7 +1393,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
} }
} }
//mVertexBuffer->setBuffer(0);
} }
else else
{ //either bump mapped or in atlas, just do the whole expensive loop { //either bump mapped or in atlas, just do the whole expensive loop
@@ -1458,8 +1450,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
} }
} }
//mVertexBuffer->setBuffer(0);
if (do_bump) if (do_bump)
{ {
@@ -1493,7 +1483,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
*tex_coords2++ = tc; *tex_coords2++ = tc;
} }
//mVertexBuffer->setBuffer(0);
} }
} }
} }
@@ -1501,74 +1490,158 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_pos) if (rebuild_pos)
{ {
llassert(num_vertices > 0); llassert(num_vertices > 0);
mVertexBuffer->getVertexStrider(vertices, mGeomIndex); mVertexBuffer->getVertexStrider(vert, mGeomIndex);
LLMatrix4a mat_vert; LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in); mat_vert.loadu(mat_vert_in);
LLVector4a* src = vf.mPositions; LLVector4a* src = vf.mPositions;
if(!vert.isStrided())
{
LLVector4a* vertices = (LLVector4a*) vert.get();
LLVector4a* dst = vertices;
LLVector4a* end = dst+num_vertices;
do
{
mat_vert.affineTransform(*src++, *dst++);
}
while(dst < end);
F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0);
F32 *index_dst = (F32*) vertices;
F32 *index_end = (F32*) end;
index_dst += 3;
index_end += 3;
do
{
*index_dst = index;
index_dst += 4;
}
while (index_dst < index_end);
S32 aligned_pad_vertices = mGeomCount - num_vertices;
LLVector4a* last_vec = end - 1;
while (aligned_pad_vertices > 0)
{
--aligned_pad_vertices;
*dst++ = *last_vec;
}
}
else
{
LLVector4a position; LLVector4a position;
F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0);
for (S32 i = 0; i < num_vertices; i++) for (S32 i = 0; i < num_vertices; i++)
{ {
mat_vert.affineTransform(src[i], position); mat_vert.affineTransform(src[i], position);
//Still using getF32ptr() because if the array is strided then theres no guarantee vertices will aligned, which LLVector4a requires //Still using getF32ptr() because if the array is strided then theres no guarantee vertices will aligned, which LLVector4a requires
vertices[i].set(position.getF32ptr()); //This assignment and the one below are oddly sensitive. Suspect something's off around here. vert[i].set(position.getF32ptr()); //This assignment and the one below are oddly sensitive. Suspect something's off around here.
vertices[i].mV[3] = index; vert[i].mV[3] = index;
} }
for (S32 i = num_vertices; i < mGeomCount; i++) for (S32 i = num_vertices; i < mGeomCount; i++)
{ {
memcpy(vertices[i].mV,vertices[num_vertices-1].mV,sizeof(LLVector4)); memcpy(vert[i].mV,vert[num_vertices-1].mV,sizeof(LLVector4));
}
} }
//mVertexBuffer->setBuffer(0);
} }
if (rebuild_normal) if (rebuild_normal)
{ {
mVertexBuffer->getNormalStrider(normals, mGeomIndex); mVertexBuffer->getNormalStrider(norm, mGeomIndex);
if(!norm.isStrided())
{
LLVector4a* normals = (LLVector4a*) norm.get();
for (S32 i = 0; i < num_vertices; i++) for (S32 i = 0; i < num_vertices; i++)
{ {
LLVector4a normal; LLVector4a normal;
mat_normal.rotate(vf.mNormals[i], normal); mat_normal.rotate(vf.mNormals[i], normal);
normal.normalize3fast(); normal.normalize3fast();
normals[i].set(normal.getF32ptr()); normals[i] = normal;
}
}
else
{
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a normal;
mat_normal.rotate(vf.mNormals[i], normal);
normal.normalize3fast();
norm[i].set(normal.getF32ptr());
}
} }
//mVertexBuffer->setBuffer(0);
} }
if (rebuild_binormal) if (rebuild_binormal)
{ {
mVertexBuffer->getBinormalStrider(binormals, mGeomIndex); mVertexBuffer->getBinormalStrider(binorm, mGeomIndex);
if(!binorm.isStrided())
{
LLVector4a* binormals = (LLVector4a*) binorm.get();
for (S32 i = 0; i < num_vertices; i++) for (S32 i = 0; i < num_vertices; i++)
{ {
LLVector4a binormal; LLVector4a binormal;
mat_normal.rotate(vf.mBinormals[i], binormal); mat_normal.rotate(vf.mBinormals[i], binormal);
binormal.normalize3fast(); binormal.normalize3fast();
binormals[i].set(binormal.getF32ptr()); binormals[i] = binormal;
}
}
else
{
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a binormal;
mat_normal.rotate(vf.mBinormals[i], binormal);
binormal.normalize3fast();
binorm[i].set(binormal.getF32ptr());
}
} }
//mVertexBuffer->setBuffer(0);
} }
#if MESH_ENABLED #if MESH_ENABLED
if (rebuild_weights && vf.mWeights) if (rebuild_weights && vf.mWeights)
{ {
mVertexBuffer->getWeight4Strider(weights, mGeomIndex); mVertexBuffer->getWeight4Strider(wght, mGeomIndex);
weights.assignArray((U8*) vf.mWeights, sizeof(vf.mWeights[0]), num_vertices); wght.assignArray((U8*) vf.mWeights, sizeof(vf.mWeights[0]), num_vertices);
//mVertexBuffer->setBuffer(0);
} }
#endif //MESH_ENABLED #endif //MESH_ENABLED
if (rebuild_color) if (rebuild_color)
{ {
mVertexBuffer->getColorStrider(colors, mGeomIndex); mVertexBuffer->getColorStrider(colors, mGeomIndex);
if(!colors.isStrided())
{
LLVector4a src;
U32 vec[4];
vec[0] = vec[1] = vec[2] = vec[3] = color.mAll;
src.loadua((F32*) vec);
LLVector4a* dst = (LLVector4a*) colors.get();
S32 num_vecs = num_vertices/4;
if (num_vertices%4 > 0)
{
++num_vecs;
}
for (S32 i = 0; i < num_vecs; i++)
{
dst[i] = src;
}
}
else
{
for (S32 i = 0; i < num_vertices; i++) for (S32 i = 0; i < num_vertices; i++)
{ {
colors[i] = color; colors[i] = color;
} }
}
//mVertexBuffer->setBuffer(0);
} }
if (rebuild_tcoord) if (rebuild_tcoord)