summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorCosmic Linden <cosmic@lindenlab.com>2024-02-08 13:24:16 -0800
committerCosmic Linden <cosmic@lindenlab.com>2024-02-08 13:24:16 -0800
commit9c6e351e05d7e0580700f040af8161da52de7a08 (patch)
tree0632ecc0349c5978634dccdfb38a4c985fa89a22 /indra
parent43b4159c8c2ca9ed1ff11399ac09e5496db9d271 (diff)
secondlife/viewer-issues#67: Improve PBR terrain loading robustness
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/lldrawpoolterrain.cpp78
-rw-r--r--indra/newview/llvlcomposition.cpp128
-rw-r--r--indra/newview/llvlcomposition.h16
3 files changed, 133 insertions, 89 deletions
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 3a943f27f6..8844f1d7e4 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -125,27 +125,29 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
tex->setBoostLevel(level);
tex->addTextureStats(stats);
- LLPointer<LLFetchedGLTFMaterial>& mat = compp->mDetailMaterials[i];
- llassert(mat.notNull());
- if (mat->mBaseColorTexture)
+ LLPointer<LLFetchedGLTFMaterial>& fetched_material = compp->mDetailMaterials[i];
+ if (fetched_material)
{
- mat->mBaseColorTexture->setBoostLevel(level);
- mat->mBaseColorTexture->addTextureStats(stats);
- }
- if (mat->mNormalTexture)
- {
- mat->mNormalTexture->setBoostLevel(level);
- mat->mNormalTexture->addTextureStats(stats);
- }
- if (mat->mMetallicRoughnessTexture)
- {
- mat->mMetallicRoughnessTexture->setBoostLevel(level);
- mat->mMetallicRoughnessTexture->addTextureStats(stats);
- }
- if (mat->mEmissiveTexture)
- {
- mat->mEmissiveTexture->setBoostLevel(level);
- mat->mEmissiveTexture->addTextureStats(stats);
+ if (fetched_material->mBaseColorTexture)
+ {
+ fetched_material->mBaseColorTexture->setBoostLevel(level);
+ fetched_material->mBaseColorTexture->addTextureStats(stats);
+ }
+ if (fetched_material->mNormalTexture)
+ {
+ fetched_material->mNormalTexture->setBoostLevel(level);
+ fetched_material->mNormalTexture->addTextureStats(stats);
+ }
+ if (fetched_material->mMetallicRoughnessTexture)
+ {
+ fetched_material->mMetallicRoughnessTexture->setBoostLevel(level);
+ fetched_material->mMetallicRoughnessTexture->addTextureStats(stats);
+ }
+ if (fetched_material->mEmissiveTexture)
+ {
+ fetched_material->mEmissiveTexture->setBoostLevel(level);
+ fetched_material->mEmissiveTexture->addTextureStats(stats);
+ }
}
}
}
@@ -234,7 +236,7 @@ void LLDrawPoolTerrain::drawLoop()
void LLDrawPoolTerrain::renderFullShader()
{
- const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(TRUE);
+ const BOOL use_local_materials = gLocalTerrainMaterials.materialsReady(true, false);
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
@@ -362,15 +364,24 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- LLPointer<LLFetchedGLTFMaterial> (*materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
+ LLPointer<LLFetchedGLTFMaterial> (*fetched_materials)[LLVLComposition::ASSET_COUNT] = &compp->mDetailMaterials;
+
+ constexpr U32 shader_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
+ constexpr U32 terrain_material_count = LLVLComposition::ASSET_COUNT;
+ llassert(shader_material_count == terrain_material_count);
if (local_materials)
{
// Override region terrain with the global local override terrain
- materials = &gLocalTerrainMaterials.mDetailMaterials;
+ fetched_materials = &gLocalTerrainMaterials.mDetailMaterials;
}
+ const LLGLTFMaterial* materials[terrain_material_count];
+ for (U32 i = 0; i < terrain_material_count; ++i)
+ {
+ materials[i] = (*fetched_materials)[i].get();
+ if (!materials[i]) { materials[i] = &LLGLTFMaterial::sDefault; }
+ }
- constexpr U32 terrain_material_count = 1 + LLViewerShaderMgr::TERRAIN_DETAIL3_BASE_COLOR - LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR;
S32 detail_basecolor[terrain_material_count];
S32 detail_normal[terrain_material_count];
S32 detail_metalrough[terrain_material_count];
@@ -378,12 +389,19 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
for (U32 i = 0; i < terrain_material_count; ++i)
{
- const LLFetchedGLTFMaterial* material = (*materials)[i].get();
+ LLViewerTexture* detail_basecolor_texturep = nullptr;
+ LLViewerTexture* detail_normal_texturep = nullptr;
+ LLViewerTexture* detail_metalrough_texturep = nullptr;
+ LLViewerTexture* detail_emissive_texturep = nullptr;
- LLViewerTexture *detail_basecolor_texturep = material->mBaseColorTexture;
- LLViewerTexture *detail_normal_texturep = material->mNormalTexture;
- LLViewerTexture *detail_metalrough_texturep = material->mMetallicRoughnessTexture;
- LLViewerTexture *detail_emissive_texturep = material->mEmissiveTexture;
+ const LLFetchedGLTFMaterial* fetched_material = (*fetched_materials)[i].get();
+ if (fetched_material)
+ {
+ detail_basecolor_texturep = fetched_material->mBaseColorTexture;
+ detail_normal_texturep = fetched_material->mNormalTexture;
+ detail_metalrough_texturep = fetched_material->mMetallicRoughnessTexture;
+ detail_emissive_texturep = fetched_material->mEmissiveTexture;
+ }
detail_basecolor[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
if (detail_basecolor_texturep)
@@ -483,7 +501,7 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
F32 minimum_alphas[terrain_material_count];
for (U32 i = 0; i < terrain_material_count; ++i)
{
- const LLFetchedGLTFMaterial* material = (*materials)[i].get();
+ const LLGLTFMaterial* material = materials[i];
base_color_factors[i] = material->mBaseColor;
metallic_factors[i] = material->mMetallicFactor;
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index 7c16ee4f61..c092eb82f3 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -75,12 +75,12 @@ LLTerrainMaterials::~LLTerrainMaterials()
BOOL LLTerrainMaterials::generateMaterials()
{
- if (texturesReady(TRUE))
+ if (texturesReady(true, true))
{
return TRUE;
}
- if (materialsReady(TRUE))
+ if (materialsReady(true, true))
{
return TRUE;
}
@@ -123,25 +123,41 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType()
{
LL_PROFILE_ZONE_SCOPED;
- const BOOL use_textures = texturesReady() || !materialsReady();
+ const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false);
return use_textures ? Type::TEXTURE : Type::PBR;
}
-BOOL LLTerrainMaterials::texturesReady(BOOL boost)
+bool LLTerrainMaterials::texturesReady(bool boost, bool strict)
{
- BOOL ready = TRUE;
- for (S32 i = 0; i < ASSET_COUNT; i++)
- {
- if (!textureReady(mDetailTextures[i], boost))
+ bool ready[ASSET_COUNT];
+ // *NOTE: Calls to textureReady may boost textures. Do not early-return.
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ ready[i] = textureReady(mDetailTextures[i], boost);
+ }
+
+ bool one_ready = false;
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ const bool current_ready = ready[i];
+ one_ready = one_ready || current_ready;
+ if (!current_ready && strict)
{
- ready = FALSE;
+ return false;
}
- }
- return ready;
+ }
+ return one_ready;
}
-BOOL LLTerrainMaterials::materialsReady(BOOL boost)
+bool LLTerrainMaterials::materialsReady(bool boost, bool strict)
{
+ bool ready[ASSET_COUNT];
+ // *NOTE: Calls to materialReady may boost materials/textures. Do not early-return.
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ ready[i] = materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost, strict);
+ }
+
#if 1
static bool sRenderTerrainPBREnabled = gSavedSettings.get<bool>("RenderTerrainPBREnabled");
static LLCachedControl<bool> sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false);
@@ -158,28 +174,31 @@ BOOL LLTerrainMaterials::materialsReady(BOOL boost)
}
if (defined)
{
- return TRUE;
+ return true;
}
}
#endif
- BOOL ready = TRUE;
- for (S32 i = 0; i < ASSET_COUNT; i++)
- {
- if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost))
+ bool one_ready = false;
+ for (S32 i = 0; i < ASSET_COUNT; i++)
+ {
+ const bool current_ready = ready[i];
+ one_ready = one_ready || current_ready;
+ if (!current_ready && strict)
{
- ready = FALSE;
+ return false;
}
}
- return ready;
+ return one_ready;
}
// Boost the texture loading priority
// Return true when ready to use (i.e. texture is sufficiently loaded)
// static
-BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost)
+bool LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost)
{
- llassert(tex.notNull());
+ llassert(tex);
+ if (!tex) { return false; }
if (tex->getDiscardLevel() < 0)
{
@@ -188,7 +207,7 @@ BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BO
tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
tex->addTextureStats(BASE_SIZE*BASE_SIZE);
}
- return FALSE;
+ return false;
}
if ((tex->getDiscardLevel() != 0 &&
(tex->getWidth() < BASE_SIZE ||
@@ -209,23 +228,23 @@ BOOL LLTerrainMaterials::textureReady(LLPointer<LLViewerFetchedTexture>& tex, BO
tex->setMinDiscardLevel(ddiscard);
tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority
}
- return FALSE;
+ return false;
}
if (tex->getComponents() == 0)
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
// Boost the loading priority of every known texture in the material
-// Return true when ready to use (i.e. material and all textures within are sufficiently loaded)
+// Return true when ready to use
// static
-BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost)
+bool LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial> &mat, bool &textures_set, bool boost, bool strict)
{
if (!mat || !mat->isLoaded())
{
- return FALSE;
+ return false;
}
// Material is loaded, but textures may not be
@@ -234,33 +253,39 @@ BOOL LLTerrainMaterials::materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bo
// *NOTE: These can sometimes be set to to nullptr due to
// updateTEMaterialTextures. For the sake of robustness, we emulate
// that fetching behavior by setting textures of null IDs to nullptr.
- mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
- mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+ mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+ mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
- mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
- textures_set = true;
+ mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+ textures_set = true;
- return FALSE;
+ return false;
}
- if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost))
- {
- return FALSE;
- }
- if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost))
- {
- return FALSE;
- }
- if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost))
+ // *NOTE: Calls to textureReady may boost textures. Do not early-return.
+ bool ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].isNull() || textureReady(mat->mBaseColorTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].isNull() || textureReady(mat->mNormalTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].isNull() ||
+ textureReady(mat->mMetallicRoughnessTexture, boost);
+ ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] =
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].isNull() || textureReady(mat->mEmissiveTexture, boost);
+
+ if (strict)
{
- return FALSE;
- }
- if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost))
- {
- return FALSE;
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (!ready[i])
+ {
+ return false;
+ }
+ }
}
- return TRUE;
+ return true;
}
@@ -427,16 +452,13 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y,
S32 st_data_size[ASSET_COUNT]; // for debugging
const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR;
- // *TODO: Remove this as it is reduandant computation (first and foremost
- // because getMaterialType() does something similar, but also... shouldn't
- // the textures/materials already be loaded by now?)
if (use_textures)
{
- if (!texturesReady()) { return FALSE; }
+ if (!texturesReady(true, true)) { return FALSE; }
}
else
{
- if (!materialsReady()) { return FALSE; }
+ if (!materialsReady(true, true)) { return FALSE; }
}
for (S32 i = 0; i < ASSET_COUNT; i++)
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index d59c0f95bb..73bfca6ed4 100644
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
@@ -61,12 +61,16 @@ public:
LLUUID getDetailAssetID(S32 asset);
virtual void setDetailAssetID(S32 asset, const LLUUID& id);
Type getMaterialType();
- BOOL texturesReady(BOOL boost = FALSE);
- BOOL materialsReady(BOOL boost = FALSE);
+ bool texturesReady(bool boost, bool strict);
+ // strict = true -> all materials must be sufficiently loaded
+ // strict = false -> at least one material must be loaded
+ bool materialsReady(bool boost, bool strict);
protected:
- static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
- static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
+ static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost);
+ // strict = true -> all materials must be sufficiently loaded
+ // strict = false -> at least one material must be loaded
+ static bool materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost, bool strict);
LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
bool mMaterialTexturesSet[ASSET_COUNT];
@@ -116,8 +120,8 @@ public:
BOOL getParamsReady() const { return mParamsReady; }
protected:
- static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
- static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
+ static bool textureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost = false);
+ static bool materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost = false);
BOOL mParamsReady = FALSE;
LLSurface *mSurfacep;