viewer#799 getAvailableVRAMMegabytes cleanup

master
Andrey Kleshchev 2024-05-06 22:48:24 +03:00 committed by Andrey Kleshchev
parent 7d87e41bbd
commit ea268fcd48
10 changed files with 5 additions and 182 deletions

View File

@ -164,8 +164,6 @@ public:
virtual F32 getPixelAspectRatio() = 0;
virtual void setNativeAspectRatio(F32 aspect) = 0;
// query VRAM usage
virtual U32 getAvailableVRAMMegabytes() = 0;
virtual void setMaxVRAMMegabytes(U32 max_vram) = 0;
virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode)

View File

@ -101,7 +101,6 @@ public:
/*virtual*/ F32 getPixelAspectRatio() override { return 1.0f; }
/*virtual*/ void setNativeAspectRatio(F32 ratio) override {}
U32 getAvailableVRAMMegabytes() override { return 4096; }
void setMaxVRAMMegabytes(U32 max_vram) override {}
/*virtual*/ void *getPlatformWindow() override { return 0; }

View File

@ -118,7 +118,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
U32 fsaa_samples,
U32 max_vram)
: LLWindow(NULL, fullscreen, flags)
, mMaxVRAM(max_vram)
{
// *HACK: During window construction we get lots of OS events for window
// reshape, activate, etc. that the viewer isn't ready to handle.
@ -1255,21 +1254,6 @@ F32 LLWindowMacOSX::getPixelAspectRatio()
return 1.f;
}
U32 LLWindowMacOSX::getAvailableVRAMMegabytes() {
// MTL (and MoltenVK) has some additional gpu data, such as recommendedMaxWorkingSetSize and currentAllocatedSize.
// But these are not available for OpenGL and/or our current mimimum OS version.
// So we will estimate.
static const U32 mb = 1024*1024;
// We're asked for total available gpu memory, but we only have allocation info on texture usage. So estimate by doubling that.
static const U32 total_factor = 2; // estimated total/textures
U32 total_vram = gGLManager.mVRAM;
if (mMaxVRAM)
{
total_vram = llmin(mMaxVRAM, total_vram);
}
return total_vram - (LLImageGL::getTextureBytesAllocated() * total_factor/mb);
}
//static SInt32 oldWindowLevel;
// MBW -- XXX -- There's got to be a better way than this. Find it, please...

View File

@ -100,9 +100,7 @@ public:
F32 getPixelAspectRatio() override;
void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; }
// query VRAM usage
/*virtual*/ U32 getAvailableVRAMMegabytes() override;
virtual void setMaxVRAMMegabytes(U32 max_vram) override { mMaxVRAM = max_vram; }
virtual void setMaxVRAMMegabytes(U32 max_vram) override {}
void beforeDialog() override;
void afterDialog() override;
@ -226,7 +224,6 @@ protected:
bool mMinimized;
U32 mFSAASamples;
bool mForceRebuild;
U32 mMaxVRAM;
S32 mDragOverrideCursor;

View File

@ -370,14 +370,6 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
//clean up DXGI/D3D resources
void cleanupDX();
// call periodically to update available VRAM
void updateVRAMUsage();
U32 getAvailableVRAMMegabytes()
{
return mAvailableVRAM;
}
/// called by main thread to post work to this window thread
template <typename CALLABLE>
void post(CALLABLE&& func)
@ -425,8 +417,6 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
// *HACK: Attempt to prevent startup crashes by deferring memory accounting
// until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
bool mGLReady = false;
// best guess at available video memory in MB
std::atomic<U32> mAvailableVRAM;
U32 mMaxVRAM = 0; // maximum amount of vram to allow in the "budget", or 0 for no maximum (see updateVRAMUsage)
@ -4556,11 +4546,6 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
return std::vector<std::string>();
}
U32 LLWindowWin32::getAvailableVRAMMegabytes()
{
return mWindowThread ? mWindowThread->getAvailableVRAMMegabytes() : 0;
}
void LLWindowWin32::setMaxVRAMMegabytes(U32 max_vram)
{
if (mWindowThread)
@ -4787,79 +4772,6 @@ void LLWindowWin32::LLWindowWin32Thread::cleanupDX()
}
}
void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
{
LL_PROFILE_ZONE_SCOPED;
if (!mGLReady) { return; }
if (mDXGIAdapter != nullptr)
{
// NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware
// It doesn't make sense, but please don't refactor it to make sense. -- davep
DXGI_QUERY_VIDEO_MEMORY_INFO info;
mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info);
#if 0 // debug 0 budget and 0 CU
info.Budget = 0;
info.CurrentUsage = 0;
#endif
U32 budget_mb = info.Budget / 1024 / 1024;
gGLManager.mVRAM = llmax(gGLManager.mVRAM, (S32) budget_mb);
U32 afr_mb = info.AvailableForReservation / 1024 / 1024;
// correct for systems that misreport budget
if (budget_mb == 0)
{
// fall back to available for reservation clamped between 512MB and 2GB
budget_mb = llclamp(afr_mb, (U32) 512, (U32) 2048);
}
if ( mMaxVRAM != 0)
{
budget_mb = llmin(budget_mb, mMaxVRAM);
}
U32 cu_mb = info.CurrentUsage / 1024 / 1024;
// get an estimated usage based on texture bytes allocated
U32 eu_mb = LLImageGL::getTextureBytesAllocated() * 2 / 1024 / 1024;
if (cu_mb == 0)
{ // current usage is sometimes unreliable on Intel GPUs, fall back to estimated usage
cu_mb = llmax((U32)1, eu_mb);
}
U32 target_mb = budget_mb;
if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free
{
target_mb -= 2048;
}
else // if less than 4GB are installed, try not to use more than half of it
{
target_mb /= 2;
}
mAvailableVRAM = cu_mb < target_mb ? target_mb - cu_mb : 0;
#if 0
F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb;
LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024
<< "\nBudget: " << info.Budget / 1024 / 1024
<< "\nCR: " << info.CurrentReservation / 1024 / 1024
<< "\nCU: " << info.CurrentUsage / 1024 / 1024
<< "\nEU: " << eu_mb << llformat(" (%.2f)", eu_error)
<< "\nTU: " << target_mb
<< "\nAM: " << mAvailableVRAM << LL_ENDL;
#endif
}
else if (mD3DDevice != NULL)
{ // fallback to D3D9
mAvailableVRAM = mD3DDevice->GetAvailableTextureMem() / 1024 / 1024;
}
}
void LLWindowWin32::LLWindowWin32Thread::run()
{
sWindowThreadId = std::this_thread::get_id();
@ -4917,14 +4829,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()
//process any pending functions
getQueue().runPending();
}
// update available vram once every 3 seconds
static LLFrameTimer vramTimer;
if (vramTimer.getElapsedTimeF32() > 3.f)
{
updateVRAMUsage();
vramTimer.reset();
}
#if 0
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Sleep");

View File

@ -108,7 +108,6 @@ public:
/*virtual*/ F32 getPixelAspectRatio();
/*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; }
U32 getAvailableVRAMMegabytes() override;
/*virtual*/ void setMaxVRAMMegabytes(U32 max_vram) override;
/*virtual*/ bool dialogColorPicker(F32 *r, F32 *g, F32 *b );

View File

@ -179,10 +179,6 @@ void LLFloaterLagMeter::determineClient()
{
mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
}
else if(LLViewerTexture::isMemoryForTextureLow())
{
mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
}
else
{
mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) );

View File

@ -529,12 +529,11 @@ void LLGLTexMemBar::draw()
U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
text = llformat("GL Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f(%d MB) Cache: %.1f/%.1f MB",
gViewerWindow->getWindow()->getAvailableVRAMMegabytes(),
text = llformat("Est. Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
(S32)LLViewerTexture::sFreeVRAMMegabytes,
LLMemory::getAvailableMemKB()/1024,
LLRenderTarget::sBytesAllocated/(1024*1024),
discard_bias,
(S32)LLViewerTexture::sFreeVRAMMegabytes,
cache_usage,
cache_max_usage);
//, cache_entries, cache_max_entries

View File

@ -1,3 +1,4 @@
/**
* @file llviewertexture.cpp
* @brief Object which handles a received image (and associated texture(s))
@ -471,61 +472,10 @@ void LLViewerTexture::initClass()
LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture();
}
// tuning params
const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;
// non-const (used externally
F32 texmem_lower_bound_scale = 0.85f;
F32 texmem_middle_bound_scale = 0.925f;
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Note: we need to figure out a better source for 'min' values,
// what is free for low end at minimal settings is 'nothing left'
// for higher end gpus at high settings.
const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20);
const S32Megabytes MIN_FREE_MAIN_MEMORY(100);
S32Megabytes gpu;
S32Megabytes physical;
getGPUMemoryForTextures(gpu, physical);
return (gpu < MIN_FREE_TEXTURE_MEMORY); // || (physical < MIN_FREE_MAIN_MEMORY);
}
//static
void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static LLFrameTimer timer;
static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
static S32Megabytes physical_res = S32Megabytes(S32_MAX);
if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
{
gpu = gpu_res;
physical = physical_res;
return;
}
timer.reset();
{
// For purposes of texture memory need to check both, actual free
// memory and estimated free texture memory from bias calculations
U32 free_memory = llmin(gViewerWindow->getWindow()->getAvailableVRAMMegabytes(), (U32)sFreeVRAMMegabytes);
gpu_res = (S32Megabytes)free_memory;
//check main memory, only works for windows and macos.
LLMemory::updateMemoryInfo();
physical_res = LLMemory::getAvailableMemKB();
gpu = gpu_res;
physical = physical_res;
}
}
//static
void LLViewerTexture::updateClass()
{

View File

@ -185,11 +185,7 @@ private:
friend class LLUIImageList;
virtual void switchToCachedImage();
static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
public:
static bool isMemoryForTextureLow();
protected:
friend class LLViewerTextureList;
LLUUID mID;