viewer#799 getAvailableVRAMMegabytes cleanup
parent
7d87e41bbd
commit
ea268fcd48
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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...
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue