From d0c3e46c800ec30492127589e3a55ac912b28e90 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Sun, 10 Aug 2014 14:29:03 -0700 Subject: [PATCH] Windows: Improve XSaveWorkaround to behave correctly when XSAVE processor feature is enabled, but AVX support isn't available for whatever reason. --- Source/Core/Common/XSaveWorkaround.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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 #include +typedef decltype(&GetEnabledXStateFeatures) GetEnabledXStateFeatures_t; + int __cdecl EnableXSaveWorkaround() { // Some Windows environments may have hardware support for AVX/FMA, @@ -17,6 +19,24 @@ int __cdecl EnableXSaveWorkaround() // The API name is somewhat misleading - we're testing for OS support // here. 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); }