Changed: Implement CSystemUtils::getTotalVideoMemory() under Linux (Xorg log and lspci parsing)
This commit is contained in:
parent
fd9a6820f7
commit
e1060b8923
1 changed files with 188 additions and 2 deletions
|
@ -32,6 +32,8 @@
|
||||||
# include <ShObjIdl.h>
|
# include <ShObjIdl.h>
|
||||||
# define TASKBAR_PROGRESS 1
|
# define TASKBAR_PROGRESS 1
|
||||||
# endif
|
# endif
|
||||||
|
#elif defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
|
||||||
|
#include "nel/misc/file.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_NEW
|
#ifdef DEBUG_NEW
|
||||||
|
@ -472,7 +474,7 @@ sint CSystemUtils::getTotalVideoMemory()
|
||||||
{
|
{
|
||||||
sint res = -1;
|
sint res = -1;
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#if defined(NL_OS_WINDOWS)
|
||||||
// using DXGI
|
// using DXGI
|
||||||
HINSTANCE hDXGI = LoadLibraryA("dxgi.dll");
|
HINSTANCE hDXGI = LoadLibraryA("dxgi.dll");
|
||||||
|
|
||||||
|
@ -596,8 +598,192 @@ sint CSystemUtils::getTotalVideoMemory()
|
||||||
nlwarning("Unable to load ddraw.dll");
|
nlwarning("Unable to load ddraw.dll");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
// the right method is using OpenGL
|
||||||
#else
|
#else
|
||||||
// TODO: implement for other systems
|
// under Linux, no method is really reliable...
|
||||||
|
NLMISC::CIFile file;
|
||||||
|
|
||||||
|
std::string logFile = "/var/log/Xorg.0.log";
|
||||||
|
|
||||||
|
// parse last Xorg.0.log
|
||||||
|
if (file.open(logFile, true))
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
|
||||||
|
while(!file.eof())
|
||||||
|
{
|
||||||
|
file.getline(buffer, 256);
|
||||||
|
|
||||||
|
if (buffer[0] == '\0') break;
|
||||||
|
|
||||||
|
std::string line(buffer);
|
||||||
|
|
||||||
|
// nvidia driver
|
||||||
|
std::string::size_type pos = line.find(") NVIDIA(");
|
||||||
|
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
// [ 20.883] (--) NVIDIA(0): Memory: 2097152 kBytes
|
||||||
|
pos = line.find("Memory: ", pos);
|
||||||
|
|
||||||
|
// found memory line
|
||||||
|
if (pos == std::string::npos) continue;
|
||||||
|
pos += 8;
|
||||||
|
|
||||||
|
std::string::size_type posUnits = line.find(" kBytes", pos);
|
||||||
|
|
||||||
|
// found units in KiB
|
||||||
|
if (posUnits == std::string::npos) continue;
|
||||||
|
|
||||||
|
std::string videoMemory = line.substr(pos, posUnits-pos);
|
||||||
|
|
||||||
|
if (!NLMISC::fromString(videoMemory, res)) continue;
|
||||||
|
|
||||||
|
nlinfo("Xorg NVIDIA driver reported %d KiB of video memory", res);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// intel driver
|
||||||
|
pos = line.find(") intel(");
|
||||||
|
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
// (**) intel(0): VideoRam: 131072 KB
|
||||||
|
pos = line.find("VideoRam: ", pos);
|
||||||
|
|
||||||
|
// found memory line
|
||||||
|
if (pos == std::string::npos) continue;
|
||||||
|
pos += 10;
|
||||||
|
|
||||||
|
std::string::size_type posUnits = line.find(" KB", pos);
|
||||||
|
|
||||||
|
// found units in KiB
|
||||||
|
if (posUnits == std::string::npos) continue;
|
||||||
|
|
||||||
|
std::string videoMemory = line.substr(pos, posUnits-pos);
|
||||||
|
|
||||||
|
if (!NLMISC::fromString(videoMemory, res)) continue;
|
||||||
|
|
||||||
|
nlinfo("Xorg Intel driver reported %d KiB of video memory", res);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: other drivers: nv, fglrx (ATI), radeon (ATI)
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == -1)
|
||||||
|
{
|
||||||
|
// use lspci
|
||||||
|
std::string command = "lspci";
|
||||||
|
|
||||||
|
std::string out = getCommandOutput(command);
|
||||||
|
|
||||||
|
if (out.empty())
|
||||||
|
{
|
||||||
|
nlwarning("Unable to launch %s", command.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
std::string deviceId;
|
||||||
|
|
||||||
|
explode(out, std::string("\n"), lines, true);
|
||||||
|
|
||||||
|
// process each line
|
||||||
|
for(uint i = 0; i < lines.size(); ++i)
|
||||||
|
{
|
||||||
|
std::string line = lines[i];
|
||||||
|
|
||||||
|
if (line.find("VGA") == std::string::npos &&
|
||||||
|
line.find("3D") == std::string::npos &&
|
||||||
|
line.find("2D") == std::string::npos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string::size_type pos = line.find(' ');
|
||||||
|
|
||||||
|
if (pos == std::string::npos) continue;
|
||||||
|
|
||||||
|
// found device ID
|
||||||
|
deviceId = line.substr(0, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceId.empty())
|
||||||
|
{
|
||||||
|
nlwarning("Unable to find a 3D device with lspci");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
command = "lspci -v -s " + deviceId;
|
||||||
|
|
||||||
|
out = getCommandOutput(command);
|
||||||
|
|
||||||
|
if (out.empty())
|
||||||
|
{
|
||||||
|
nlwarning("Unable to launch %s", command.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
explode(out, std::string("\n"), lines, true);
|
||||||
|
|
||||||
|
// process each line
|
||||||
|
for(uint i = 0; i < lines.size(); ++i)
|
||||||
|
{
|
||||||
|
std::string line = lines[i];
|
||||||
|
|
||||||
|
// look for a size
|
||||||
|
std::string::size_type pos0 = line.find("[size=");
|
||||||
|
if (pos0 == std::string::npos) continue;
|
||||||
|
|
||||||
|
// move to first digit
|
||||||
|
pos0 += 6;
|
||||||
|
|
||||||
|
// end of the size
|
||||||
|
std::string::size_type pos1 = line.find("]", pos0);
|
||||||
|
if (pos1 == std::string::npos) continue;
|
||||||
|
|
||||||
|
sint units;
|
||||||
|
|
||||||
|
if (line.substr(pos1-1, 1) == "M")
|
||||||
|
{
|
||||||
|
// size in MiB
|
||||||
|
units = 1024;
|
||||||
|
--pos1;
|
||||||
|
}
|
||||||
|
else if (line.substr(pos1-1, 1) == "K")
|
||||||
|
{
|
||||||
|
// size in KiB
|
||||||
|
units = 1;
|
||||||
|
--pos1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// size in B
|
||||||
|
units = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract the size
|
||||||
|
std::string sizeStr = line.substr(pos0, pos1-pos0);
|
||||||
|
|
||||||
|
// convert size to integer with right units
|
||||||
|
sint tmpSize;
|
||||||
|
if (!NLMISC::fromString(sizeStr, tmpSize)) continue;
|
||||||
|
|
||||||
|
tmpSize *= units;
|
||||||
|
|
||||||
|
// take the higher size (up to 256 MiB apparently)
|
||||||
|
if (tmpSize > res) res = tmpSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlinfo("lspci reported %d KiB of video memory", res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Reference in a new issue