diff options
Diffstat (limited to 'Source/Core/Common/XSaveWorkaround.cpp')
| -rw-r--r-- | Source/Core/Common/XSaveWorkaround.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/Source/Core/Common/XSaveWorkaround.cpp b/Source/Core/Common/XSaveWorkaround.cpp index 78f92b9bcf..d73b4a6ee0 100644 --- a/Source/Core/Common/XSaveWorkaround.cpp +++ b/Source/Core/Common/XSaveWorkaround.cpp @@ -7,6 +7,8 @@ #include <math.h> #include <Windows.h> +typedef decltype(&GetEnabledXStateFeatures) GetEnabledXStateFeatures_t; + int __cdecl EnableXSaveWorkaround() { // Some Windows environments may have hardware support for AVX/FMA, @@ -19,6 +21,24 @@ int __cdecl EnableXSaveWorkaround() if (!IsProcessorFeaturePresent(PF_XSAVE_ENABLED)) { _set_FMA3_enable(0); + return 0; + } + + // Even if XSAVE feature is enabled, we have to see if + // GetEnabledXStateFeatures function is present, and see what it says about + // AVX state. + auto kernel32Handle = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32Handle == nullptr) + { + std::abort(); + } + + auto pGetEnabledXStateFeatures = (GetEnabledXStateFeatures_t)GetProcAddress( + kernel32Handle, "GetEnabledXStateFeatures"); + if (pGetEnabledXStateFeatures == nullptr || + (pGetEnabledXStateFeatures() & XSTATE_MASK_AVX) == 0) + { + _set_FMA3_enable(0); } return 0; |
