#3575 Clean up obsolete VRAM detectin logic
parent
9aea5bb5e2
commit
2da46c3830
|
|
@ -1228,28 +1228,9 @@ bool LLGLManager::initGL()
|
|||
}
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
#include "llstl.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
void (*gWriteDebug)(const char* msg) = NULL;
|
||||
LLDXHardware gDXHardware;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -61,170 +60,6 @@ typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSv
|
|||
OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,
|
||||
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
|
||||
|
||||
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)
|
||||
|
|
@ -480,495 +315,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;
|
||||
}
|
||||
*/
|
||||
|
||||
bool LLDXHardware::getInfo(bool vram_only)
|
||||
{
|
||||
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
|
||||
if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))
|
||||
{
|
||||
mVRAM = vram/(1024*1024);
|
||||
}
|
||||
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
|
||||
if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram)))
|
||||
{
|
||||
mVRAM = vram / (1024 * 1024);
|
||||
}
|
||||
}
|
||||
|
||||
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: " << 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;
|
||||
|
|
@ -995,7 +349,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
|
||||
|
|
@ -1111,9 +464,4 @@ LCleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void LLDXHardware::setWriteDebugFunc(void (*func)(const char*))
|
||||
{
|
||||
gWriteDebug = func;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,64 +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.
|
||||
bool getInfo(bool vram_only);
|
||||
|
||||
// WMI can return multiple GPU drivers
|
||||
// specify which one to output
|
||||
typedef enum {
|
||||
|
|
@ -98,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
|
||||
|
|
|
|||
|
|
@ -842,69 +842,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"))
|
||||
{
|
||||
// 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);
|
||||
bool probe_ok = gDXHardware.getInfo(vram_only);
|
||||
|
||||
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://secondlife.com/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();
|
||||
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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
<string name="SUPPORT_SITE">Second Life Support Portal</string>
|
||||
|
||||
<!-- starting up -->
|
||||
<string name="StartupDetectingHardware">Detecting hardware...</string>
|
||||
<string name="StartupLoading">Loading [APP_NAME]...</string>
|
||||
<string name="StartupClearingCache">Clearing cache...</string>
|
||||
<string name="StartupInitializingTextureCache">Initializing texture cache...</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue