# Conflicts:
#	indra/newview/llviewertexturelist.cpp
master
Ansariel 2024-09-05 01:05:15 +02:00
commit 95707d7c13
19 changed files with 162 additions and 95 deletions

View File

@ -1659,3 +1659,19 @@ namespace LLError
sLocalizedOutOfMemoryWarning = message;
}
}
void crashdriver(void (*callback)(int*))
{
// The LLERROR_CRASH macro used to have inline code of the form:
//int* make_me_crash = NULL;
//*make_me_crash = 0;
// But compilers are getting smart enough to recognize that, so we must
// assign to an address supplied by a separate source file. We could do
// the assignment here in crashdriver() -- but then BugSplat would group
// all LL_ERRS() crashes as the fault of this one function, instead of
// identifying the specific LL_ERRS() source line. So instead, do the
// assignment in a lambda in the caller's source. We just provide the
// nullptr target.
callback(nullptr);
}

View File

@ -420,11 +420,9 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
#define LL_NEWLINE '\n'
// Use this only in LL_ERRS or in a place that LL_ERRS may not be used
#define LLERROR_CRASH \
{ \
int* make_me_crash = (int*)0xDEADBEEFDEADBEEFUL; \
*make_me_crash = 0; \
exit(*make_me_crash); \
#define LLERROR_CRASH \
{ \
crashdriver([](int* ptr){ *ptr = 0; exit(*ptr); }); \
}
#define LL_ENDL \
@ -526,4 +524,7 @@ LL_DEBUGS("SomeTag") performs the locking and map-searching ONCE, then caches
the result in a static variable.
*/
// used by LLERROR_CRASH
void crashdriver(void (*)(int*));
#endif // LL_LLERROR_H

View File

@ -311,47 +311,6 @@ private:
// access our private members.
friend class LLParamSingleton<DERIVED_TYPE>;
// Scoped lock on the mutex associated with this LLSingleton<T>
class Locker
{
public:
Locker(): mLock(getMutex()) {}
private:
// Use a recursive_mutex in case of constructor circularity. With a
// non-recursive mutex, that would result in deadlock.
typedef std::recursive_mutex mutex_t;
// LLSingleton<T> must have a distinct instance of sMutex for every
// distinct T. It's tempting to consider hoisting Locker up into
// LLSingletonBase. Don't do it.
//
// sMutex must be a function-local static rather than a static member. One
// of the essential features of LLSingleton and friends is that they must
// support getInstance() even when the containing module's static
// variables have not yet been runtime-initialized. A mutex requires
// construction. A static class member might not yet have been
// constructed.
//
// We could store a dumb mutex_t*, notice when it's NULL and allocate a
// heap mutex -- but that's vulnerable to race conditions. And we can't
// defend the dumb pointer with another mutex.
//
// We could store a std::atomic<mutex_t*> -- but a default-constructed
// std::atomic<T> does not contain a valid T, even a default-constructed
// T! Which means std::atomic, too, requires runtime initialization.
//
// But a function-local static is guaranteed to be initialized exactly
// once, the first time control reaches that declaration.
static mutex_t& getMutex()
{
static mutex_t sMutex;
return sMutex;
}
std::unique_lock<mutex_t> mLock;
};
// LLSingleton only supports a nullary constructor. However, the specific
// purpose for its subclass LLParamSingleton is to support Singletons
// requiring constructor arguments. constructSingleton() supports both use

View File

@ -1048,6 +1048,7 @@ void LLGLManager::initWGL()
GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
}
mHasNVXGpuMemoryInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
{
@ -1188,7 +1189,7 @@ bool LLGLManager::initGL()
// U32 old_vram = mVRAM;
// mVRAM = 0;
#if LL_WINDOWS
#if 0 //LL_WINDOWS <FS:Ansariel> Special handling down below
if (mHasAMDAssociations)
{
GLuint gl_gpus_count = wglGetGPUIDsAMD(0, 0);
@ -1217,6 +1218,17 @@ bool LLGLManager::initGL()
LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
}
}
else if (mHasNVXGpuMemoryInfo)
{
GLint mem_kb = 0;
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &mem_kb);
mVRAM = mem_kb / 1024;
if (mVRAM != 0)
{
LL_WARNS("RenderInit") << "VRAM Detected (NVXGpuMemoryInfo):" << mVRAM << LL_ENDL;
}
}
#endif
// <FS:Beq> remove this so that we can attempt to use driver specifics
@ -1241,7 +1253,7 @@ bool LLGLManager::initGL()
// </FS:Beq>
// Ultimate fallbacks for linux and mesa
if (mHasNVXMemInfo && mVRAM == 0)
if (mHasNVXGpuMemoryInfo && mVRAM == 0)
{
S32 dedicated_memory;
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
@ -1249,6 +1261,32 @@ bool LLGLManager::initGL()
LL_INFOS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL;
}
if (mHasAMDAssociations && mVRAM == 0)
{
GLuint gl_gpus_count = wglGetGPUIDsAMD(0, 0);
if (gl_gpus_count > 0)
{
GLuint* ids = new GLuint[gl_gpus_count];
wglGetGPUIDsAMD(gl_gpus_count, ids);
GLuint mem_mb = 0;
for (U32 i = 0; i < gl_gpus_count; i++)
{
wglGetGPUInfoAMD(ids[i],
WGL_GPU_RAM_AMD,
GL_UNSIGNED_INT,
sizeof(GLuint),
&mem_mb);
if (mVRAM < mem_mb)
{
// basically pick the best AMD and trust driver/OS to know to switch
mVRAM = mem_mb;
}
}
}
LL_INFOS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
}
if (mHasATIMemInfo && mVRAM == 0)
{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
S32 meminfo[4];
@ -1462,7 +1500,6 @@ void LLGLManager::initExtensions()
// <FS:Zi> Linux support
//#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;

View File

@ -109,7 +109,7 @@ public:
// Vendor-specific extensions
bool mHasAMDAssociations = false;
bool mHasNVXMemInfo = false;
bool mHasNVXGpuMemoryInfo = false;
bool mHasATIMemInfo = false;
bool mIsAMD;

View File

@ -10507,6 +10507,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderCanUseTerrainBakeShaders</key>
<map>
<key>Comment</key>
<string>Hardware has support for Terrain Bake shaders</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderClass1MemoryBandwidth</key>
<map>
<key>Comment</key>
@ -12899,7 +12910,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Comment</key>
<string>EXPERIMENTAL: Enable PBR Terrain texture transforms.</string>
<key>Persist</key>
<integer>1</integer>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>

View File

@ -99,10 +99,13 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v,
{
l = normalize(lv);
h = normalize(l + v);
nh = clamp(dot(n, h), 0.0, 1.0);
nl = clamp(dot(n, l), 0.0, 1.0);
nv = clamp(dot(n, v), 0.0, 1.0);
vh = clamp(dot(v, h), 0.0, 1.0);
// lower bound to avoid divide by zero
float eps = 0.000001;
nh = clamp(dot(n, h), eps, 1.0);
nl = clamp(dot(n, l), eps, 1.0);
nv = clamp(dot(n, v), eps, 1.0);
vh = clamp(dot(v, h), eps, 1.0);
lightDist = length(lv);
}

View File

@ -208,7 +208,7 @@ RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
RenderLocalLightCount 1 1024
RenderTransparentWater 1 1
RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0

View File

@ -208,7 +208,7 @@ RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
RenderLocalLightCount 1 1024
RenderTransparentWater 1 1
RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0

View File

@ -135,7 +135,7 @@ RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
RenderTerrainPBRDetail 1 -1
RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 0
@ -172,7 +172,7 @@ RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 0
@ -209,7 +209,7 @@ RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTerrainPBRDetail 1 0
RenderTerrainPBRPlanarSampleCount 1 1
RenderTransparentWater 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 2.0
RenderDeferredSSAO 1 0

View File

@ -919,7 +919,9 @@ bool LLAppViewer::init()
// inits from settings.xml and from strings.xml
if (!initConfiguration())
{
LL_ERRS("InitInfo") << "initConfiguration() failed." << LL_ENDL;
LL_WARNS("InitInfo") << "initConfiguration() failed." << LL_ENDL;
// quit immediately
return false;
}
LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ;
@ -1104,7 +1106,9 @@ bool LLAppViewer::init()
if (!initHardwareTest())
{
// Early out from user choice.
LL_ERRS("InitInfo") << "initHardwareTest() failed." << LL_ENDL;
LL_WARNS("InitInfo") << "initHardwareTest() failed." << LL_ENDL;
// quit immediately
return false;
}
LL_INFOS("InitInfo") << "Hardware test initialization done." << LL_ENDL ;
@ -1120,7 +1124,9 @@ bool LLAppViewer::init()
{
std::string msg = LLTrans::getString("MBUnableToAccessFile");
OSMessageBox(msg.c_str(), LLStringUtil::null, OSMB_OK);
LL_ERRS("InitInfo") << "Failed to init cache" << LL_ENDL;
LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
// quit immediately
return false;
}
LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
@ -1159,7 +1165,9 @@ bool LLAppViewer::init()
if (!gGLManager.mHasRequirements)
{
// Already handled with a MBVideoDrvErr
LL_ERRS("InitInfo") << "gGLManager.mHasRequirements is false." << LL_ENDL;
LL_WARNS("InitInfo") << "gGLManager.mHasRequirements is false." << LL_ENDL;
// quit immediately
return false;
}
// Without SSE2 support we will crash almost immediately, warn here.
@ -1169,7 +1177,9 @@ bool LLAppViewer::init()
// all hell breaks lose.
std::string msg = LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2");
OSMessageBox(msg.c_str(), LLStringUtil::null, OSMB_OK);
LL_ERRS("InitInfo") << "SSE2 is not supported" << LL_ENDL;
LL_WARNS("InitInfo") << "SSE2 is not supported" << LL_ENDL;
// quit immediately
return false;
}
// alert the user if they are using unsupported hardware
@ -4732,7 +4742,6 @@ void LLAppViewer::forceQuit()
LLApp::setQuitting();
}
//TODO: remove
void LLAppViewer::fastQuit(S32 error_code)
{
// finish pending transfers

View File

@ -287,7 +287,7 @@ bool LLFloaterRegionInfo::postBuild()
mInfoPanels.push_back(panel);
static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
static LLCachedControl<bool> feature_pbr_terrain_transforms_enabled(gSavedSettings, "RenderTerrainPBRTransformsEnabled", false);
if (!feature_pbr_terrain_transforms_enabled || !feature_pbr_terrain_enabled)
if (!feature_pbr_terrain_transforms_enabled() || !feature_pbr_terrain_enabled())
{
panel->buildFromFile("panel_region_terrain.xml");
}
@ -1880,7 +1880,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
const bool textures_ready = compp->makeTexturesReady(false, false);
const bool materials_ready = feature_pbr_terrain_enabled && compp->makeMaterialsReady(false, false);
const bool materials_ready = feature_pbr_terrain_enabled() && compp->makeMaterialsReady(false, false);
bool set_texture_swatches;
bool set_material_swatches;
@ -1910,7 +1910,7 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
{
material_type_to_ctrl(mMaterialTypeCtrl, material_type);
updateForMaterialType();
mMaterialTypeCtrl->setVisible(feature_pbr_terrain_enabled);
mMaterialTypeCtrl->setVisible(feature_pbr_terrain_enabled());
}
if (set_texture_swatches)
@ -2133,7 +2133,7 @@ bool LLPanelRegionTerrainInfo::sendUpdate()
// POST to ModifyRegion endpoint, if enabled
static LLCachedControl<bool> feature_pbr_terrain_transforms_enabled(gSavedSettings, "RenderTerrainPBRTransformsEnabled", false);
if (material_type == LLTerrainMaterials::Type::PBR && feature_pbr_terrain_transforms_enabled)
if (material_type == LLTerrainMaterials::Type::PBR && feature_pbr_terrain_transforms_enabled())
{
LLTerrainMaterials composition;
for (S32 i = 0; i < LLTerrainMaterials::ASSET_COUNT; ++i)

View File

@ -1225,6 +1225,9 @@ F32 gpu_benchmark()
return -1.f;
}
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// disable mipmaps and use point filtering to cause cache misses
gGL.getTexUnit(0)->setHasMipMaps(false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
if (alloc_timer.getElapsedTimeF32() > time_limit)
{
@ -1341,7 +1344,8 @@ F32 gpu_benchmark()
F32 seconds = ms/1000.f;
F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn;
F32 samples_sec = (F32)((samples_drawn/1000000000.0)/seconds);
F64 gpixels_drawn = samples_drawn / 1000000000.0;
F32 samples_sec = (F32)(gpixels_drawn/seconds);
gbps = samples_sec*4; // 4 bytes per sample
LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;

View File

@ -4137,6 +4137,12 @@ bool enable_gltf_upload()
return enable_gltf_save_as();
}
bool enable_terrain_local_paintmap()
{
static LLCachedControl<bool> can_use_shaders(gSavedSettings, "RenderCanUseTerrainBakeShaders", true);
return can_use_shaders;
}
class LLSelfRemoveAllAttachments : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@ -13115,6 +13121,7 @@ void initialize_menus()
enable.add("EnableGLTF", boost::bind(&enable_gltf));
enable.add("EnableGLTFSaveAs", boost::bind(&enable_gltf_save_as));
enable.add("EnableGLTFUpload", boost::bind(&enable_gltf_upload));
enable.add("EnableTerrainLocalPaintMap", std::bind(&enable_terrain_local_paintmap));
enable.add("EnableBridgeFunction", boost::bind(&enable_bridge_function)); // <FS:CR>
view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible");

View File

@ -3190,7 +3190,14 @@ bool LLViewerShaderMgr::loadShadersInterface()
const U32 value_range = (1 << bit_depth) - 1;
shader->addPermutation("TERRAIN_PAINT_PRECISION", llformat("%d", value_range));
success = success && shader->createShader();
llassert(success);
//llassert(success);
if (!success)
{
LL_WARNS() << "Failed to create shader '" << shader->mName << "', disabling!" << LL_ENDL;
gSavedSettings.setBOOL("RenderCanUseTerrainBakeShaders", false);
// continue as if this shader never happened
success = true;
}
}
if (success)

View File

@ -547,6 +547,9 @@ void send_viewer_stats(bool include_preferences)
agent["run_time"] = run_time;
}
// report time the viewer has spent in the foreground
agent["foreground_time"] = gForegroundTime.getElapsedTimeF32();
// send fps only for time app spends in foreground
agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
agent["version"] = LLVersionInfo::instance().getChannelAndVersion();

View File

@ -525,46 +525,55 @@ void LLViewerTexture::updateClass()
F32 over_pct = (used - target) / target;
bool is_low = over_pct > 0.f;
bool is_sys_low = isSystemMemoryLow();
bool is_low = is_sys_low || over_pct > 0.f;
if (isSystemMemoryLow())
static bool was_low = false;
static bool was_sys_low = false;
if (is_low && !was_low)
{
is_low = true;
// System RAM is low -> ramp up discard bias over time to free memory
// slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately)
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f);
if (is_sys_low)
{ // if we're low on system memory, emergency purge off screen textures to avoid a death spiral
LL_WARNS() << "Low system memory detected, emergency downrezzing off screen textures" << LL_ENDL;
for (auto& image : gTextureList)
{
gTextureList.updateImageDecodePriority(image, false /*will modify gTextureList otherwise!*/);
}
}
}
was_low = is_low;
was_sys_low = is_sys_low;
if (is_low)
{
// ramp up discard bias over time to free memory
LL_DEBUGS("TextureMemory") << "System memory is low, use more aggressive discard bias." << LL_ENDL;
if (sEvaluationTimer.getElapsedTimeF32() > MEMORY_CHECK_WAIT_TIME)
{
static LLCachedControl<F32> low_mem_min_discard_increment(gSavedSettings, "RenderLowMemMinDiscardIncrement", .1f);
sDesiredDiscardBias += (F32) low_mem_min_discard_increment * (F32) gFrameIntervalSeconds;
sDesiredDiscardBias += (F32)low_mem_min_discard_increment * (F32)gFrameIntervalSeconds;
sEvaluationTimer.reset();
}
}
else
{
LL_DEBUGS("TextureMemory") << "System memory is plentiful, act normally." << LL_ENDL;
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.f + over_pct);
// don't execute above until the slam to 1.5 has a chance to take effect
sEvaluationTimer.reset();
// lower discard bias over time when free memory is available
if (sDesiredDiscardBias > 1.f && over_pct < 0.f)
{
sDesiredDiscardBias -= gFrameIntervalSeconds * 0.01f;
}
}
static bool was_low = false;
if (is_low && !was_low)
{
LL_WARNS() << "Low system memory detected, emergency downrezzing off screen textures" << LL_ENDL;
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f);
for (auto& image : gTextureList)
{
gTextureList.updateImageDecodePriority(image, false /*will modify gTextureList otherwise!*/);
}
}
was_low = is_low;
// set to max discard bias if the window has been backgrounded for a while
static bool was_backgrounded = false;
static LLFrameTimer backgrounded_timer;

View File

@ -977,7 +977,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
// this is an alternative to decaying mMaxVirtualSize over time
// that keeps textures from continously downrezzing and uprezzing in the background
if (LLViewerTexture::sDesiredDiscardBias > 2.f ||
if (LLViewerTexture::sDesiredDiscardBias > 1.5f ||
(!on_screen && LLViewerTexture::sDesiredDiscardBias > 1.f))
{
imagep->mMaxVirtualSize = 0.f;

View File

@ -4989,9 +4989,10 @@
<menu_item_separator/>
<menu_item_call
enabled="true"
label="Create Local Paintmap"
name="Create Local Paintmap">
<menu_item_call.on_enable
function="EnableTerrainLocalPaintMap"/>
<menu_item_call.on_click
function="Advanced.TerrainCreateLocalPaintMap" />
</menu_item_call>