summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llprocessor.cpp89
-rw-r--r--indra/llcommon/llprocessor.h3
-rw-r--r--indra/llcommon/llsys.cpp35
-rw-r--r--indra/llcommon/llsys.h8
-rw-r--r--indra/newview/llappviewer.cpp8
5 files changed, 141 insertions, 2 deletions
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 0778b123ea..180538eeb9 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -123,6 +123,9 @@ namespace
eSSE4_1_Features = 38,
eSSE4_2_Features = 39,
eSSE4a_Features = 40,
+ eAVX_Features = 41,
+ eAVX2_Features = 42,
+ eAVX512F_Features = 43,
};
const char* cpu_feature_names[] =
@@ -170,6 +173,9 @@ namespace
"SSE4.1 Instructions",
"SSE4.2 Instructions",
"SSE4a Instructions",
+ "AVX Instructions", // 41
+ "AVX2 Instructions", // 42
+ "AVX-512F Instructions", // 43
};
std::string intel_CPUFamilyName(int composed_family)
@@ -283,6 +289,21 @@ public:
return hasExtension(cpu_feature_names[eSSE4a_Features]);
}
+ bool hasAVX() const
+ {
+ return hasExtension(cpu_feature_names[eAVX_Features]);
+ }
+
+ bool hasAVX2() const
+ {
+ return hasExtension(cpu_feature_names[eAVX2_Features]);
+ }
+
+ bool hasAVX512F() const
+ {
+ return hasExtension(cpu_feature_names[eAVX512F_Features]);
+ }
+
bool hasAltivec() const
{
return hasExtension("Altivec");
@@ -572,6 +593,12 @@ private:
setExtension(cpu_feature_names[eSSE4_2_Features]);
}
+ // AVX: CPUID leaf 1, ECX bit 28, OSXSAVE + XCR0[1:2] enabled
+ if ((cpu_info[2] & 0x18000000) == 0x18000000 && ((_xgetbv(0) & 0x6) == 0x6))
+ {
+ setExtension(cpu_feature_names[eAVX_Features]);
+ }
+
unsigned int feature_info = (unsigned int) cpu_info[3];
for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)
{
@@ -581,6 +608,27 @@ private:
}
}
}
+ else if (i == 7)
+ {
+ // AVX2/AVX-512* require AVX to be usable (OSXSAVE + XCR0 state)
+ if (hasExtension(cpu_feature_names[eAVX_Features]))
+ {
+ int cpu_info7[4] = { -1 };
+ __cpuidex(cpu_info7, 7, 0);
+ // AVX2: EBX bit 5
+ if (cpu_info7[1] & 0x20)
+ {
+ setExtension(cpu_feature_names[eAVX2_Features]);
+ }
+
+ // AVX-512F: EBX bit 16; ZMM state in XCR0 (bits 5-7)
+ const unsigned long long xcr0 = _xgetbv(0);
+ if ((cpu_info7[1] & 0x10000) && ((xcr0 & 0xE6) == 0xE6))
+ {
+ setExtension(cpu_feature_names[eAVX512F_Features]);
+ }
+ }
+ }
}
// Calling __cpuid with 0x80000000 as the InfoType argument
@@ -779,6 +827,29 @@ private:
// Not supposed to happen?
setExtension(cpu_feature_names[eSSE4a_Features]);
}
+ if (cpu_features_str.find(" AVX1.0 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eAVX_Features]);
+ }
+
+ // AVX2 and AVX-512F are reported in machdep.cpu.leaf7_features on macOS
+ char cpu_leaf7_features[1024];
+ len = sizeof(cpu_leaf7_features);
+ memset(cpu_leaf7_features, 0, len);
+ sysctlbyname("machdep.cpu.leaf7_features", (void*)cpu_leaf7_features, &len, NULL, 0);
+
+ std::string cpu_leaf7_str(cpu_leaf7_features);
+ cpu_leaf7_str = " " + cpu_leaf7_str + " ";
+
+ if (cpu_leaf7_str.find(" AVX2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eAVX2_Features]);
+ }
+
+ if (cpu_leaf7_str.find(" AVX512F ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eAVX512F_Features]);
+ }
}
};
@@ -915,6 +986,21 @@ private:
setExtension(cpu_feature_names[eSSE4a_Features]);
}
+ if (flags.find(" avx ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eAVX_Features]);
+ }
+
+ if (flags.find(" avx2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eAVX2_Features]);
+ }
+
+ if (flags.find(" avx512f ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eAVX512F_Features]);
+ }
+
# endif // LL_X86
}
@@ -979,6 +1065,9 @@ bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); }
bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); }
bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); }
bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); }
+bool LLProcessorInfo::hasAVX() const { return mImpl->hasAVX(); }
+bool LLProcessorInfo::hasAVX2() const { return mImpl->hasAVX2(); }
+bool LLProcessorInfo::hasAVX512F() const { return mImpl->hasAVX512F(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); }
std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index b955f7f55c..da93a531f4 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -46,6 +46,9 @@ public:
bool hasSSE41() const;
bool hasSSE42() const;
bool hasSSE4a() const;
+ bool hasAVX() const;
+ bool hasAVX2() const;
+ bool hasAVX512F() const;
bool hasAltivec() const;
std::string getCPUFamilyName() const;
std::string getCPUBrandName() const;
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 803bab393c..051f24fcb5 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -590,6 +590,9 @@ LLCPUInfo::LLCPUInfo()
mHasSSE41 = proc.hasSSE41();
mHasSSE42 = proc.hasSSE42();
mHasSSE4a = proc.hasSSE4a();
+ mHasAVX = proc.hasAVX();
+ mHasAVX2 = proc.hasAVX2();
+ mHasAVX512F = proc.hasAVX512F();
mHasAltivec = proc.hasAltivec();
mCPUMHz = (F64)proc.getCPUFrequency();
mFamily = proc.getCPUFamilyName();
@@ -631,6 +634,18 @@ LLCPUInfo::LLCPUInfo()
{
mSSEVersions.append("4a");
}
+ if (mHasAVX)
+ {
+ mSIMDVersions.append("AVX");
+ }
+ if (mHasAVX2)
+ {
+ mSIMDVersions.append("AVX2");
+ }
+ if (mHasAVX512F)
+ {
+ mSIMDVersions.append("AVX-512F");
+ }
}
bool LLCPUInfo::hasAltivec() const
@@ -673,6 +688,21 @@ bool LLCPUInfo::hasSSE4a() const
return mHasSSE4a;
}
+bool LLCPUInfo::hasAVX() const
+{
+ return mHasAVX;
+}
+
+bool LLCPUInfo::hasAVX2() const
+{
+ return mHasAVX2;
+}
+
+bool LLCPUInfo::hasAVX512F() const
+{
+ return mHasAVX512F;
+}
+
F64 LLCPUInfo::getMHz() const
{
return mCPUMHz;
@@ -688,6 +718,11 @@ const LLSD& LLCPUInfo::getSSEVersions() const
return mSSEVersions;
}
+const LLSD& LLCPUInfo::getSIMDVersions() const
+{
+ return mSIMDVersions;
+}
+
void LLCPUInfo::stream(std::ostream& s) const
{
// gather machine information.
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 827b0dc048..e19f6922f3 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -81,6 +81,7 @@ public:
std::string getCPUString() const;
const LLSD& getSSEVersions() const;
+ const LLSD& getSIMDVersions() const;
bool hasAltivec() const;
bool hasSSE() const;
@@ -90,6 +91,9 @@ public:
bool hasSSE41() const;
bool hasSSE42() const;
bool hasSSE4a() const;
+ bool hasAVX() const;
+ bool hasAVX2() const;
+ bool hasAVX512F() const;
F64 getMHz() const;
// Family is "AMD Duron" or "Intel Pentium Pro"
@@ -103,11 +107,15 @@ private:
bool mHasSSE41;
bool mHasSSE42;
bool mHasSSE4a;
+ bool mHasAVX;
+ bool mHasAVX2;
+ bool mHasAVX512F;
bool mHasAltivec;
F64 mCPUMHz;
std::string mFamily;
std::string mCPUString;
LLSD mSSEVersions;
+ LLSD mSIMDVersions;
};
//=============================================================================
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d3df15a642..67b84c324c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3890,8 +3890,12 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily();
gDebugInfo["CPUInfo"]["CPUMhz"] = (S32)gSysCPU.getMHz();
gDebugInfo["CPUInfo"]["CPUAltivec"] = gSysCPU.hasAltivec();
- gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
- gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
+ gDebugInfo["CPUInfo"]["CPUSSE42"] = gSysCPU.hasSSE42();
+ gDebugInfo["CPUInfo"]["CPUSSE4a"] = gSysCPU.hasSSE4a();
+ gDebugInfo["CPUInfo"]["CPUAVX"] = gSysCPU.hasAVX();
+ gDebugInfo["CPUInfo"]["CPUAVX2"] = gSysCPU.hasAVX2();
+ gDebugInfo["CPUInfo"]["CPUAVX512F"] = gSysCPU.hasAVX512F();
+
gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value());
gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());