Commit 6364e2ff authored by Andrey Lihatskiy's avatar Andrey Lihatskiy

Merge branch 'master' into DRTVWR-460

parents d3b10072 4a7fd011
......@@ -347,6 +347,7 @@ Charles Courtois
Charlie Sazaland
Chaser Zaks
BUG-225599
BUG-227485
Cherry Cheevers
ChickyBabes Zuzu
Christopher Organiser
......
......@@ -271,7 +271,7 @@ BOOL LLVorbisDecodeState::initDecode()
mWAVBuffer.reserve(size_guess);
mWAVBuffer.resize(WAV_HEADER_SIZE);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LL_WARNS("AudioEngine") << "Out of memory when trying to alloc buffer: " << size_guess << LL_ENDL;
delete mInFilep;
......
......@@ -195,6 +195,8 @@ namespace
std::string amd_CPUFamilyName(int composed_family)
{
// https://en.wikipedia.org/wiki/List_of_AMD_CPU_microarchitectures
// https://developer.amd.com/resources/developer-guides-manuals/
switch(composed_family)
{
case 4: return "AMD 80486/5x86";
......@@ -202,6 +204,13 @@ namespace
case 6: return "AMD K7";
case 0xF: return "AMD K8";
case 0x10: return "AMD K8L";
case 0x12: return "AMD K10";
case 0x14: return "AMD Bobcat";
case 0x15: return "AMD Bulldozer";
case 0x16: return "AMD Jaguar";
case 0x17: return "AMD Zen/Zen+/Zen2";
case 0x18: return "AMD Hygon Dhyana";
case 0x19: return "AMD Zen 3";
}
return STRINGIZE("AMD <unknown 0x" << std::hex << composed_family << ">");
}
......
......@@ -2251,7 +2251,7 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
return ZR_SIZE_ERROR;
}
#endif
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
free(result);
return ZR_MEM_ERROR;
......
......@@ -318,7 +318,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
{
LOG_UNHANDLED_EXCEPTION("");
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LLMemory::logMemoryInfo(TRUE);
......
......@@ -147,7 +147,7 @@ size_t BufferArray::append(const void * src, size_t len)
{
block = Block::alloc(BLOCK_ALLOC_SIZE);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LLMemory::logMemoryInfo(TRUE);
......
......@@ -315,7 +315,7 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
jpeg_destroy_decompress(&cinfo);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
setLastError( "Out of memory");
jpeg_destroy_decompress(&cinfo);
......
......@@ -210,7 +210,7 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf
releaseResources();
return (FALSE);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
mErrorMessage = "LLPngWrapper";
releaseResources();
......
......@@ -2399,9 +2399,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
{ //face has no geometry, continue
face.resizeIndices(3);
face.resizeVertices(1);
memset(face.mPositions, 0, sizeof(LLVector4a));
memset(face.mNormals, 0, sizeof(LLVector4a));
memset(face.mTexCoords, 0, sizeof(LLVector2));
face.mPositions->clear();
face.mNormals->clear();
face.mTexCoords->setZero();
memset(face.mIndices, 0, sizeof(U16)*3);
continue;
}
......@@ -2489,7 +2489,11 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
else
{
memset(norm_out, 0, sizeof(LLVector4a)*num_verts);
for (U32 j = 0; j < num_verts; ++j)
{
norm_out->clear();
norm_out++; // or just norm_out[j].clear();
}
}
}
......@@ -2519,7 +2523,11 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
else
{
memset(tc_out, 0, sizeof(LLVector2)*num_verts);
for (U32 j = 0; j < num_verts; j += 2)
{
tc_out->clear();
tc_out++;
}
}
}
......@@ -5288,7 +5296,7 @@ bool LLVolumeFace::cacheOptimize()
triangle_data.resize(mNumIndices / 3);
vertex_data.resize(mNumVertices);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LL_WARNS("LLVOLUME") << "Resize failed" << LL_ENDL;
return false;
......@@ -5442,7 +5450,7 @@ bool LLVolumeFace::cacheOptimize()
{
new_idx.resize(mNumVertices, -1);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
ll_aligned_free<64>(pos);
ll_aligned_free_16(wght);
......@@ -6968,11 +6976,16 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
{
//LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
// new(tan1) LLVector4a;
LLVector4a* tan2 = tan1 + vertexCount;
memset(tan1, 0, vertexCount*2*sizeof(LLVector4a));
U32 count = vertexCount * 2;
for (U32 i = 0; i < count; i++)
{
tan1[i].clear();
}
for (U32 a = 0; a < triangleCount; a++)
{
U32 i1 = *index_array++;
......
......@@ -597,7 +597,7 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
{
bas >> jsonRoot;
}
catch (std::runtime_error e)
catch (std::runtime_error& e)
{ // deserialization failed. Record the reason and pass back an empty map for markup.
status = LLCore::HttpStatus(499, std::string(e.what()));
return result;
......@@ -625,7 +625,7 @@ LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &succes
{
bas >> jsonRoot;
}
catch (std::runtime_error e)
catch (std::runtime_error&)
{
success = false;
return LLSD();
......
......@@ -125,7 +125,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
{
response->result(simpleGet());
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}
......@@ -138,7 +138,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons
{
response->result(simplePut(input));
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}
......@@ -151,7 +151,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con
{
response->result(simplePost(input));
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}
......@@ -164,7 +164,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
{
response->result(simpleDel(context));
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}
......
......@@ -50,6 +50,10 @@
#include "llglheaders.h"
#include "llglslshader.h"
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
#ifdef _DEBUG
//#define GL_STATE_VERIFY
#endif
......@@ -395,6 +399,8 @@ PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
#if LL_WINDOWS
PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD = NULL;
PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD = NULL;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
#endif
......@@ -414,6 +420,7 @@ LLGLManager::LLGLManager() :
mHasMultitexture(FALSE),
mHasATIMemInfo(FALSE),
mHasAMDAssociations(FALSE),
mHasNVXMemInfo(FALSE),
mNumTextureUnits(1),
mHasMipMapGeneration(FALSE),
......@@ -498,7 +505,16 @@ void LLGLManager::initWGL()
{
LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
}
// For retreiving information per AMD adapter,
// because we can't trust curently selected/default one when there are multiple
mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts);
if (mHasAMDAssociations)
{
GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
}
if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
{
GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
......@@ -684,23 +700,78 @@ bool LLGLManager::initGL()
stop_glerror();
S32 old_vram = mVRAM;
mVRAM = 0;
if (mHasATIMemInfo)
#if LL_WINDOWS
if (mHasAMDAssociations)
{
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;
}
}
}
if (mVRAM != 0)
{
LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
}
}
#endif
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];
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
mVRAM = meminfo[0]/1024;
mVRAM = meminfo[0] / 1024;
LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL;
}
else if (mHasNVXMemInfo)
if (mHasNVXMemInfo && mVRAM == 0)
{
S32 dedicated_memory;
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
mVRAM = dedicated_memory/1024;
LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL;
}
#if LL_WINDOWS
if (mVRAM < 256)
{ //something likely went wrong using the above extensions, fall back to old method
{
// 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.
S32 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;
}
......@@ -962,7 +1033,7 @@ void LLGLManager::initExtensions()
mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
......
......@@ -78,6 +78,7 @@ class LLGLManager
// Extensions used by everyone
BOOL mHasMultitexture;
BOOL mHasATIMemInfo;
BOOL mHasAMDAssociations;
BOOL mHasNVXMemInfo;
S32 mNumTextureUnits;
BOOL mHasMipMapGeneration;
......
......@@ -618,6 +618,8 @@ extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI;
extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI;
extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI;
extern PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD;
extern PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD;
extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
// GL_ARB_occlusion_query
......
......@@ -36,6 +36,11 @@
#include <boost/regex.hpp>
#if LL_WINDOWS
// because something pulls in window and lldxdiag dependencies which in turn need wbemuuid.lib
#pragma comment(lib, "wbemuuid.lib")
#endif
// namespace LLExperienceCache
// {
......
......@@ -61,7 +61,7 @@ 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 GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam)
{
HRESULT hr;
bool bGotMemory = false;
......@@ -149,21 +149,26 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
if ( !pVideoControllers[iController] )
continue;
pPropName = SysAllocString( L"PNPDeviceID" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
// 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 );
if( FAILED( hr ) )
wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );
#endif
if( SUCCEEDED( hr ) )
{
if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
bFound = true;
if( SUCCEEDED( hr ) && strInputDeviceID)
{
if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
bFound = true;
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
if( bFound )
if( bFound || !strInputDeviceID )
{
pPropName = SysAllocString( L"AdapterRAM" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
......@@ -175,13 +180,18 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
if( SUCCEEDED( hr ) )
{
bGotMemory = true;
*pdwAdapterRam = var.ulVal;
*pdwAdapterRam = llmax(var.ulVal, *pdwAdapterRam);
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
break;
}
SAFE_RELEASE( pVideoControllers[iController] );
if (bFound)
{
break;
}
}
}
}
......@@ -207,6 +217,17 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
return E_FAIL;
}
//static
S32 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()
{
......@@ -615,6 +636,8 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
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,
......@@ -677,6 +700,8 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
}
// 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)
......@@ -689,12 +714,27 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
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");
......
......@@ -94,6 +94,10 @@ class LLDXHardware
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 S32 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
......
......@@ -741,17 +741,27 @@ void LLWindowWin32::restore()
SetFocus(mWindowHandle);
}
// See SL-12170
// According to callstack "c0000005 Access violation" happened inside __try block,
// deep in DestroyWindow and crashed viewer, which shouldn't be possible.
// I tried manually causing this exception and it was caught without issues, so
// I'm turning off optimizations for this part to be sure code executes as intended
// (it is a straw, but I have no idea why else __try can get overruled)
#pragma optimize("", off)
bool destroy_window_handler(HWND &hWnd)
{
bool res;
__try
{
return DestroyWindow(hWnd);
res = DestroyWindow(hWnd);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return false;
res = false;
}
return res;
}
#pragma optimize("", on)
// close() destroys all OS-specific code associated with a window.
// Usually called from LLWindowManager::destroyWindow()
......
......@@ -2036,6 +2036,14 @@ U8 LLAgent::getRenderState()
//-----------------------------------------------------------------------------
void LLAgent::endAnimationUpdateUI()
{
if (LLApp::isExiting()
|| !gViewerWindow
|| !gMenuBarView
|| !gToolBarView
|| !gStatusBar)
{
return;
}
if (gAgentCamera.getCameraMode() == gAgentCamera.getLastCameraMode())
{
// We're already done endAnimationUpdateUI for this transition.
......
......@@ -280,6 +280,11 @@ LLAgentCamera::~LLAgentCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
{
if (gDisconnected)
{
return;
}
if (gAgent.getAutoPilot())
{
gAgent.stopAutoPilot(TRUE);
......
......@@ -62,7 +62,9 @@
#include "llallocator.h"
#include "llcalc.h"
#include "llconversationlog.h"
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
#include "lltexturestats.h"
#include "lltrace.h"
#include "lltracethreadrecorder.h"
......@@ -1134,7 +1136,7 @@ bool LLAppViewer::init()
try {
initializeSecHandler();
}
catch (LLProtectedDataException ex)
catch (LLProtectedDataException&)