From 184d95c7204f1adce0cb45e78668ee6e8b17c604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sun, 24 Mar 2019 13:53:54 -0700 Subject: [PATCH] Fix #8947: Detection of AVX2 support --- distribution/changelog.txt | 1 + src/openrct2/util/Util.cpp | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 3336349eb5..f1dc18fa8e 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Fix: [#7884] Unfinished preserved rides can be demolished with quick demolish. - Fix: [#8873] Potential crash when placing footpaths. - Fix: [#8900] Peep tracking is not synchronized. +- Fix: [#8947] Detection of AVX2 support. - Improved: Allow the use of numpad enter key for console and chat. 0.2.2 (2019-03-13) diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index 350bfa149d..ec2e3556d0 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -223,10 +223,10 @@ bool sse41_available() bool avx2_available() { #ifdef OPENRCT2_X86 -// For GCC and similar use the builtin function, as cpuid changed its semantics in -// https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1 -// which causes it to ignore subleafs, but the new function is unavailable on Ubuntu's -// prehistoric toolchains + // For GCC and similar use the builtin function, as cpuid changed its semantics in + // https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1 + // which causes it to ignore subleafs, but the new function is unavailable on + // Ubuntu 18.04's toolchains. # if defined(OpenRCT2_CPUID_GNUC_X86) && (!defined(__FreeBSD__) || (__FreeBSD__ > 10)) return __builtin_cpu_supports("avx2"); # else @@ -234,7 +234,15 @@ bool avx2_available() uint32_t regs[4] = { 0 }; if (cpuid_x86(regs, 7)) { - return (regs[1] & (1 << 5)); + bool avxCPUSupport = (regs[1] & (1 << 5)) != 0; + if (avxCPUSupport) + { + // Need to check if OS also supports the register of xmm/ymm + // This check has to be conditional, otherwise INVALID_INSTRUCTION exception. + uint64_t xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); + avxCPUSupport = (xcrFeatureMask & 0x6) || false; + } + return avxCPUSupport; } # endif #endif