summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2024-06-21 13:13:08 -0500
committerGitHub <noreply@github.com>2024-06-21 13:13:08 -0500
commit80ea30af1a8b38360f71c29cc45872c4399dab0d (patch)
treedb07a706a4c896b11b8abca8a7d8815797a8d0be /indra/llrender
parent9fb9e8f33cb33a1535f43b4be030009c192ea92b (diff)
#1769 gltf optimization pass (#1816)
#1814 and #1517 Fix mirror update rate and occlusion culling
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llglslshader.cpp6
-rw-r--r--indra/llrender/llglslshader.h9
-rw-r--r--indra/llrender/llrender.cpp2
-rw-r--r--indra/llrender/llshadermgr.cpp2
-rw-r--r--indra/llrender/llshadermgr.h2
-rw-r--r--indra/llrender/llvertexbuffer.cpp106
-rw-r--r--indra/llrender/llvertexbuffer.h18
7 files changed, 105 insertions, 40 deletions
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*> 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)
{}