From 80ea30af1a8b38360f71c29cc45872c4399dab0d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 21 Jun 2024 13:13:08 -0500 Subject: #1769 gltf optimization pass (#1816) #1814 and #1517 Fix mirror update rate and occlusion culling --- indra/llrender/llglslshader.cpp | 6 ++- indra/llrender/llglslshader.h | 9 +++- indra/llrender/llrender.cpp | 2 + indra/llrender/llshadermgr.cpp | 2 + indra/llrender/llshadermgr.h | 2 + indra/llrender/llvertexbuffer.cpp | 106 +++++++++++++++++++++++++------------- indra/llrender/llvertexbuffer.h | 18 +++++++ 7 files changed, 105 insertions(+), 40 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index e22df46b28..25e4a88f28 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -54,6 +54,8 @@ using std::string; GLuint LLGLSLShader::sCurBoundShader = 0; LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL; S32 LLGLSLShader::sIndexedTextureChannels = 0; +U32 LLGLSLShader::sMaxGLTFMaterials = 0; +U32 LLGLSLShader::sMaxGLTFNodes = 0; bool LLGLSLShader::sProfileEnabled = false; std::set LLGLSLShader::sInstances; LLGLSLShader::defines_map_t LLGLSLShader::sGlobalDefines; @@ -978,7 +980,9 @@ bool LLGLSLShader::mapUniforms() const char* ubo_names[] = { "ReflectionProbes", // UB_REFLECTION_PROBES - "GLTFJoints", // UB_GLTF_JOINTS + "GLTFJoints", // UB_GLTF_JOINTS + "GLTFNodes", // UB_GLTF_NODES + "GLTFMaterials", // UB_GLTF_MATERIALS }; llassert(LL_ARRAY_SIZE(ubo_names) == NUM_UNIFORM_BLOCKS); diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index cc2ba0fcff..86e5625dca 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -147,8 +147,10 @@ public: enum UniformBlock : GLuint { - UB_REFLECTION_PROBES, - UB_GLTF_JOINTS, + UB_REFLECTION_PROBES, // "ReflectionProbes" + UB_GLTF_JOINTS, // "GLTFJoints" + UB_GLTF_NODES, // "GLTFNodes" + UB_GLTF_MATERIALS, // "GLTFMaterials" NUM_UNIFORM_BLOCKS }; @@ -163,6 +165,9 @@ public: static LLGLSLShader* sCurBoundShaderPtr; static S32 sIndexedTextureChannels; + static U32 sMaxGLTFMaterials; + static U32 sMaxGLTFNodes; + static void initProfile(); static void finishProfile(bool emit_report = true); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index cfefde3acc..a0209fab43 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -991,6 +991,8 @@ void LLRender::syncLightState() void LLRender::syncMatrices() { STOP_GLERROR; + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + static const U32 name[] = { LLShaderMgr::MODELVIEW_MATRIX, diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 574cf55a0e..a8e9f20b40 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1185,6 +1185,8 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("normal_texcoord"); // (GLTF) mReservedUniforms.push_back("metallic_roughness_texcoord"); // (GLTF) mReservedUniforms.push_back("occlusion_texcoord"); // (GLTF) + mReservedUniforms.push_back("gltf_node_id"); // (GLTF) + mReservedUniforms.push_back("gltf_material_id"); // (GLTF) mReservedUniforms.push_back("terrain_texture_transforms"); // (GLTF) diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index c00aff3a9a..fe6137c448 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -63,6 +63,8 @@ public: NORMAL_TEXCOORD, // "normal_texcoord" (GLTF) METALLIC_ROUGHNESS_TEXCOORD, // "metallic_roughness_texcoord" (GLTF) OCCLUSION_TEXCOORD, // "occlusion_texcoord" (GLTF) + GLTF_NODE_ID, // "gltf_node_id" (GLTF) + GLTF_MATERIAL_ID, // "gltf_material_id" (GLTF) TERRAIN_TEXTURE_TRANSFORMS, // "terrain_texture_transforms" (GLTF) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index f82ec30242..2eb7c21f77 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -806,6 +806,13 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi STOP_GLERROR; } +void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +{ + glDrawRangeElements(sGLMode[mode], start, end, count, mIndicesType, + (GLvoid*)(indices_offset * (size_t)mIndicesStride)); +} + + void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { drawRange(mode, 0, mNumVerts-1, count, indices_offset); @@ -1062,12 +1069,6 @@ bool LLVertexBuffer::updateNumVerts(U32 nverts) bool success = true; - if (nverts > 65536) - { - LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL; - nverts = 65536; - } - U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts); if (needed_size != mSize) @@ -1210,7 +1211,7 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) // end -- last byte to copy (NOT last byte + 1) // data -- data to be flushed // dst -- mMappedData or mMappedIndexData -static void flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst) +void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst) { #if LL_DARWIN LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy"); @@ -1218,6 +1219,8 @@ static void flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst) // copy into mapped buffer memcpy(dst+start, data, end-start+1); #else + llassert(target == GL_ARRAY_BUFFER ? sGLRenderBuffer == mGLBuffer : sGLRenderIndices == mGLIndices); + // skip mapped data and stream to GPU via glBufferSubData if (end != 0) { @@ -1627,81 +1630,51 @@ void LLVertexBuffer::setupVertexBuffer() void LLVertexBuffer::setPositionData(const LLVector4a* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, 0, sizeof(LLVector4a) * getNumVerts()-1, (U8*) data, mMappedData); } void LLVertexBuffer::setTexCoord0Data(const LLVector2* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + sTypeSize[TYPE_TEXCOORD0] * getNumVerts() - 1, (U8*)data, mMappedData); } void LLVertexBuffer::setTexCoord1Data(const LLVector2* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD1], mOffsets[TYPE_TEXCOORD1] + sTypeSize[TYPE_TEXCOORD1] * getNumVerts() - 1, (U8*)data, mMappedData); } void LLVertexBuffer::setColorData(const LLColor4U* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts() - 1, (U8*) data, mMappedData); } void LLVertexBuffer::setNormalData(const LLVector4a* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_NORMAL], mOffsets[TYPE_NORMAL] + sTypeSize[TYPE_NORMAL] * getNumVerts() - 1, (U8*) data, mMappedData); } void LLVertexBuffer::setTangentData(const LLVector4a* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TANGENT], mOffsets[TYPE_TANGENT] + sTypeSize[TYPE_TANGENT] * getNumVerts() - 1, (U8*) data, mMappedData); } void LLVertexBuffer::setWeight4Data(const LLVector4a* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_WEIGHT4], mOffsets[TYPE_WEIGHT4] + sTypeSize[TYPE_WEIGHT4] * getNumVerts() - 1, (U8*) data, mMappedData); } void LLVertexBuffer::setJointData(const U64* data) { -#if !LL_DARWIN - llassert(sGLRenderBuffer == mGLBuffer); -#endif flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_JOINT], mOffsets[TYPE_JOINT] + sTypeSize[TYPE_JOINT] * getNumVerts() - 1, (U8*) data, mMappedData); } void LLVertexBuffer::setIndexData(const U16* data) { -#if !LL_DARWIN - llassert(sGLRenderIndices == mGLIndices); -#endif flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16) * getNumIndices() - 1, (U8*) data, mMappedIndexData); } void LLVertexBuffer::setIndexData(const U32* data) { -#if !LL_DARWIN - llassert(sGLRenderIndices == mGLIndices); -#endif if (mIndicesType != GL_UNSIGNED_INT) { // HACK -- vertex buffers are initialized as 16-bit indices, but can be switched to 32-bit indices mIndicesType = GL_UNSIGNED_INT; @@ -1711,3 +1684,62 @@ void LLVertexBuffer::setIndexData(const U32* data) flush_vbo(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U32) * getNumIndices() - 1, (U8*)data, mMappedIndexData); } +void LLVertexBuffer::setPositionData(const LLVector4a* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, offset * sizeof(LLVector4a), (offset + count) * sizeof(LLVector4a) - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setNormalData(const LLVector4a* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_NORMAL] + offset * sTypeSize[TYPE_NORMAL], mOffsets[TYPE_NORMAL] + (offset + count) * sTypeSize[TYPE_NORMAL] - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setTexCoord0Data(const LLVector2* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0] + offset * sTypeSize[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + (offset + count) * sTypeSize[TYPE_TEXCOORD0] - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setTexCoord1Data(const LLVector2* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD1] + offset * sTypeSize[TYPE_TEXCOORD1], mOffsets[TYPE_TEXCOORD1] + (offset + count) * sTypeSize[TYPE_TEXCOORD1] - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setColorData(const LLColor4U* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR] + offset * sTypeSize[TYPE_COLOR], mOffsets[TYPE_COLOR] + (offset + count) * sTypeSize[TYPE_COLOR] - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setTangentData(const LLVector4a* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TANGENT] + offset * sTypeSize[TYPE_TANGENT], mOffsets[TYPE_TANGENT] + (offset + count) * sTypeSize[TYPE_TANGENT] - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setWeight4Data(const LLVector4a* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_WEIGHT4] + offset * sTypeSize[TYPE_WEIGHT4], mOffsets[TYPE_WEIGHT4] + (offset + count) * sTypeSize[TYPE_WEIGHT4] - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setJointData(const U64* data, U32 offset, U32 count) +{ + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_JOINT] + offset * sTypeSize[TYPE_JOINT], mOffsets[TYPE_JOINT] + (offset + count) * sTypeSize[TYPE_JOINT] - 1, (U8*)data, mMappedData); +} + +void LLVertexBuffer::setIndexData(const U16* data, U32 offset, U32 count) +{ + flush_vbo(GL_ELEMENT_ARRAY_BUFFER, offset * sizeof(U16), (offset + count) * sizeof(U16) - 1, (U8*)data, mMappedIndexData); +} + +void LLVertexBuffer::setIndexData(const U32* data, U32 offset, U32 count) +{ + if (mIndicesType != GL_UNSIGNED_INT) + { // HACK -- vertex buffers are initialized as 16-bit indices, but can be switched to 32-bit indices + mIndicesType = GL_UNSIGNED_INT; + mIndicesStride = 4; + mNumIndices /= 2; + } + flush_vbo(GL_ELEMENT_ARRAY_BUFFER, offset * sizeof(U32), (offset + count) * sizeof(U32) - 1, (U8*)data, mMappedIndexData); +} + + + + diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 601096abf9..49500e28ce 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -202,6 +202,18 @@ public: void setIndexData(const U16* data); void setIndexData(const U32* data); + void setPositionData(const LLVector4a* data, U32 offset, U32 count); + void setNormalData(const LLVector4a* data, U32 offset, U32 count); + void setTangentData(const LLVector4a* data, U32 offset, U32 count); + void setWeight4Data(const LLVector4a* data, U32 offset, U32 count); + void setJointData(const U64* data, U32 offset, U32 count); + void setTexCoord0Data(const LLVector2* data, U32 offset, U32 count); + void setTexCoord1Data(const LLVector2* data, U32 offset, U32 count); + void setColorData(const LLColor4U* data, U32 offset, U32 count); + void setIndexData(const U16* data, U32 offset, U32 count); + void setIndexData(const U32* data, U32 offset, U32 count); + + U32 getNumVerts() const { return mNumVerts; } U32 getNumIndices() const { return mNumIndices; } @@ -219,6 +231,10 @@ public: void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + // draw without syncing matrices. If you're positive there have been no matrix + // since the last call to syncMatrices, this is much faster than drawRange + void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + //for debugging, validate data in given range is valid bool validateRange(U32 start, U32 end, U32 count, U32 offset) const; @@ -256,6 +272,8 @@ private: friend class LLNavShapeVBOManager; friend class LLNavMeshVBOManager; + void flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst); + LLVertexBuffer(U32 typemask, U32 usage) : LLVertexBuffer(typemask) {} -- cgit v1.2.3