diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index dab7dc9ebf7e169154eb9ecdaa3f74eafe7c2ce3..31199980fcaeeb1824f4a0089a6a511f12df2b01 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -117,6 +117,7 @@ bool LLVertexBuffer::sMapped = false; bool LLVertexBuffer::sUseStreamDraw = true; bool LLVertexBuffer::sUseVAO = false; bool LLVertexBuffer::sPreferStreamDraw = false; +LLVertexBuffer* LLVertexBuffer::sUtilityBuffer = nullptr; U32 LLVBOPool::genBuffer() @@ -590,71 +591,80 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con return; } - unbind(); - - setupClientArrays(MAP_VERTEX | MAP_NORMAL); - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (shader) + if (!sUtilityBuffer) { - S32 loc = LLVertexBuffer::TYPE_VERTEX; - if (loc > -1) - { - glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV); - } - loc = LLVertexBuffer::TYPE_NORMAL; - if (loc > -1) - { - glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV); - } + sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW); + sUtilityBuffer->allocateBuffer(count, count, true); } - else + if (sUtilityBuffer->getNumVerts() < (S32) count) { - glVertexPointer(3, GL_FLOAT, 0, pos[0].mV); - glNormalPointer(GL_FLOAT, 0, norm[0].mV); + sUtilityBuffer->resizeBuffer(count, count); } + + LLStrider<LLVector3> vertex_strider; + LLStrider<LLVector3> normal_strider; + sUtilityBuffer->getVertexStrider(vertex_strider); + sUtilityBuffer->getNormalStrider(normal_strider); + vertex_strider.copyArray(0, pos.data(), count); + normal_strider.copyArray(0, norm.data(), count); + + sUtilityBuffer->setBuffer(MAP_VERTEX | MAP_NORMAL); LLGLSLShader::startProfile(); - glDrawArrays(sGLMode[mode], 0, count); + sUtilityBuffer->drawArrays(mode, 0, pos.size()); LLGLSLShader::stopProfile(count, mode); } //static -void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp) +void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp) { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - gGL.syncMatrices(); + if (num_vertices <= 0) + { + LL_WARNS() << "Called drawElements with 0 vertices" << LL_ENDL; + return; + } - U32 mask = LLVertexBuffer::MAP_VERTEX; - if (tc) + if (num_indices <= 0) { - mask = mask | LLVertexBuffer::MAP_TEXCOORD0; + LL_WARNS() << "Called drawElements with 0 indices" << LL_ENDL; + return; } - unbind(); - - setupClientArrays(mask); + gGL.syncMatrices(); - if (LLGLSLShader::sNoFixedFunction) + if (!sUtilityBuffer) { - S32 loc = LLVertexBuffer::TYPE_VERTEX; - glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); - - if (tc) - { - loc = LLVertexBuffer::TYPE_TEXCOORD0; - glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); - } + sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW); + sUtilityBuffer->allocateBuffer(num_vertices, num_indices, true); } - else + if (sUtilityBuffer->getNumVerts() < num_vertices || sUtilityBuffer->getNumIndices() < num_indices) + { + sUtilityBuffer->resizeBuffer(llmax(sUtilityBuffer->getNumVerts(), num_vertices), llmax(sUtilityBuffer->getNumIndices(), num_indices)); + } + + U32 mask = LLVertexBuffer::MAP_VERTEX; + + LLStrider<U16> index_strider; + LLStrider<LLVector4a> vertex_strider; + sUtilityBuffer->getIndexStrider(index_strider); + sUtilityBuffer->getVertexStrider(vertex_strider); + const S32 index_size = ((num_indices * sizeof(U16)) + 0xF) & ~0xF; + const S32 vertex_size = ((num_vertices * 4 * sizeof(F32)) + 0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*)index_strider.get(), (F32*)indicesp, index_size); + LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)pos, vertex_size); + if (tc) { - glTexCoordPointer(2, GL_FLOAT, 0, tc); - glVertexPointer(3, GL_FLOAT, 16, pos); + mask = mask | LLVertexBuffer::MAP_TEXCOORD0; + LLStrider<LLVector2> tc_strider; + sUtilityBuffer->getTexCoord0Strider(tc_strider); + const S32 tc_size = ((num_vertices * 2 * sizeof(F32)) + 0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*)tc_strider.get(), (F32*)tc, tc_size); } + sUtilityBuffer->setBuffer(mask); LLGLSLShader::startProfile(); - glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); + sUtilityBuffer->draw(mode, num_indices, 0); LLGLSLShader::stopProfile(num_indices, mode); } @@ -917,6 +927,8 @@ void LLVertexBuffer::cleanupClass() sStreamVBOPool.cleanup(); sDynamicVBOPool.cleanup(); sDynamicCopyVBOPool.cleanup(); + delete sUtilityBuffer; + sUtilityBuffer = nullptr; } //---------------------------------------------------------------------------- diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index bd99ef7feff9c71ce0da17db084618267aac63f9..89e83688fcf1a9c1ebab1354968dd7ceddf07072 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -135,7 +135,7 @@ class LLVertexBuffer : public LLRefCount, public LLTrace::MemTrackable<LLVertexB static void setupClientArrays(U32 data_mask); static void pushPositions(U32 mode, const LLVector4a* pos, U32 count); static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm); - static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp); + static void drawElements(U32 mode, const S32 num_vertices, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp); static void unbind(); //unbind any bound vertex buffer @@ -345,6 +345,9 @@ class LLVertexBuffer : public LLRefCount, public LLTrace::MemTrackable<LLVertexB static U32 sIndexCount; static U32 sBindCount; static U32 sSetCount; + +private: + static LLVertexBuffer* sUtilityBuffer; }; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 90088975bd07a8952451d972529c886e9f91196b..9c91bdf3b63e9cea00eab86867882528de9b8335 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -638,7 +638,7 @@ void renderFace(LLDrawable* drawable, LLFace *face) if (volume) { const LLVolumeFace& vol_face = volume->getVolumeFace(face->getTEOffset()); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mPositions, NULL, vol_face.mNumIndices, vol_face.mIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mNumVertices, vol_face.mPositions, NULL, vol_face.mNumIndices, vol_face.mIndices); } } } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 8c04cf80cfbf1d25b8271a5cb8fcc6f84ff9f99c..2f7d6590dd1d15d34c341db9efe249df9bde25f7 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1614,7 +1614,7 @@ void pushVerts(LLVolume* volume) for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { const LLVolumeFace& face = volume->getVolumeFace(i); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mNumVertices, face.mPositions, NULL, face.mNumIndices, face.mIndices); } } @@ -2575,11 +2575,11 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); gGL.diffuseColor4fv(color.mV); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices); } else