Merge branch 'release/2025.04' of https://github.com/secondlife/viewer

# Conflicts:
#	indra/llrender/llgl.cpp
#	indra/llwindow/lldxhardware.cpp
#	indra/llwindow/lldxhardware.h
#	indra/newview/llappviewerwin32.cpp
#	indra/newview/llviewerdisplay.cpp
master
Ansariel 2025-04-10 18:50:12 +02:00
commit 6487febff0
19 changed files with 78 additions and 881 deletions

View File

@ -1243,23 +1243,6 @@ bool LLGLManager::initGL()
// <FS:Beq> remove this so that we can attempt to use driver specifics
// if it fails we will pick up the `old_vram` value , which is either WMI or the combined dxdiag number
// both of which are rather useless, but it does at least respect the disable_wmi setting.
// #if LL_WINDOWS
// if (mVRAM < 256)
// {
// // Something likely went wrong using the above extensions
// // try WMI first and fall back to old method (from dxdiag) if all else fails
// // Function will check all GPUs WMI knows of and will pick up the one with most
// // memory. We need to check all GPUs because system can switch active GPU to
// // weaker one, to preserve power when not under load.
// U32 mem = LLDXHardware::getMBVideoMemoryViaWMI();
// if (mem != 0)
// {
// mVRAM = mem;
// LL_WARNS("RenderInit") << "VRAM Detected (WMI):" << mVRAM<< LL_ENDL;
// }
// }
// #endif
// </FS:Beq>
// Ultimate fallbacks for linux and mesa
if (mHasNVXGpuMemoryInfo && mVRAM == 0)
@ -1310,12 +1293,8 @@ bool LLGLManager::initGL()
// if (mVRAM < 256 && old_vram > 0)
// {
// // fall back to old method
// // Note: on Windows value will be from LLDXHardware.
// // Either received via dxdiag or via WMI by id from dxdiag.
// mVRAM = old_vram;
// // <FS:Ansariel> VRAM detection logging
// LL_WARNS("RenderInit") << "VRAM detected via MemInfo OpenGL extension most likely broken. Reverting to " << mVRAM << " MB" << LL_ENDL;
// }
// </FS:Beq>
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits);

View File

@ -48,7 +48,6 @@
#include "llstl.h"
#include "lltimer.h"
void (*gWriteDebug)(const char* msg) = NULL;
LLDXHardware gDXHardware;
//-----------------------------------------------------------------------------
@ -62,206 +61,6 @@ typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSv
OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
// <FS:Beq> Deprecate WMI support
uint64_t GetVideoMemoryViaDXGI()
{
HRESULT hr;
IDXGIFactory* pFactory = nullptr;
IDXGIAdapter* pAdapter = nullptr;
// Create a DXGI Factory
hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pFactory);
if (FAILED(hr)) {
std::cerr << "Failed to create DXGI factory." << std::endl;
return 0;
}
// Enumerate adapters
UINT i = 0;
uint64_t vram_bytes = 0;
while (pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND)
{
if(pAdapter)
{
DXGI_ADAPTER_DESC desc;
pAdapter->GetDesc(&desc);
vram_bytes = desc.DedicatedVideoMemory;
break;
}
SAFE_RELEASE(pAdapter);
++i;
}
SAFE_RELEASE(pAdapter)
SAFE_RELEASE(pFactory)
return vram_bytes;
}
// </FS:Beq>
HRESULT GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam)
{
HRESULT hr;
bool bGotMemory = false;
IWbemLocator* pIWbemLocator = nullptr;
IWbemServices* pIWbemServices = nullptr;
BSTR pNamespace = nullptr;
*pdwAdapterRam = 0;
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
hr = CoCreateInstance( CLSID_WbemLocator,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
( LPVOID* )&pIWbemLocator );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: CoCreateInstance failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) && pIWbemLocator )
{
// Using the locator, connect to WMI in the given namespace.
pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );
hr = pIWbemLocator->ConnectServer( pNamespace, nullptr, nullptr, 0L,
0L, nullptr, nullptr, &pIWbemServices );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: pIWbemLocator->ConnectServer failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) && pIWbemServices != 0 )
{
HINSTANCE hinstOle32 = nullptr;
hinstOle32 = LoadLibraryW( L"ole32.dll" );
if( hinstOle32 )
{
PfnCoSetProxyBlanket pfnCoSetProxyBlanket = nullptr;
pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" );
if( pfnCoSetProxyBlanket != 0 )
{
// Switch security level to IMPERSONATE.
pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 );
}
FreeLibrary( hinstOle32 );
}
IEnumWbemClassObject* pEnumVideoControllers = nullptr;
BSTR pClassName = nullptr;
pClassName = SysAllocString( L"Win32_VideoController" );
hr = pIWbemServices->CreateInstanceEnum( pClassName, 0,
nullptr, &pEnumVideoControllers );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: pIWbemServices->CreateInstanceEnum failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) && pEnumVideoControllers )
{
IWbemClassObject* pVideoControllers[10] = {0};
DWORD uReturned = 0;
BSTR pPropName = nullptr;
// Get the first one in the list
pEnumVideoControllers->Reset();
hr = pEnumVideoControllers->Next( 5000, // timeout in 5 seconds
10, // return the first 10
pVideoControllers,
&uReturned );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) ) wprintf( L"WMI: pEnumVideoControllers->Next failed: 0x%0.8x\n", hr );
if( uReturned == 0 ) wprintf( L"WMI: pEnumVideoControllers uReturned == 0\n" );
#endif
VARIANT var;
if( SUCCEEDED( hr ) )
{
bool bFound = false;
for( UINT iController = 0; iController < uReturned; iController++ )
{
if ( !pVideoControllers[iController] )
continue;
// if strInputDeviceID is set find this specific device and return memory or specific device
// if strInputDeviceID is not set return the best device
if (strInputDeviceID)
{
pPropName = SysAllocString( L"PNPDeviceID" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) )
wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) && strInputDeviceID)
{
if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
bFound = true;
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
}
if( bFound || !strInputDeviceID )
{
pPropName = SysAllocString( L"AdapterRAM" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
#ifdef PRINTF_DEBUGGING
if( FAILED( hr ) )
wprintf( L"WMI: pVideoControllers[iController]->Get AdapterRAM failed: 0x%0.8x\n",
hr );
#endif
if( SUCCEEDED( hr ) )
{
bGotMemory = true;
*pdwAdapterRam = llmax(var.ulVal, *pdwAdapterRam);
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
}
SAFE_RELEASE( pVideoControllers[iController] );
if (bFound)
{
break;
}
}
}
}
if( pClassName )
SysFreeString( pClassName );
SAFE_RELEASE( pEnumVideoControllers );
}
if( pNamespace )
SysFreeString( pNamespace );
SAFE_RELEASE( pIWbemServices );
}
SAFE_RELEASE( pIWbemLocator );
CoUninitialize();
if( bGotMemory )
return S_OK;
else
return E_FAIL;
}
//static
U32 LLDXHardware::getMBVideoMemoryViaWMI()
{
DWORD vram = 0;
if (SUCCEEDED(GetVideoMemoryViaWMI(NULL, &vram)))
{
return vram / (1024 * 1024);;
}
return 0;
}
//Getting the version of graphics controller driver via WMI
std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
@ -517,509 +316,14 @@ std::string get_string(IDxDiagContainer *containerp, const WCHAR *wszPropName)
return utf16str_to_utf8str(wszPropValue);
}
LLVersion::LLVersion()
{
mValid = false;
S32 i;
for (i = 0; i < 4; i++)
{
mFields[i] = 0;
}
}
bool LLVersion::set(const std::string &version_string)
{
S32 i;
for (i = 0; i < 4; i++)
{
mFields[i] = 0;
}
// Split the version string.
std::string str(version_string);
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(".", "", boost::keep_empty_tokens);
tokenizer tokens(str, sep);
tokenizer::iterator iter = tokens.begin();
S32 count = 0;
for (;(iter != tokens.end()) && (count < 4);++iter)
{
mFields[count] = atoi(iter->c_str());
count++;
}
if (count < 4)
{
//LL_WARNS() << "Potentially bogus version string!" << version_string << LL_ENDL;
for (i = 0; i < 4; i++)
{
mFields[i] = 0;
}
mValid = false;
}
else
{
mValid = true;
}
return mValid;
}
S32 LLVersion::getField(const S32 field_num)
{
if (!mValid)
{
return -1;
}
else
{
return mFields[field_num];
}
}
std::string LLDXDriverFile::dump()
{
if (gWriteDebug)
{
gWriteDebug("Filename:");
gWriteDebug(mName.c_str());
gWriteDebug("\n");
gWriteDebug("Ver:");
gWriteDebug(mVersionString.c_str());
gWriteDebug("\n");
gWriteDebug("Date:");
gWriteDebug(mDateString.c_str());
gWriteDebug("\n");
}
LL_INFOS() << mFilepath << LL_ENDL;
LL_INFOS() << mName << LL_ENDL;
LL_INFOS() << mVersionString << LL_ENDL;
LL_INFOS() << mDateString << LL_ENDL;
return "";
}
LLDXDevice::~LLDXDevice()
{
for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer());
mDriverFiles.clear();
}
std::string LLDXDevice::dump()
{
if (gWriteDebug)
{
gWriteDebug("StartDevice\n");
gWriteDebug("DeviceName:");
gWriteDebug(mName.c_str());
gWriteDebug("\n");
gWriteDebug("PCIString:");
gWriteDebug(mPCIString.c_str());
gWriteDebug("\n");
}
LL_INFOS() << LL_ENDL;
LL_INFOS() << "DeviceName:" << mName << LL_ENDL;
LL_INFOS() << "PCIString:" << mPCIString << LL_ENDL;
LL_INFOS() << "Drivers" << LL_ENDL;
LL_INFOS() << "-------" << LL_ENDL;
for (driver_file_map_t::iterator iter = mDriverFiles.begin(),
end = mDriverFiles.end();
iter != end; iter++)
{
LLDXDriverFile *filep = iter->second;
filep->dump();
}
if (gWriteDebug)
{
gWriteDebug("EndDevice\n");
}
return "";
}
LLDXDriverFile *LLDXDevice::findDriver(const std::string &driver)
{
for (driver_file_map_t::iterator iter = mDriverFiles.begin(),
end = mDriverFiles.end();
iter != end; iter++)
{
LLDXDriverFile *filep = iter->second;
if (!utf8str_compare_insensitive(filep->mName,driver))
{
return filep;
}
}
return NULL;
}
LLDXHardware::LLDXHardware()
{
mVRAM = 0;
gWriteDebug = NULL;
}
void LLDXHardware::cleanup()
{
// for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer());
// mDevices.clear();
}
/*
std::string LLDXHardware::dumpDevices()
{
if (gWriteDebug)
{
gWriteDebug("\n");
gWriteDebug("StartAllDevices\n");
}
for (device_map_t::iterator iter = mDevices.begin(),
end = mDevices.end();
iter != end; iter++)
{
LLDXDevice *devicep = iter->second;
devicep->dump();
}
if (gWriteDebug)
{
gWriteDebug("EndAllDevices\n\n");
}
return "";
}
LLDXDevice *LLDXHardware::findDevice(const std::string &vendor, const std::string &devices)
{
// Iterate through different devices tokenized in devices string
std::string str(devices);
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
tokenizer tokens(str, sep);
tokenizer::iterator iter = tokens.begin();
for (;iter != tokens.end();++iter)
{
std::string dev_str = *iter;
for (device_map_t::iterator iter = mDevices.begin(),
end = mDevices.end();
iter != end; iter++)
{
LLDXDevice *devicep = iter->second;
if ((devicep->mVendorID == vendor)
&& (devicep->mDeviceID == dev_str))
{
return devicep;
}
}
}
return NULL;
}
*/
// <FS:Ansariel> FIRE-15891: Add option to disable WMI check in case of problems
//bool LLDXHardware::getInfo(bool vram_only)
bool LLDXHardware::getInfo(bool vram_only, bool disable_wmi)
// </FS:Ansariel>
{
LLTimer hw_timer;
bool ok = false;
HRESULT hr;
// CLSID_DxDiagProvider does not work with Multithreaded?
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
IDxDiagProvider *dx_diag_providerp = NULL;
IDxDiagContainer *dx_diag_rootp = NULL;
IDxDiagContainer *devices_containerp = NULL;
// IDxDiagContainer *system_device_containerp= NULL;
IDxDiagContainer *device_containerp = NULL;
IDxDiagContainer *file_containerp = NULL;
IDxDiagContainer *driver_containerp = NULL;
DWORD dw_device_count;
mVRAM = 0;
// CoCreate a IDxDiagProvider*
LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;
hr = CoCreateInstance(CLSID_DxDiagProvider,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDxDiagProvider,
(LPVOID*) &dx_diag_providerp);
if (FAILED(hr))
{
LL_WARNS("AppInit") << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL;
gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n");
goto LCleanup;
}
if (SUCCEEDED(hr)) // if FAILED(hr) then dx9 is not installed
{
// Fill out a DXDIAG_INIT_PARAMS struct and pass it to IDxDiagContainer::Initialize
// Passing in TRUE for bAllowWHQLChecks, allows dxdiag to check if drivers are
// digital signed as logo'd by WHQL which may connect via internet to update
// WHQL certificates.
DXDIAG_INIT_PARAMS dx_diag_init_params;
ZeroMemory(&dx_diag_init_params, sizeof(DXDIAG_INIT_PARAMS));
dx_diag_init_params.dwSize = sizeof(DXDIAG_INIT_PARAMS);
dx_diag_init_params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
dx_diag_init_params.bAllowWHQLChecks = TRUE;
dx_diag_init_params.pReserved = NULL;
LL_DEBUGS("AppInit") << "dx_diag_providerp->Initialize" << LL_ENDL;
hr = dx_diag_providerp->Initialize(&dx_diag_init_params);
if(FAILED(hr))
{
goto LCleanup;
}
LL_DEBUGS("AppInit") << "dx_diag_providerp->GetRootContainer" << LL_ENDL;
hr = dx_diag_providerp->GetRootContainer( &dx_diag_rootp );
if(FAILED(hr) || !dx_diag_rootp)
{
goto LCleanup;
}
HRESULT hr;
// Get display driver information
LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer" << LL_ENDL;
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
if(FAILED(hr) || !devices_containerp)
{
// do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp
devices_containerp = NULL;
goto LCleanup;
}
// make sure there is something inside
hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count);
if (FAILED(hr) || dw_device_count == 0)
{
goto LCleanup;
}
// Get device 0
// By default 0 device is the primary one, howhever in case of various hybrid graphics
// like itegrated AMD and PCI AMD GPUs system might switch.
LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL;
hr = devices_containerp->GetChildContainer(L"0", &device_containerp);
if(FAILED(hr) || !device_containerp)
{
goto LCleanup;
}
DWORD vram = 0;
WCHAR deviceID[512];
get_wstring(device_containerp, L"szDeviceID", deviceID, 512);
// Example: searches id like 1F06 in pnp string (aka VEN_10DE&DEV_1F06)
// doesn't seem to work on some systems since format is unrecognizable
// but in such case keyDeviceID works
// <FS:Ansariel> FIRE-15891: Add option to disable WMI check in case of problems
//if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))
if (!disable_wmi && SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))
// </FS:Ansariel>
{
mVRAM = vram/(1024*1024);
LL_INFOS("AppInit") << "VRAM Detected via WMI: " << mVRAM << LL_ENDL;
}
else
{
get_wstring(device_containerp, L"szKeyDeviceID", deviceID, 512);
LL_WARNS() << "szDeviceID" << deviceID << LL_ENDL;
// '+9' to avoid ENUM\\PCI\\ prefix
// Returns string like Enum\\PCI\\VEN_10DE&DEV_1F06&SUBSYS...
// and since GetVideoMemoryViaWMI searches by PNPDeviceID it is sufficient
// <FS:Ansariel> FIRE-15891: Add option to disable WMI check in case of problems
//if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram)))
if (!disable_wmi && SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram)))
{
mVRAM = vram / (1024 * 1024);
LL_INFOS("AppInit") << "VRAM Detected via WMI: " << mVRAM << LL_ENDL;
}
}
// <FS:Beq> Deprecate WMI use DXGI in preference.
mVRAM = (S32)(GetVideoMemoryViaDXGI()/1024/1024);
LL_INFOS("AppInit") << "VRAM Detected via DXGI: " << mVRAM << "MB" << LL_ENDL;
// </FS:Beq>
if (mVRAM == 0)
{ // Get the English VRAM string
std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish");
// We don't need the device any more
SAFE_RELEASE(device_containerp);
// Dump the string as an int into the structure
char *stopstring;
mVRAM = strtol(ram_str.c_str(), &stopstring, 10);
LL_INFOS("AppInit") << "VRAM Detected via DirectX: " << mVRAM << " DX9 string: " << ram_str << LL_ENDL;
}
if (vram_only)
{
ok = true;
goto LCleanup;
}
/* for now, we ONLY do vram_only the rest of this
is commented out, to ensure no-one is tempted
to use it
// Now let's get device and driver information
// Get the IDxDiagContainer object called "DxDiag_SystemDevices".
// This call may take some time while dxdiag gathers the info.
DWORD num_devices = 0;
WCHAR wszContainer[256];
LL_DEBUGS("AppInit") << "dx_diag_rootp->GetChildContainer DxDiag_SystemDevices" << LL_ENDL;
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_SystemDevices", &system_device_containerp);
if (FAILED(hr))
{
goto LCleanup;
}
hr = system_device_containerp->GetNumberOfChildContainers(&num_devices);
if (FAILED(hr))
{
goto LCleanup;
}
LL_DEBUGS("AppInit") << "DX9 iterating over devices" << LL_ENDL;
S32 device_num = 0;
for (device_num = 0; device_num < (S32)num_devices; device_num++)
{
hr = system_device_containerp->EnumChildContainerNames(device_num, wszContainer, 256);
if (FAILED(hr))
{
goto LCleanup;
}
hr = system_device_containerp->GetChildContainer(wszContainer, &device_containerp);
if (FAILED(hr) || device_containerp == NULL)
{
goto LCleanup;
}
std::string device_name = get_string(device_containerp, L"szDescription");
std::string device_id = get_string(device_containerp, L"szDeviceID");
LLDXDevice *dxdevicep = new LLDXDevice;
dxdevicep->mName = device_name;
dxdevicep->mPCIString = device_id;
mDevices[dxdevicep->mPCIString] = dxdevicep;
// Split the PCI string based on vendor, device, subsys, rev.
std::string str(device_id);
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep("&\\", "", boost::keep_empty_tokens);
tokenizer tokens(str, sep);
tokenizer::iterator iter = tokens.begin();
S32 count = 0;
bool valid = true;
for (;(iter != tokens.end()) && (count < 3);++iter)
{
switch (count)
{
case 0:
if (strcmp(iter->c_str(), "PCI"))
{
valid = false;
}
break;
case 1:
dxdevicep->mVendorID = iter->c_str();
break;
case 2:
dxdevicep->mDeviceID = iter->c_str();
break;
default:
// Ignore it
break;
}
count++;
}
// Now, iterate through the related drivers
hr = device_containerp->GetChildContainer(L"Drivers", &driver_containerp);
if (FAILED(hr) || !driver_containerp)
{
goto LCleanup;
}
DWORD num_files = 0;
hr = driver_containerp->GetNumberOfChildContainers(&num_files);
if (FAILED(hr))
{
goto LCleanup;
}
S32 file_num = 0;
for (file_num = 0; file_num < (S32)num_files; file_num++ )
{
hr = driver_containerp->EnumChildContainerNames(file_num, wszContainer, 256);
if (FAILED(hr))
{
goto LCleanup;
}
hr = driver_containerp->GetChildContainer(wszContainer, &file_containerp);
if (FAILED(hr) || file_containerp == NULL)
{
goto LCleanup;
}
std::string driver_path = get_string(file_containerp, L"szPath");
std::string driver_name = get_string(file_containerp, L"szName");
std::string driver_version = get_string(file_containerp, L"szVersion");
std::string driver_date = get_string(file_containerp, L"szDatestampEnglish");
LLDXDriverFile *dxdriverfilep = new LLDXDriverFile;
dxdriverfilep->mName = driver_name;
dxdriverfilep->mFilepath= driver_path;
dxdriverfilep->mVersionString = driver_version;
dxdriverfilep->mVersion.set(driver_version);
dxdriverfilep->mDateString = driver_date;
dxdevicep->mDriverFiles[driver_name] = dxdriverfilep;
SAFE_RELEASE(file_containerp);
}
SAFE_RELEASE(device_containerp);
}
*/
}
// dumpDevices();
ok = true;
LCleanup:
if (!ok)
{
LL_WARNS("AppInit") << "DX9 probe failed" << LL_ENDL;
gWriteDebug("DX9 probe failed\n");
}
SAFE_RELEASE(file_containerp);
SAFE_RELEASE(driver_containerp);
SAFE_RELEASE(device_containerp);
SAFE_RELEASE(devices_containerp);
SAFE_RELEASE(dx_diag_rootp);
SAFE_RELEASE(dx_diag_providerp);
CoUninitialize();
return ok;
}
LLSD LLDXHardware::getDisplayInfo()
{
LLTimer hw_timer;
@ -1046,7 +350,6 @@ LLSD LLDXHardware::getDisplayInfo()
if (FAILED(hr))
{
LL_WARNS() << "No DXDiag provider found! DirectX 9 not installed!" << LL_ENDL;
gWriteDebug("No DXDiag provider found! DirectX 9 not installed!\n");
goto LCleanup;
}
if (SUCCEEDED(hr)) // if FAILED(hr) then dx9 is not installed
@ -1162,9 +465,4 @@ LCleanup:
return ret;
}
void LLDXHardware::setWriteDebugFunc(void (*func)(const char*))
{
gWriteDebug = func;
}
#endif

View File

@ -30,67 +30,16 @@
#include <map>
#include "stdtypes.h"
#include "llstring.h"
#include "llsd.h"
class LLVersion
{
public:
LLVersion();
bool set(const std::string &version_string);
S32 getField(const S32 field_num);
protected:
std::string mVersionString;
S32 mFields[4];
bool mValid;
};
class LLDXDriverFile
{
public:
std::string dump();
public:
std::string mFilepath;
std::string mName;
std::string mVersionString;
LLVersion mVersion;
std::string mDateString;
};
class LLDXDevice
{
public:
~LLDXDevice();
std::string dump();
LLDXDriverFile *findDriver(const std::string &driver);
public:
std::string mName;
std::string mPCIString;
std::string mVendorID;
std::string mDeviceID;
typedef std::map<std::string, LLDXDriverFile *> driver_file_map_t;
driver_file_map_t mDriverFiles;
};
class LLDXHardware
{
public:
LLDXHardware();
void setWriteDebugFunc(void (*func)(const char*));
void cleanup();
// Returns true on success.
// vram_only true does a "light" probe.
// <FS:Ansariel> FIRE-15891: Add option to disable WMI check in case of problems
//bool getInfo(bool vram_only);
bool getInfo(bool vram_only, bool disable_wmi);
// </FS:Ansariel>
// WMI can return multiple GPU drivers
// specify which one to output
typedef enum {
@ -101,29 +50,9 @@ public:
} EGPUVendor;
std::string getDriverVersionWMI(EGPUVendor vendor);
S32 getVRAM() const { return mVRAM; }
LLSD getDisplayInfo();
// Will get memory of best GPU in MB, return memory on sucsess, 0 on failure
// Note: WMI is not accurate in some cases
static U32 getMBVideoMemoryViaWMI();
// Find a particular device that matches the following specs.
// Empty strings indicate that you don't care.
// You can separate multiple devices with '|' chars to indicate you want
// ANY of them to match and return.
// LLDXDevice *findDevice(const std::string &vendor, const std::string &devices);
// std::string dumpDevices();
public:
typedef std::map<std::string, LLDXDevice *> device_map_t;
// device_map_t mDevices;
protected:
S32 mVRAM;
};
extern void (*gWriteDebug)(const char* msg);
extern LLDXHardware gDXHardware;
#endif // LL_LLDXHARDWARE_H

View File

@ -4858,9 +4858,18 @@ void LLWindowWin32::LLWindowWin32Thread::checkDXMem()
if (phys_mb > 0)
{
// Intel uses 'shared' vram, cap it to 25% of total memory
// Todo: consider caping all adapters at least to 50% ram
budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.25));
if (gGLManager.mIsIntel)
{
// Intel uses 'shared' vram, cap it to 25% of total memory
// Todo: consider a way of detecting integrated Intel and AMD
budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.25));
}
else
{
// More budget is generally better, but the way viewer
// utilizes even dedicated VRAM leaves a footprint in RAM
budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.75));
}
}
else
{

View File

@ -1910,6 +1910,17 @@
<string>F32</string>
<key>Value</key>
<real>0.7</real>
</map>
<key>AudioLevelWind</key>
<map>
<key>Comment</key>
<string>Audio level of wind noise when standing still</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.5</real>
</map>
<key>AudioStreamingMedia</key>
<map>

View File

@ -69,9 +69,16 @@ void GLTFSceneManager::load()
{
return;
}
if (filenames.size() > 0)
try
{
GLTFSceneManager::instance().load(filenames[0]);
if (filenames.size() > 0)
{
GLTFSceneManager::instance().load(filenames[0]);
}
}
catch (std::bad_alloc&)
{
LLNotificationsUtil::add("CannotOpenFileTooBig");
}
},
LLFilePicker::FFLOAD_GLTF,

View File

@ -6169,6 +6169,8 @@ void LLAppViewer::sendLogoutRequest()
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gAgent.sendReliableMessage();
LL_INFOS("Agent") << "Logging out as agent: " << gAgent.getID() << " Session: " << gAgent.getSessionID() << LL_ENDL;
gLogoutTimer.reset();
gLogoutMaxTime = LOGOUT_REQUEST_TIME;
mLogoutRequestSent = true;

View File

@ -1060,73 +1060,11 @@ void write_debug_dx(const std::string& str)
bool LLAppViewerWin32::initHardwareTest()
{
//
// Do driver verification and initialization based on DirectX
// hardware polling and driver versions
//
if (/*true == gSavedSettings.getBOOL("ProbeHardwareOnStartup") &&*/ false == gSavedSettings.getBOOL("NoHardwareProbe")) // <FS:Ansariel> FIRE-20378 / FIRE-20382: Breaks memory detection an 4K monitor workaround
{
// per DEV-11631 - disable hardware probing for everything
// but vram.
bool vram_only = true;
LLSplashScreen::update(LLTrans::getString("StartupDetectingHardware"));
LL_DEBUGS("AppInit") << "Attempting to poll DirectX for hardware info" << LL_ENDL;
gDXHardware.setWriteDebugFunc(write_debug_dx);
// <FS:Ansariel> FIRE-15891: Add option to disable WMI check in case of problems
//bool probe_ok = gDXHardware.getInfo(vram_only);
bool probe_ok = gDXHardware.getInfo(vram_only, gSavedSettings.getBOOL("FSDisableWMIProbing"));
// </FS:Ansariel>
if (!probe_ok
&& gWarningSettings.getBOOL("AboutDirectX9"))
{
LL_WARNS("AppInit") << "DirectX probe failed, alerting user." << LL_ENDL;
// Warn them that runnin without DirectX 9 will
// not allow us to tell them about driver issues
std::ostringstream msg;
msg << LLTrans::getString ("MBNoDirectX");
S32 button = OSMessageBox(
msg.str(),
LLTrans::getString("MBWarning"),
OSMB_YESNO);
if (OSBTN_NO== button)
{
LL_INFOS("AppInit") << "User quitting after failed DirectX 9 detection" << LL_ENDL;
LLWeb::loadURLExternal("http://www.firestormviewer.org/support", false);
return false;
}
gWarningSettings.setBOOL("AboutDirectX9", false);
}
LL_DEBUGS("AppInit") << "Done polling DirectX for hardware info" << LL_ENDL;
// Only probe once after installation
gSavedSettings.setBOOL("ProbeHardwareOnStartup", false);
// Disable so debugger can work
std::string splash_msg;
LLStringUtil::format_map_t args;
args["[APP_NAME]"] = LLAppViewer::instance()->getSecondLifeTitle();
args["[CURRENT_GRID]"] = LLGridManager::getInstance()->getGridLabel();
splash_msg = LLTrans::getString("StartupLoading", args);
LLSplashScreen::update(splash_msg);
}
if (!restoreErrorTrap())
{
LL_WARNS("AppInit") << " Someone took over my exception handler (post hardware probe)!" << LL_ENDL;
LL_WARNS("AppInit") << " Someone took over my exception handler!" << LL_ENDL;
}
if (gGLManager.mVRAM == 0)
{
gGLManager.mVRAM = gDXHardware.getVRAM();
}
// LL_INFOS("AppInit") << "Detected VRAM: " << gGLManager.mVRAM << LL_ENDL; // <FS:Beq/> move this into common code
return true;
}

View File

@ -260,7 +260,15 @@ void LLDrawable::cleanupReferences()
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
gPipeline.unlinkDrawable(this);
if (gPipeline.mInitialized)
{
gPipeline.unlinkDrawable(this);
}
else if (getSpatialGroup())
{
// Not supposed to happen?
getSpatialGroup()->getSpatialPartition()->remove(this, getSpatialGroup());
}
removeFromOctree();

View File

@ -499,7 +499,6 @@ void LLDrawPoolAvatar::beginImpostor()
if (!LLPipeline::sReflectionRender)
{
LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f);
LLVOAvatar::sNumVisibleAvatars = 0;
}
@ -555,7 +554,6 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
if (!LLPipeline::sReflectionRender)
{
LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f);
LLVOAvatar::sNumVisibleAvatars = 0;
}

View File

@ -2866,9 +2866,16 @@ void LLMaterialEditor::importMaterial()
{
return;
}
if (filenames.size() > 0)
try
{
LLMaterialEditor::loadMaterialFromFile(filenames[0], -1);
if (filenames.size() > 0)
{
LLMaterialEditor::loadMaterialFromFile(filenames[0], -1);
}
}
catch (std::bad_alloc&)
{
LLNotificationsUtil::add("CannotOpenFileTooBig");
}
},
LLFilePicker::FFLOAD_MATERIAL,

View File

@ -650,8 +650,8 @@ void audio_update_wind(bool force_update)
// whereas steady-state avatar walk velocity is only 3.2 m/s.
// Without this the world feels desolate on first login when you are
// standing still.
const F32 WIND_LEVEL = 0.5f;
LLVector3 scaled_wind_vec = gWindVec * WIND_LEVEL;
static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
LLVector3 scaled_wind_vec = gWindVec * wind_level;
// Mix in the avatar's motion, subtract because when you walk north,
// the apparent wind moves south.

View File

@ -227,10 +227,13 @@ void display_update_camera()
final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance");
}
else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
{
final_far *= 0.5f;
}
else if (LLViewerTexture::sDesiredDiscardBias > 2.f)
{
final_far = llmax(32.f, final_far / (LLViewerTexture::sDesiredDiscardBias - 1.f));
}
// <FS:CR> Aurora sim
if(LLWorld::getInstance()->getLockedDrawDistance())
{
@ -239,6 +242,7 @@ void display_update_camera()
}
// </FS:CR> Aurora sim
LLViewerCamera::getInstance()->setFar(final_far);
LLVOAvatar::sRenderDistance = llclamp(final_far, 16.f, 256.f);
gViewerWindow->setup3DRender();
if (!gCubeSnapshot)

View File

@ -12246,8 +12246,7 @@ void LLVOAvatar::idleUpdateRenderComplexity()
bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
if (autotune && !isDead())
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
F32 radius = render_far_clip * render_far_clip;
F32 radius = sRenderDistance * sRenderDistance;
bool is_nearby = true;
if ((dist_vec_squared(getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
@ -12279,8 +12278,7 @@ void LLVOAvatar::updateNearbyAvatarCount()
if (agent_update_timer.getElapsedTimeF32() > 1.0f)
{
S32 avs_nearby = 0;
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
F32 radius = render_far_clip * render_far_clip;
F32 radius = sRenderDistance * sRenderDistance;
for (LLCharacter* character : LLCharacter::sInstances)
{
LLVOAvatar* avatar = (LLVOAvatar*)character;

View File

@ -1887,10 +1887,8 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLVOAvatar*> &valid_nearby_avs)
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
F32 nearby_max_complexity = 0;
F32 radius = render_far_clip * render_far_clip;
F32 radius = LLVOAvatar::sRenderDistance * LLVOAvatar::sRenderDistance;
for (LLCharacter* character : LLCharacter::sInstances)
{

View File

@ -953,6 +953,11 @@ Die Datei ist möglicherweise zu groß. Versuchen Sie, die Auflösung oder Quali
Schnappschuss nicht hochgeladen werden.
Die Datei ist möglicherweise zu groß. Versuchen Sie, die Auflösung zu verringern oder versuchen Sie es erneut.
</notification>
<notification name="CannotOpenFileTooBig">
Datei kann nicht geöffnet werden.
Dem Viewer ist beim Öffnen der Datei der Speicher ausgegangen. Die Datei ist vermutlich zu groß.
</notification>
<notification name="LandmarkCreated">
„[LANDMARK_NAME]“ wurde zum Ordner „[FOLDER_NAME]“ hinzugefügt.

View File

@ -10,9 +10,6 @@
<string name="SUPPORT_SITE">
Firestorm Support-Portal
</string>
<string name="StartupDetectingHardware">
Hardware wird erfasst...
</string>
<string name="StartupLoading">
[APP_NAME] wird geladen...
</string>

View File

@ -2503,6 +2503,16 @@ Unable to upload snapshot.
File might be too big, try reducing resolution or try again later.
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="CannotOpenFileTooBig"
type="alertmodal">
Unable to open file.
Viewer ran out of memory while opening file. File might be too big.
<tag>fail</tag>
</notification>
<notification
icon="notifytip.tga"

View File

@ -18,7 +18,6 @@
<string name="APP_NAME_ABBR">FS</string>
<!-- starting up -->
<string name="StartupDetectingHardware">Detecting hardware...</string>
<string name="StartupLoading">Loading [APP_NAME]...</string>
<string name="StartupClearingCache">Clearing cache...</string>
<string name="StartupClearingTextureCache">Clearing texture cache...</string>