diff options
| author | 2022-03-11 17:26:41 -0800 | |
|---|---|---|
| committer | 2022-03-11 17:26:41 -0800 | |
| commit | 27cc7b6a73121ff7d467772da460a9ca85cd85bc (patch) | |
| tree | a0bc65a2fba8947a7235de75394a93a4283cd101 /src | |
| parent | Merge pull request #8003 from yuzu-emu/revert-7982-fix_cmake_missing_qt5_dbus (diff) | |
| parent | cpu_detect: Add additional x86 flags and telemetry (diff) | |
| download | yuzu-27cc7b6a73121ff7d467772da460a9ca85cd85bc.tar.gz yuzu-27cc7b6a73121ff7d467772da460a9ca85cd85bc.tar.xz yuzu-27cc7b6a73121ff7d467772da460a9ca85cd85bc.zip | |
Merge pull request #7997 from Wunkolo/cpu_detect_more
cpu_detect: Add additional x86 flags and telemetry
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/telemetry.cpp | 60 | ||||
| -rw-r--r-- | src/common/telemetry.h | 7 | ||||
| -rw-r--r-- | src/common/x64/cpu_detect.cpp | 30 | ||||
| -rw-r--r-- | src/common/x64/cpu_detect.h | 21 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 4 |
5 files changed, 90 insertions, 32 deletions
diff --git a/src/common/telemetry.cpp b/src/common/telemetry.cpp index 6241d08b3..98c82cd17 100644 --- a/src/common/telemetry.cpp +++ b/src/common/telemetry.cpp | |||
| @@ -55,22 +55,50 @@ void AppendBuildInfo(FieldCollection& fc) { | |||
| 55 | 55 | ||
| 56 | void AppendCPUInfo(FieldCollection& fc) { | 56 | void AppendCPUInfo(FieldCollection& fc) { |
| 57 | #ifdef ARCHITECTURE_x86_64 | 57 | #ifdef ARCHITECTURE_x86_64 |
| 58 | fc.AddField(FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string); | 58 | |
| 59 | fc.AddField(FieldType::UserSystem, "CPU_BrandString", Common::GetCPUCaps().brand_string); | 59 | const auto& caps = Common::GetCPUCaps(); |
| 60 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes); | 60 | const auto add_field = [&fc](std::string_view field_name, const auto& field_value) { |
| 61 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX", Common::GetCPUCaps().avx); | 61 | fc.AddField(FieldType::UserSystem, field_name, field_value); |
| 62 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX2", Common::GetCPUCaps().avx2); | 62 | }; |
| 63 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AVX512", Common::GetCPUCaps().avx512); | 63 | add_field("CPU_Model", caps.cpu_string); |
| 64 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_BMI1", Common::GetCPUCaps().bmi1); | 64 | add_field("CPU_BrandString", caps.brand_string); |
| 65 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_BMI2", Common::GetCPUCaps().bmi2); | 65 | |
| 66 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_FMA", Common::GetCPUCaps().fma); | 66 | add_field("CPU_Extension_x64_SSE", caps.sse); |
| 67 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_FMA4", Common::GetCPUCaps().fma4); | 67 | add_field("CPU_Extension_x64_SSE2", caps.sse2); |
| 68 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE", Common::GetCPUCaps().sse); | 68 | add_field("CPU_Extension_x64_SSE3", caps.sse3); |
| 69 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE2", Common::GetCPUCaps().sse2); | 69 | add_field("CPU_Extension_x64_SSSE3", caps.ssse3); |
| 70 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE3", Common::GetCPUCaps().sse3); | 70 | add_field("CPU_Extension_x64_SSE41", caps.sse4_1); |
| 71 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSSE3", Common::GetCPUCaps().ssse3); | 71 | add_field("CPU_Extension_x64_SSE42", caps.sse4_2); |
| 72 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE41", Common::GetCPUCaps().sse4_1); | 72 | |
| 73 | fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_SSE42", Common::GetCPUCaps().sse4_2); | 73 | add_field("CPU_Extension_x64_AVX", caps.avx); |
| 74 | add_field("CPU_Extension_x64_AVX_VNNI", caps.avx_vnni); | ||
| 75 | add_field("CPU_Extension_x64_AVX2", caps.avx2); | ||
| 76 | |||
| 77 | // Skylake-X/SP level AVX512, for compatibility with the previous telemetry field | ||
| 78 | add_field("CPU_Extension_x64_AVX512", | ||
| 79 | caps.avx512f && caps.avx512cd && caps.avx512vl && caps.avx512dq && caps.avx512bw); | ||
| 80 | |||
| 81 | add_field("CPU_Extension_x64_AVX512F", caps.avx512f); | ||
| 82 | add_field("CPU_Extension_x64_AVX512CD", caps.avx512cd); | ||
| 83 | add_field("CPU_Extension_x64_AVX512VL", caps.avx512vl); | ||
| 84 | add_field("CPU_Extension_x64_AVX512DQ", caps.avx512dq); | ||
| 85 | add_field("CPU_Extension_x64_AVX512BW", caps.avx512bw); | ||
| 86 | add_field("CPU_Extension_x64_AVX512BITALG", caps.avx512bitalg); | ||
| 87 | add_field("CPU_Extension_x64_AVX512VBMI", caps.avx512vbmi); | ||
| 88 | |||
| 89 | add_field("CPU_Extension_x64_AES", caps.aes); | ||
| 90 | add_field("CPU_Extension_x64_BMI1", caps.bmi1); | ||
| 91 | add_field("CPU_Extension_x64_BMI2", caps.bmi2); | ||
| 92 | add_field("CPU_Extension_x64_F16C", caps.f16c); | ||
| 93 | add_field("CPU_Extension_x64_FMA", caps.fma); | ||
| 94 | add_field("CPU_Extension_x64_FMA4", caps.fma4); | ||
| 95 | add_field("CPU_Extension_x64_GFNI", caps.gfni); | ||
| 96 | add_field("CPU_Extension_x64_INVARIANT_TSC", caps.invariant_tsc); | ||
| 97 | add_field("CPU_Extension_x64_LZCNT", caps.lzcnt); | ||
| 98 | add_field("CPU_Extension_x64_MOVBE", caps.movbe); | ||
| 99 | add_field("CPU_Extension_x64_PCLMULQDQ", caps.pclmulqdq); | ||
| 100 | add_field("CPU_Extension_x64_POPCNT", caps.popcnt); | ||
| 101 | add_field("CPU_Extension_x64_SHA", caps.sha); | ||
| 74 | #else | 102 | #else |
| 75 | fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); | 103 | fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); |
| 76 | #endif | 104 | #endif |
diff --git a/src/common/telemetry.h b/src/common/telemetry.h index 4d632f7eb..3524c857e 100644 --- a/src/common/telemetry.h +++ b/src/common/telemetry.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <map> | 8 | #include <map> |
| 9 | #include <memory> | 9 | #include <memory> |
| 10 | #include <string> | 10 | #include <string> |
| 11 | #include <string_view> | ||
| 11 | #include "common/common_funcs.h" | 12 | #include "common/common_funcs.h" |
| 12 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 13 | 14 | ||
| @@ -55,8 +56,8 @@ class Field : public FieldInterface { | |||
| 55 | public: | 56 | public: |
| 56 | YUZU_NON_COPYABLE(Field); | 57 | YUZU_NON_COPYABLE(Field); |
| 57 | 58 | ||
| 58 | Field(FieldType type_, std::string name_, T value_) | 59 | Field(FieldType type_, std::string_view name_, T value_) |
| 59 | : name(std::move(name_)), type(type_), value(std::move(value_)) {} | 60 | : name(name_), type(type_), value(std::move(value_)) {} |
| 60 | 61 | ||
| 61 | ~Field() override = default; | 62 | ~Field() override = default; |
| 62 | 63 | ||
| @@ -123,7 +124,7 @@ public: | |||
| 123 | * @param value Value for the field to add. | 124 | * @param value Value for the field to add. |
| 124 | */ | 125 | */ |
| 125 | template <typename T> | 126 | template <typename T> |
| 126 | void AddField(FieldType type, const char* name, T value) { | 127 | void AddField(FieldType type, std::string_view name, T value) { |
| 127 | return AddField(std::make_unique<Field<T>>(type, name, std::move(value))); | 128 | return AddField(std::make_unique<Field<T>>(type, name, std::move(value))); |
| 128 | } | 129 | } |
| 129 | 130 | ||
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index 99d87f586..d81edb140 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp | |||
| @@ -93,10 +93,14 @@ static CPUCaps Detect() { | |||
| 93 | caps.sse = Common::Bit<25>(cpu_id[3]); | 93 | caps.sse = Common::Bit<25>(cpu_id[3]); |
| 94 | caps.sse2 = Common::Bit<26>(cpu_id[3]); | 94 | caps.sse2 = Common::Bit<26>(cpu_id[3]); |
| 95 | caps.sse3 = Common::Bit<0>(cpu_id[2]); | 95 | caps.sse3 = Common::Bit<0>(cpu_id[2]); |
| 96 | caps.pclmulqdq = Common::Bit<1>(cpu_id[2]); | ||
| 96 | caps.ssse3 = Common::Bit<9>(cpu_id[2]); | 97 | caps.ssse3 = Common::Bit<9>(cpu_id[2]); |
| 97 | caps.sse4_1 = Common::Bit<19>(cpu_id[2]); | 98 | caps.sse4_1 = Common::Bit<19>(cpu_id[2]); |
| 98 | caps.sse4_2 = Common::Bit<20>(cpu_id[2]); | 99 | caps.sse4_2 = Common::Bit<20>(cpu_id[2]); |
| 100 | caps.movbe = Common::Bit<22>(cpu_id[2]); | ||
| 101 | caps.popcnt = Common::Bit<23>(cpu_id[2]); | ||
| 99 | caps.aes = Common::Bit<25>(cpu_id[2]); | 102 | caps.aes = Common::Bit<25>(cpu_id[2]); |
| 103 | caps.f16c = Common::Bit<29>(cpu_id[2]); | ||
| 100 | 104 | ||
| 101 | // AVX support requires 3 separate checks: | 105 | // AVX support requires 3 separate checks: |
| 102 | // - Is the AVX bit set in CPUID? | 106 | // - Is the AVX bit set in CPUID? |
| @@ -112,16 +116,26 @@ static CPUCaps Detect() { | |||
| 112 | 116 | ||
| 113 | if (max_std_fn >= 7) { | 117 | if (max_std_fn >= 7) { |
| 114 | __cpuidex(cpu_id, 0x00000007, 0x00000000); | 118 | __cpuidex(cpu_id, 0x00000007, 0x00000000); |
| 115 | // Can't enable AVX2 unless the XSAVE/XGETBV checks above passed | 119 | // Can't enable AVX{2,512} unless the XSAVE/XGETBV checks above passed |
| 116 | caps.avx2 = caps.avx && Common::Bit<5>(cpu_id[1]); | 120 | if (caps.avx) { |
| 121 | caps.avx2 = Common::Bit<5>(cpu_id[1]); | ||
| 122 | caps.avx512f = Common::Bit<16>(cpu_id[1]); | ||
| 123 | caps.avx512dq = Common::Bit<17>(cpu_id[1]); | ||
| 124 | caps.avx512cd = Common::Bit<28>(cpu_id[1]); | ||
| 125 | caps.avx512bw = Common::Bit<30>(cpu_id[1]); | ||
| 126 | caps.avx512vl = Common::Bit<31>(cpu_id[1]); | ||
| 127 | caps.avx512vbmi = Common::Bit<1>(cpu_id[2]); | ||
| 128 | caps.avx512bitalg = Common::Bit<12>(cpu_id[2]); | ||
| 129 | } | ||
| 130 | |||
| 117 | caps.bmi1 = Common::Bit<3>(cpu_id[1]); | 131 | caps.bmi1 = Common::Bit<3>(cpu_id[1]); |
| 118 | caps.bmi2 = Common::Bit<8>(cpu_id[1]); | 132 | caps.bmi2 = Common::Bit<8>(cpu_id[1]); |
| 119 | // Checks for AVX512F, AVX512CD, AVX512VL, AVX512DQ, AVX512BW (Intel Skylake-X/SP) | 133 | caps.sha = Common::Bit<29>(cpu_id[1]); |
| 120 | if (Common::Bit<16>(cpu_id[1]) && Common::Bit<28>(cpu_id[1]) && | 134 | |
| 121 | Common::Bit<31>(cpu_id[1]) && Common::Bit<17>(cpu_id[1]) && | 135 | caps.gfni = Common::Bit<8>(cpu_id[2]); |
| 122 | Common::Bit<30>(cpu_id[1])) { | 136 | |
| 123 | caps.avx512 = caps.avx2; | 137 | __cpuidex(cpu_id, 0x00000007, 0x00000001); |
| 124 | } | 138 | caps.avx_vnni = caps.avx && Common::Bit<4>(cpu_id[0]); |
| 125 | } | 139 | } |
| 126 | } | 140 | } |
| 127 | 141 | ||
diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h index 3e6d808f3..40c48b132 100644 --- a/src/common/x64/cpu_detect.h +++ b/src/common/x64/cpu_detect.h | |||
| @@ -35,16 +35,31 @@ struct CPUCaps { | |||
| 35 | bool ssse3 : 1; | 35 | bool ssse3 : 1; |
| 36 | bool sse4_1 : 1; | 36 | bool sse4_1 : 1; |
| 37 | bool sse4_2 : 1; | 37 | bool sse4_2 : 1; |
| 38 | bool lzcnt : 1; | 38 | |
| 39 | bool avx : 1; | 39 | bool avx : 1; |
| 40 | bool avx_vnni : 1; | ||
| 40 | bool avx2 : 1; | 41 | bool avx2 : 1; |
| 41 | bool avx512 : 1; | 42 | bool avx512f : 1; |
| 43 | bool avx512dq : 1; | ||
| 44 | bool avx512cd : 1; | ||
| 45 | bool avx512bw : 1; | ||
| 46 | bool avx512vl : 1; | ||
| 47 | bool avx512vbmi : 1; | ||
| 48 | bool avx512bitalg : 1; | ||
| 49 | |||
| 50 | bool aes : 1; | ||
| 42 | bool bmi1 : 1; | 51 | bool bmi1 : 1; |
| 43 | bool bmi2 : 1; | 52 | bool bmi2 : 1; |
| 53 | bool f16c : 1; | ||
| 44 | bool fma : 1; | 54 | bool fma : 1; |
| 45 | bool fma4 : 1; | 55 | bool fma4 : 1; |
| 46 | bool aes : 1; | 56 | bool gfni : 1; |
| 47 | bool invariant_tsc : 1; | 57 | bool invariant_tsc : 1; |
| 58 | bool lzcnt : 1; | ||
| 59 | bool movbe : 1; | ||
| 60 | bool pclmulqdq : 1; | ||
| 61 | bool popcnt : 1; | ||
| 62 | bool sha : 1; | ||
| 48 | }; | 63 | }; |
| 49 | 64 | ||
| 50 | /** | 65 | /** |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index b3a8da0ea..1d459bdb3 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -249,9 +249,9 @@ GMainWindow::GMainWindow() | |||
| 249 | #ifdef ARCHITECTURE_x86_64 | 249 | #ifdef ARCHITECTURE_x86_64 |
| 250 | const auto& caps = Common::GetCPUCaps(); | 250 | const auto& caps = Common::GetCPUCaps(); |
| 251 | std::string cpu_string = caps.cpu_string; | 251 | std::string cpu_string = caps.cpu_string; |
| 252 | if (caps.avx || caps.avx2 || caps.avx512) { | 252 | if (caps.avx || caps.avx2 || caps.avx512f) { |
| 253 | cpu_string += " | AVX"; | 253 | cpu_string += " | AVX"; |
| 254 | if (caps.avx512) { | 254 | if (caps.avx512f) { |
| 255 | cpu_string += "512"; | 255 | cpu_string += "512"; |
| 256 | } else if (caps.avx2) { | 256 | } else if (caps.avx2) { |
| 257 | cpu_string += '2'; | 257 | cpu_string += '2'; |