summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt5
-rw-r--r--src/common/telemetry.cpp15
-rw-r--r--src/common/thread.h9
-rw-r--r--src/common/x64/cpu_detect.cpp68
-rw-r--r--src/common/x64/cpu_detect.h31
5 files changed, 14 insertions, 114 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 9b0c3db68..9afc6105d 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -15,6 +15,10 @@ endif ()
15if (DEFINED ENV{DISPLAYVERSION}) 15if (DEFINED ENV{DISPLAYVERSION})
16 set(DISPLAY_VERSION $ENV{DISPLAYVERSION}) 16 set(DISPLAY_VERSION $ENV{DISPLAYVERSION})
17endif () 17endif ()
18
19# Pass the path to git to the GenerateSCMRev.cmake as well
20find_package(Git QUIET)
21
18add_custom_command(OUTPUT scm_rev.cpp 22add_custom_command(OUTPUT scm_rev.cpp
19 COMMAND ${CMAKE_COMMAND} 23 COMMAND ${CMAKE_COMMAND}
20 -DSRC_DIR="${CMAKE_SOURCE_DIR}" 24 -DSRC_DIR="${CMAKE_SOURCE_DIR}"
@@ -23,6 +27,7 @@ add_custom_command(OUTPUT scm_rev.cpp
23 -DTITLE_BAR_FORMAT_RUNNING="${TITLE_BAR_FORMAT_RUNNING}" 27 -DTITLE_BAR_FORMAT_RUNNING="${TITLE_BAR_FORMAT_RUNNING}"
24 -DBUILD_TAG="${BUILD_TAG}" 28 -DBUILD_TAG="${BUILD_TAG}"
25 -DBUILD_ID="${DISPLAY_VERSION}" 29 -DBUILD_ID="${DISPLAY_VERSION}"
30 -DGIT_EXECUTABLE="${GIT_EXECUTABLE}"
26 -P "${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake" 31 -P "${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake"
27 DEPENDS 32 DEPENDS
28 # WARNING! It was too much work to try and make a common location for this list, 33 # WARNING! It was too much work to try and make a common location for this list,
diff --git a/src/common/telemetry.cpp b/src/common/telemetry.cpp
index f53a8d193..200c6489a 100644
--- a/src/common/telemetry.cpp
+++ b/src/common/telemetry.cpp
@@ -44,20 +44,6 @@ template class Field<std::string>;
44template class Field<const char*>; 44template class Field<const char*>;
45template class Field<std::chrono::microseconds>; 45template class Field<std::chrono::microseconds>;
46 46
47#ifdef ARCHITECTURE_x86_64
48static const char* CpuVendorToStr(Common::CPUVendor vendor) {
49 switch (vendor) {
50 case Common::CPUVendor::INTEL:
51 return "Intel";
52 case Common::CPUVendor::AMD:
53 return "Amd";
54 case Common::CPUVendor::OTHER:
55 return "Other";
56 }
57 UNREACHABLE();
58}
59#endif
60
61void AppendBuildInfo(FieldCollection& fc) { 47void AppendBuildInfo(FieldCollection& fc) {
62 const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr}; 48 const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr};
63 fc.AddField(FieldType::App, "Git_IsDirty", is_git_dirty); 49 fc.AddField(FieldType::App, "Git_IsDirty", is_git_dirty);
@@ -71,7 +57,6 @@ void AppendCPUInfo(FieldCollection& fc) {
71#ifdef ARCHITECTURE_x86_64 57#ifdef ARCHITECTURE_x86_64
72 fc.AddField(FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string); 58 fc.AddField(FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string);
73 fc.AddField(FieldType::UserSystem, "CPU_BrandString", Common::GetCPUCaps().brand_string); 59 fc.AddField(FieldType::UserSystem, "CPU_BrandString", Common::GetCPUCaps().brand_string);
74 fc.AddField(FieldType::UserSystem, "CPU_Vendor", CpuVendorToStr(Common::GetCPUCaps().vendor));
75 fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes); 60 fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes);
76 fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX", Common::GetCPUCaps().avx); 61 fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX", Common::GetCPUCaps().avx);
77 fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX2", Common::GetCPUCaps().avx2); 62 fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX2", Common::GetCPUCaps().avx2);
diff --git a/src/common/thread.h b/src/common/thread.h
index 0cfd98be6..2fc071685 100644
--- a/src/common/thread.h
+++ b/src/common/thread.h
@@ -28,6 +28,15 @@ public:
28 is_set = false; 28 is_set = false;
29 } 29 }
30 30
31 template <class Duration>
32 bool WaitFor(const std::chrono::duration<Duration>& time) {
33 std::unique_lock lk{mutex};
34 if (!condvar.wait_for(lk, time, [this] { return is_set; }))
35 return false;
36 is_set = false;
37 return true;
38 }
39
31 template <class Clock, class Duration> 40 template <class Clock, class Duration>
32 bool WaitUntil(const std::chrono::time_point<Clock, Duration>& time) { 41 bool WaitUntil(const std::chrono::time_point<Clock, Duration>& time) {
33 std::unique_lock lk{mutex}; 42 std::unique_lock lk{mutex};
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index 2dfcd39c8..c9349a6b4 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -3,8 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring> 5#include <cstring>
6#include <string>
7#include <thread>
8#include "common/common_types.h" 6#include "common/common_types.h"
9#include "common/x64/cpu_detect.h" 7#include "common/x64/cpu_detect.h"
10 8
@@ -51,8 +49,6 @@ namespace Common {
51static CPUCaps Detect() { 49static CPUCaps Detect() {
52 CPUCaps caps = {}; 50 CPUCaps caps = {};
53 51
54 caps.num_cores = std::thread::hardware_concurrency();
55
56 // Assumes the CPU supports the CPUID instruction. Those that don't would likely not support 52 // Assumes the CPU supports the CPUID instruction. Those that don't would likely not support
57 // yuzu at all anyway 53 // yuzu at all anyway
58 54
@@ -70,12 +66,6 @@ static CPUCaps Detect() {
70 __cpuid(cpu_id, 0x80000000); 66 __cpuid(cpu_id, 0x80000000);
71 67
72 u32 max_ex_fn = cpu_id[0]; 68 u32 max_ex_fn = cpu_id[0];
73 if (!strcmp(caps.brand_string, "GenuineIntel"))
74 caps.vendor = CPUVendor::INTEL;
75 else if (!strcmp(caps.brand_string, "AuthenticAMD"))
76 caps.vendor = CPUVendor::AMD;
77 else
78 caps.vendor = CPUVendor::OTHER;
79 69
80 // Set reasonable default brand string even if brand string not available 70 // Set reasonable default brand string even if brand string not available
81 strcpy(caps.cpu_string, caps.brand_string); 71 strcpy(caps.cpu_string, caps.brand_string);
@@ -96,15 +86,9 @@ static CPUCaps Detect() {
96 caps.sse4_1 = true; 86 caps.sse4_1 = true;
97 if ((cpu_id[2] >> 20) & 1) 87 if ((cpu_id[2] >> 20) & 1)
98 caps.sse4_2 = true; 88 caps.sse4_2 = true;
99 if ((cpu_id[2] >> 22) & 1)
100 caps.movbe = true;
101 if ((cpu_id[2] >> 25) & 1) 89 if ((cpu_id[2] >> 25) & 1)
102 caps.aes = true; 90 caps.aes = true;
103 91
104 if ((cpu_id[3] >> 24) & 1) {
105 caps.fxsave_fxrstor = true;
106 }
107
108 // AVX support requires 3 separate checks: 92 // AVX support requires 3 separate checks:
109 // - Is the AVX bit set in CPUID? 93 // - Is the AVX bit set in CPUID?
110 // - Is the XSAVE bit set in CPUID? 94 // - Is the XSAVE bit set in CPUID?
@@ -129,8 +113,6 @@ static CPUCaps Detect() {
129 } 113 }
130 } 114 }
131 115
132 caps.flush_to_zero = caps.sse;
133
134 if (max_ex_fn >= 0x80000004) { 116 if (max_ex_fn >= 0x80000004) {
135 // Extract CPU model string 117 // Extract CPU model string
136 __cpuid(cpu_id, 0x80000002); 118 __cpuid(cpu_id, 0x80000002);
@@ -144,14 +126,8 @@ static CPUCaps Detect() {
144 if (max_ex_fn >= 0x80000001) { 126 if (max_ex_fn >= 0x80000001) {
145 // Check for more features 127 // Check for more features
146 __cpuid(cpu_id, 0x80000001); 128 __cpuid(cpu_id, 0x80000001);
147 if (cpu_id[2] & 1)
148 caps.lahf_sahf_64 = true;
149 if ((cpu_id[2] >> 5) & 1)
150 caps.lzcnt = true;
151 if ((cpu_id[2] >> 16) & 1) 129 if ((cpu_id[2] >> 16) & 1)
152 caps.fma4 = true; 130 caps.fma4 = true;
153 if ((cpu_id[3] >> 29) & 1)
154 caps.long_mode = true;
155 } 131 }
156 132
157 return caps; 133 return caps;
@@ -162,48 +138,4 @@ const CPUCaps& GetCPUCaps() {
162 return caps; 138 return caps;
163} 139}
164 140
165std::string GetCPUCapsString() {
166 auto caps = GetCPUCaps();
167
168 std::string sum(caps.cpu_string);
169 sum += " (";
170 sum += caps.brand_string;
171 sum += ")";
172
173 if (caps.sse)
174 sum += ", SSE";
175 if (caps.sse2) {
176 sum += ", SSE2";
177 if (!caps.flush_to_zero)
178 sum += " (without DAZ)";
179 }
180
181 if (caps.sse3)
182 sum += ", SSE3";
183 if (caps.ssse3)
184 sum += ", SSSE3";
185 if (caps.sse4_1)
186 sum += ", SSE4.1";
187 if (caps.sse4_2)
188 sum += ", SSE4.2";
189 if (caps.avx)
190 sum += ", AVX";
191 if (caps.avx2)
192 sum += ", AVX2";
193 if (caps.bmi1)
194 sum += ", BMI1";
195 if (caps.bmi2)
196 sum += ", BMI2";
197 if (caps.fma)
198 sum += ", FMA";
199 if (caps.aes)
200 sum += ", AES";
201 if (caps.movbe)
202 sum += ", MOVBE";
203 if (caps.long_mode)
204 sum += ", 64-bit support";
205
206 return sum;
207}
208
209} // namespace Common 141} // namespace Common
diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h
index 0af3a8adb..20f2ba234 100644
--- a/src/common/x64/cpu_detect.h
+++ b/src/common/x64/cpu_detect.h
@@ -4,23 +4,12 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <string>
8
9namespace Common { 7namespace Common {
10 8
11/// x86/x64 CPU vendors that may be detected by this module
12enum class CPUVendor {
13 INTEL,
14 AMD,
15 OTHER,
16};
17
18/// x86/x64 CPU capabilities that may be detected by this module 9/// x86/x64 CPU capabilities that may be detected by this module
19struct CPUCaps { 10struct CPUCaps {
20 CPUVendor vendor;
21 char cpu_string[0x21]; 11 char cpu_string[0x21];
22 char brand_string[0x41]; 12 char brand_string[0x41];
23 int num_cores;
24 bool sse; 13 bool sse;
25 bool sse2; 14 bool sse2;
26 bool sse3; 15 bool sse3;
@@ -35,20 +24,6 @@ struct CPUCaps {
35 bool fma; 24 bool fma;
36 bool fma4; 25 bool fma4;
37 bool aes; 26 bool aes;
38
39 // Support for the FXSAVE and FXRSTOR instructions
40 bool fxsave_fxrstor;
41
42 bool movbe;
43
44 // This flag indicates that the hardware supports some mode in which denormal inputs and outputs
45 // are automatically set to (signed) zero.
46 bool flush_to_zero;
47
48 // Support for LAHF and SAHF instructions in 64-bit mode
49 bool lahf_sahf_64;
50
51 bool long_mode;
52}; 27};
53 28
54/** 29/**
@@ -57,10 +32,4 @@ struct CPUCaps {
57 */ 32 */
58const CPUCaps& GetCPUCaps(); 33const CPUCaps& GetCPUCaps();
59 34
60/**
61 * Gets a string summary of the name and supported capabilities of the host CPU
62 * @return String summary
63 */
64std::string GetCPUCapsString();
65
66} // namespace Common 35} // namespace Common