Bug 1403353 - Block D3D11 when using Intel drivers on Windows 7 systems with partial AVX support. r=jrmuizel, a=lizzard FIREFOX_56_0_1_BUILD2 FIREFOX_56_0_1_RELEASE
authorDavid Anderson <danderson@mozilla.com>
Thu, 28 Sep 2017 10:51:59 -0700
changeset 694360 3e4ce49f3214e87a52a2b70ca7fbdffe20bef362
parent 694359 2d18686f1723ce21b167abf584f32563a620d92f
child 694361 c544e8973f19af60c7a59f41fe6f83d35c45b2a6
push id88118
push userbmo:edilee@mozilla.com
push dateTue, 07 Nov 2017 18:56:14 +0000
reviewersjrmuizel, lizzard
bugs1403353
milestone56.0.1
Bug 1403353 - Block D3D11 when using Intel drivers on Windows 7 systems with partial AVX support. r=jrmuizel, a=lizzard
widget/windows/GfxInfo.cpp
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -15,16 +15,17 @@
 #include "prenv.h"
 #include "prprf.h"
 #include "GfxDriverInfo.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
 #include "mozilla/gfx/Logging.h"
 #include "nsPrintfCString.h"
 #include "jsapi.h"
+#include <intrin.h>
 
 #if defined(MOZ_CRASHREPORTER)
 #include "nsExceptionHandler.h"
 #include "nsICrashReporter.h"
 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
 #endif
 
 using namespace mozilla;
@@ -970,16 +971,49 @@ WindowsVersionToOperatingSystem(int32_t 
     case kWindows10:
       return OperatingSystem::Windows10;
     case kWindowsUnknown:
     default:
       return OperatingSystem::Unknown;
     }
 }
 
+// Return true if the CPU supports AVX, but the operating system does not.
+#if defined(_M_X64)
+static inline bool
+DetectBrokenAVX()
+{
+  int regs[4];
+  __cpuid(regs, 0);
+  if (regs[0] == 0) {
+    // Level not supported.
+    return false;
+  }
+
+  __cpuid(regs, 1);
+
+  const unsigned AVX = 1u << 28;
+  const unsigned XSAVE = 1u << 26;
+  if ((regs[2] & (AVX|XSAVE)) != (AVX|XSAVE)) {
+    // AVX is not supported on this CPU.
+    return false;
+  }
+
+  const unsigned OSXSAVE = 1u << 27;
+  if ((regs[2] & OSXSAVE) != OSXSAVE) {
+    // AVX is supported, but the OS didn't enable it.
+    // This can be forced via bcdedit /set xsavedisable 1.
+    return true;
+  }
+
+  const unsigned AVX_CTRL_BITS = (1 << 1) | (1 << 2);
+  return (_xgetbv(0) & AVX_CTRL_BITS) != AVX_CTRL_BITS;
+}
+#endif
+
 const nsTArray<GfxDriverInfo>&
 GfxInfo::GetGfxDriverInfo()
 {
   if (!mDriverInfo->Length()) {
     /*
      * It should be noted here that more specialized rules on certain features
      * should be inserted -before- more generalized restriction. As the first
      * match for feature/OS/device found in the list will be used for the final
@@ -1284,16 +1318,25 @@ GfxInfo::GetGfxDriverInfo()
       DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_BUG_1336710");
 
     /* Bug 1304360: Graphical artifacts with D3D9 on Windows 7. */
     APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows7,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(IntelGMAX3000),
       nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
       DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, 1749, "FEATURE_FAILURE_INTEL_W7_D3D9_LAYERS");
 
+#if defined(_M_X64)
+    if (DetectBrokenAVX()) {
+      APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows7,
+        (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), GfxDriverInfo::allDevices,
+        nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
+        DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_BUG_1403353");
+    }
+#endif
+
     ////////////////////////////////////
     // WebGL
 
     // Older than 5-15-2016
     APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
       nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED, DRIVER_LESS_THAN,
       V(16,200,1010,1002), "WEBGL_NATIVE_GL_OLD_AMD");