From 2f7c62a4c312ae6c0d2c6ae52cb06a73c553c2c3 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 8 Jun 2013 19:37:53 +0300 Subject: Add cpu features detection. --- src/CMakeLists.txt | 2 + src/Makefile.am | 2 + src/client.cpp | 2 + src/utils/cpu.cpp | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/cpu.h | 44 +++++++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 src/utils/cpu.cpp create mode 100644 src/utils/cpu.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4f5fa4ee3..ebb55e132 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -503,6 +503,8 @@ SET(SRCS utils/checkutils.h utils/copynpaste.cpp utils/copynpaste.h + utils/cpu.cpp + utils/cpu.h utils/dtor.h utils/gettext.h utils/langs.cpp diff --git a/src/Makefile.am b/src/Makefile.am index b7584a950..662ae3f74 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -504,6 +504,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ utils/checkutils.h \ utils/copynpaste.cpp \ utils/copynpaste.h \ + utils/cpu.cpp \ + utils/cpu.h \ utils/dtor.h \ utils/gettext.h \ utils/langs.cpp \ diff --git a/src/client.cpp b/src/client.cpp index 4fcfaa081..fef51e24f 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -96,6 +96,7 @@ #include "resources/petdb.h" #include "resources/resourcemanager.h" +#include "utils/cpu.h" #include "utils/gettext.h" #include "utils/mkdir.h" #include "utils/paths.h" @@ -589,6 +590,7 @@ void Client::gameInit() ImageHelper::setEnableAlpha(config.getFloatValue("guialpha") != 1.0f); #endif logVars(); + Cpu::detect(); graphicsManager.initGraphics(mOptions.noOpenGL); graphicsManager.detectPixelSize(); runCounters = config.getBoolValue("packetcounters"); diff --git a/src/utils/cpu.cpp b/src/utils/cpu.cpp new file mode 100644 index 000000000..bef0d653d --- /dev/null +++ b/src/utils/cpu.cpp @@ -0,0 +1,109 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "utils/cpu.h" + +#include "logger.h" + +#include "utils/stringutils.h" + +#include "resources/resourcemanager.h" + +#include "debug.h" + +int mCpuFlags = 0; + +void Cpu::detect() +{ +#ifdef __GNUC__ + __builtin_cpu_init(); + if (__builtin_cpu_supports ("mmx")) + mCpuFlags |= FEATURE_MMX; + if (__builtin_cpu_supports ("sse")) + mCpuFlags |= FEATURE_SSE; + if (__builtin_cpu_supports ("sse2")) + mCpuFlags |= FEATURE_SSE2; + if (__builtin_cpu_supports ("ssse3")) + mCpuFlags |= FEATURE_SSSE3; + if (__builtin_cpu_supports ("sse4.1")) + mCpuFlags |= FEATURE_SSE4; + if (__builtin_cpu_supports ("sse4.2")) + mCpuFlags |= FEATURE_SSE42; + printFlags(); +#elif defined(__linux__) || defined(__linux) + FILE *file = fopen("/proc/cpuinfo", "r"); + char buf[1001]; + if (!file) + return; + while (fgets(buf, 1000, file)) + { + std::string str = buf; + if (findFirst(str, "flags")) + { + size_t idx = str.find(":"); + if (idx == std::string::npos) + continue; + str = str.substr(idx + 1); + trim(str); + StringVect vect; + splitToStringVector(vect, str, ' '); + FOR_EACH (StringVectCIter, it, vect) + { + const std::string &flag = *it; + if (flag == "mmx") + mCpuFlags |= FEATURE_MMX; + else if (flag == "sse") + mCpuFlags |= FEATURE_SSE; + else if (flag == "sse2") + mCpuFlags |= FEATURE_SSE2; + else if (flag == "ssse3") + mCpuFlags |= FEATURE_SSSE3; + else if (flag == "sse4_1") + mCpuFlags |= FEATURE_SSE4; + else if (flag == "sse4_2") + mCpuFlags |= FEATURE_SSE42; + } + fclose(file); + printFlags(); + return; + } + } + fclose(file); + logger->log("cpu features was not detected"); +#endif +} + +void Cpu::printFlags() +{ + std::string str = "CPU features:"; + if (mCpuFlags & FEATURE_MMX) + str.append(" mmx"); + if (mCpuFlags & FEATURE_SSE) + str.append(" sse"); + if (mCpuFlags & FEATURE_SSE2) + str.append(" sse2"); + if (mCpuFlags & FEATURE_SSSE3) + str.append(" ssse3"); + if (mCpuFlags & FEATURE_SSE4) + str.append(" sse4"); + if (mCpuFlags & FEATURE_SSE42) + str.append(" sse4_2"); + logger->log(str); +} diff --git a/src/utils/cpu.h b/src/utils/cpu.h new file mode 100644 index 000000000..88d35933d --- /dev/null +++ b/src/utils/cpu.h @@ -0,0 +1,44 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UTILD_CPU_H +#define UTILD_CPU_H + +#include "localconsts.h" + +namespace Cpu +{ + enum + { + FEATURE_EMPTY = 0, + FEATURE_MMX = 1, + FEATURE_SSE = 2, + FEATURE_SSE2 = 4, + FEATURE_SSSE3 = 8, + FEATURE_SSE4 = 16, + FEATURE_SSE42 = 32 + }; + + void detect(); + + void printFlags(); +} // namespace CPU + +#endif // UTILD_CPU_H -- cgit v1.2.3-70-g09d2