diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 0d6b15cfd3..3898cd5a47 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;
+S32 LLGLSLShader::sIndexedGLTFChannels = 0;
+bool LLGLSLShader::sIndexedLegacyMaterials = false;
U32 LLGLSLShader::sMaxGLTFMaterials = 0;
U32 LLGLSLShader::sMaxGLTFNodes = 0;
bool LLGLSLShader::sProfileEnabled = false;
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 704ecf90a1..ecae11511b 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -171,6 +171,17 @@ class LLGLSLShader
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
+ // Number of GLTF PBR materials that can be batched into one indexed draw call.
+ // Each material consumes four texture units (base color, normal, ORM, emissive),
+ // so this is roughly (available fragment texture units) / 4. See
+ // PASS_GLTF_PBR_INDEXED and LLVolumeGeometryManager::genDrawInfo.
+ static S32 sIndexedGLTFChannels;
+
+ // True once the indexed legacy (Blinn-Phong) material programs have loaded.
+ // Gates indexed POOL_MATERIALS batching (shares sIndexedGLTFChannels for the
+ // per-slot stride); independent so a material-shader failure doesn't disable PBR.
+ static bool sIndexedLegacyMaterials;
+
static U32 sMaxGLTFMaterials;
static U32 sMaxGLTFNodes;
diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml
index 48f2c098e5..960048deae 100644
--- a/indra/newview/app_settings/settings_alchemy.xml
+++ b/indra/newview/app_settings/settings_alchemy.xml
@@ -1235,6 +1235,17 @@
Value
1
+ RenderGLTFPBRBatching
+
RenderBloomThreshold