From 94d4364084329cc6d16af7a126148117ad13555a Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 16 Oct 2019 22:36:10 +0300 Subject: SL-12103 More reliable memory detection --- indra/llrender/llgl.cpp | 83 ++++++++++++++++++++++++++++++++++++++++---- indra/llrender/llgl.h | 1 + indra/llrender/llglheaders.h | 2 ++ 3 files changed, 80 insertions(+), 6 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c0f0cec80b..bcc702d31f 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -49,6 +49,10 @@ #include "llglheaders.h" #include "llglslshader.h" +#if LL_WINDOWS +#include "lldxhardware.h" +#endif + #ifdef _DEBUG //#define GL_STATE_VERIFY #endif @@ -394,6 +398,8 @@ PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL; PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL; #if LL_WINDOWS +PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD = NULL; +PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD = NULL; PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL; #endif @@ -413,6 +419,7 @@ LLGLManager::LLGLManager() : mHasMultitexture(FALSE), mHasATIMemInfo(FALSE), + mHasAMDAssociations(FALSE), mHasNVXMemInfo(FALSE), mNumTextureUnits(1), mHasMipMapGeneration(FALSE), @@ -497,7 +504,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"); @@ -683,23 +699,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; } @@ -961,7 +1032,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"); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 4c4302d05b..6db1fe9c90 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -78,6 +78,7 @@ public: // Extensions used by everyone BOOL mHasMultitexture; BOOL mHasATIMemInfo; + BOOL mHasAMDAssociations; BOOL mHasNVXMemInfo; S32 mNumTextureUnits; BOOL mHasMipMapGeneration; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 722dd9050b..36fbb381bb 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -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 -- cgit v1.2.3 From a3d0e3f14de4ae99128424ce0f495f40bb638202 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Wed, 15 Apr 2020 09:26:29 -0700 Subject: Cleanup to coding standard --- indra/llrender/llglslshader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 384e5bf99f..8cc3c50ec2 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -485,7 +485,8 @@ BOOL LLGLSLShader::createShader(std::vector * attributes, return success; } -BOOL LLGLSLShader::attachVertexObject(std::string object_path) { +BOOL LLGLSLShader::attachVertexObject(std::string object_path) +{ if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0) { stop_glerror(); -- cgit v1.2.3 From 2df08951e102c05335ce4143fe436b40cc34d22a Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Wed, 15 Apr 2020 15:38:46 -0700 Subject: SL-13019: Add debug logging of shaders used to track down macOSX / OSX GLSL linker errors --- indra/llrender/llglslshader.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'indra/llrender') diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 8cc3c50ec2..74cfa60b27 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -37,6 +37,10 @@ #include "OpenGL/OpenGL.h" #endif +// Print-print list of shader included source files that are linked together via glAttachObjectARB() +// i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state. +#define DEBUG_SHADER_INCLUDES 0 + // Lots of STL stuff in here, using namespace std to keep things more readable using std::vector; using std::pair; @@ -402,6 +406,10 @@ BOOL LLGLSLShader::createShader(std::vector * attributes, mDefines["OLD_SELECT"] = "1"; #endif +#if DEBUG_SHADER_INCLUDES + fprintf(stderr, "--- %s ---\n", mName.c_str()); +#endif // DEBUG_SHADER_INCLUDES + //compile new source vector< pair >::iterator fileIter = mShaderFiles.begin(); for ( ; fileIter != mShaderFiles.end(); fileIter++ ) @@ -485,12 +493,36 @@ BOOL LLGLSLShader::createShader(std::vector * attributes, return success; } +#if DEBUG_SHADER_INCLUDES +void dumpAttachObject( const char *func_name, GLhandleARB program_object, const std::string &object_path ) +{ + GLcharARB* info_log; + GLint info_len_expect = 0; + GLint info_len_actual = 0; + + glGetObjectParameterivARB(program_object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_len_expect); + fprintf(stderr, " * %-20s(), log size: %d, %s\n", func_name, info_len_expect, object_path.c_str()); + + if (info_len_expect > 0) + { + fprintf(stderr, " ========== %s() ========== \n", func_name); + info_log = new GLcharARB [ info_len_expect ]; + glGetInfoLogARB(program_object, info_len_expect, &info_len_actual, info_log); + fprintf(stderr, "%s\n", info_log); + delete [] info_log; + } +} +#endif // DEBUG_SHADER_INCLUDES + BOOL LLGLSLShader::attachVertexObject(std::string object_path) { if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0) { stop_glerror(); glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]); +#if DEBUG_SHADER_INCLUDES + dumpAttachObject("attachVertexObject", mProgramObject, object_path); +#endif // DEBUG_SHADER_INCLUDES stop_glerror(); return TRUE; } @@ -507,6 +539,9 @@ BOOL LLGLSLShader::attachFragmentObject(std::string object_path) { stop_glerror(); glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]); +#if DEBUG_SHADER_INCLUDES + dumpAttachObject("attachFragmentObject", mProgramObject, object_path); +#endif // DEBUG_SHADER_INCLUDES stop_glerror(); return TRUE; } @@ -523,6 +558,10 @@ void LLGLSLShader::attachObject(GLhandleARB object) { stop_glerror(); glAttachObjectARB(mProgramObject, object); +#if DEBUG_SHADER_INCLUDES + std::string object_path("???"); + dumpAttachObject("attachObject", mProgramObject, object_path); +#endif // DEBUG_SHADER_INCLUDES stop_glerror(); } else -- cgit v1.2.3 From 05ddffb6bab6da2e2bcaaa215824b4c09d6928e7 Mon Sep 17 00:00:00 2001 From: Ptolemy Date: Tue, 28 Apr 2020 09:12:32 -0700 Subject: DRTVWR-510: Cleanup: Add link for Optimus global variable for nVidia driver. --- indra/llrender/llgl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llrender') diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 4c56b8eace..7560fe9505 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -2703,6 +2703,7 @@ LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_w #if LL_WINDOWS // Expose desired use of high-performance graphics processor to Optimus driver +// https://docs.nvidia.com/gameworks/content/technologies/desktop/optimus.htm extern "C" { _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; -- cgit v1.2.3