Bug 1359416: Allow blocklisting of D3D11 keyed mutex and block it for Intel Gen 6. r=bas,dvander
authorMilan Sreckovic <milan@mozilla.com>
Tue, 25 Jul 2017 14:02:36 -0400
changeset 370998 38778100700eb9e90b829a9f045fedc97a8cff00
parent 370997 cce8190a82302fbef20fec336c5afdb5e85f3c1d
child 370999 ddda63d5366eca8bec018171271fbb426321eab1
push id92990
push usercbook@mozilla.com
push dateWed, 26 Jul 2017 09:16:20 +0000
treeherdermozilla-inbound@e9224528ba04 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas, dvander
bugs1359416
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1359416: Allow blocklisting of D3D11 keyed mutex and block it for Intel Gen 6. r=bas,dvander MozReview-Commit-ID: 2u7N5qhHhD1
gfx/config/gfxVars.h
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPrefs.h
widget/GfxInfoBase.cpp
widget/nsIGfxInfo.idl
widget/windows/GfxInfo.cpp
--- a/gfx/config/gfxVars.h
+++ b/gfx/config/gfxVars.h
@@ -34,16 +34,17 @@ class gfxVarReceiver;
   _(PDMWMFDisableD3D11Dlls,     nsCString,        nsCString())          \
   _(PDMWMFDisableD3D9Dlls,      nsCString,        nsCString())          \
   _(DXInterop2Blocked,          bool,             false)                \
   _(UseWebRender,               bool,             false)                \
   _(UseWebRenderANGLE,          bool,             false)                \
   _(ScreenDepth,                int32_t,          0)                    \
   _(GREDirectory,               nsCString,        nsCString())          \
   _(UseOMTP,                    bool,             false)                \
+  _(AllowD3D11KeyedMutex,       bool,             false)                \
 
   /* Add new entries above this line. */
 
 // Some graphics settings are computed on the UI process and must be
 // communicated to content and GPU processes. gfxVars helps facilitate
 // this. Its function is similar to gfxPrefs, except rather than hold
 // user preferences, it holds dynamically computed values.
 //
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -10,16 +10,17 @@
 #include "gfxPrefs.h"
 #include "gfxWindowsPlatform.h"
 #include "mozilla/D3DMessageUtils.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/gfx/GPUParent.h"
 #include "mozilla/gfx/GraphicsMessages.h"
 #include "mozilla/gfx/Logging.h"
+#include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/DeviceAttachmentsD3D11.h"
 #include "mozilla/layers/MLGDeviceD3D11.h"
 #include "mozilla/layers/PaintThread.h"
 #include "nsIGfxInfo.h"
 #include "nsString.h"
 #include <d3d11.h>
@@ -939,22 +940,18 @@ DeviceManagerDx::TextureSharingWorks()
   }
   return mDeviceStatus->textureSharingWorks();
 }
 
 bool
 DeviceManagerDx::CanInitializeKeyedMutexTextures()
 {
   MutexAutoLock lock(mDeviceLock);
-  if (!mDeviceStatus) {
-    return false;
-  }
-  // Disable this on all Intel devices because of crashes.
-  // See bug 1292923.
-  return (mDeviceStatus->adapter().VendorId != 0x8086 || gfxPrefs::Direct3D11AllowIntelMutex());
+  return mDeviceStatus && gfxPrefs::Direct3D11AllowKeyedMutex() &&
+         gfxVars::AllowD3D11KeyedMutex();
 }
 
 bool
 DeviceManagerDx::HasCrashyInitData()
 {
   MutexAutoLock lock(mDeviceLock);
   if (!mDeviceStatus) {
     return false;
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2280,27 +2280,38 @@ gfxPlatform::InitAcceleration()
   // If this is called for the first time on a non-main thread, we're screwed.
   // At the moment there's no explicit guarantee that the main thread calls
   // this before the compositor thread, but let's at least make the assumption
   // explicit.
   MOZ_ASSERT(NS_IsMainThread(), "can only initialize prefs on the main thread");
 
   gfxPrefs::GetSingleton();
 
+  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
+  nsCString discardFailureId;
+  int32_t status;
+
   if (XRE_IsParentProcess()) {
     gfxVars::SetBrowserTabsRemoteAutostart(BrowserTabsRemoteAutostart());
     gfxVars::SetOffscreenFormat(GetOffscreenFormat());
     gfxVars::SetRequiresAcceleratedGLContextForCompositorOGL(
               RequiresAcceleratedGLContextForCompositorOGL());
+#ifdef XP_WIN
+    if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX,
+                                               discardFailureId, &status))) {
+      gfxVars::SetAllowD3D11KeyedMutex(status == nsIGfxInfo::FEATURE_STATUS_OK);
+    } else {
+      // If we couldn't properly evaluate the status, err on the side
+      // of caution and give this functionality to the user.
+      gfxCriticalNote << "Cannot evaluate keyed mutex feature status";
+      gfxVars::SetAllowD3D11KeyedMutex(true);
+    }
+#endif
   }
 
-  nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
-  nsCString discardFailureId;
-  int32_t status;
-
   if (Preferences::GetBool("media.hardware-video-decoding.enabled", false) &&
 #ifdef XP_WIN
     Preferences::GetBool("media.windows-media-foundation.use-dxva", true) &&
 #endif
       NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING,
                                                discardFailureId, &status))) {
       if (status == nsIGfxInfo::FEATURE_STATUS_OK || gfxPrefs::HardwareVideoDecodingForceEnabled()) {
         sLayersSupportsHardwareVideoDecoding = true;
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -432,17 +432,17 @@ private:
   DECL_GFX_PREF(Once, "gfx.content.skia-font-cache-size",      SkiaContentFontCacheSize, int32_t, 10);
 
   DECL_GFX_PREF(Once, "gfx.device-reset.limit",                DeviceResetLimitCount, int32_t, 10);
   DECL_GFX_PREF(Once, "gfx.device-reset.threshold-ms",         DeviceResetThresholdMilliseconds, int32_t, -1);
 
   DECL_GFX_PREF(Once, "gfx.direct2d.disabled",                 Direct2DDisabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled",            Direct2DForceEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.direct3d11.reuse-decoder-device",   Direct3D11ReuseDecoderDevice, int32_t, -1);
-  DECL_GFX_PREF(Live, "gfx.direct3d11.allow-intel-mutex",      Direct3D11AllowIntelMutex, bool, true);
+  DECL_GFX_PREF(Live, "gfx.direct3d11.allow-keyed-mutex",      Direct3D11AllowKeyedMutex, bool, true);
   DECL_GFX_PREF(Live, "gfx.direct3d11.use-double-buffering",   Direct3D11UseDoubleBuffering, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct3d11.enable-debug-layer",     Direct3D11EnableDebugLayer, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct3d11.break-on-error",         Direct3D11BreakOnError, bool, false);
   DECL_GFX_PREF(Live, "gfx.downloadable_fonts.keep_variation_tables", KeepVariationTables, bool, false);
   DECL_GFX_PREF(Live, "gfx.downloadable_fonts.otl_validation", ValidateOTLTables, bool, true);
   DECL_GFX_PREF(Live, "gfx.draw-color-bars",                   CompositorDrawColorBars, bool, false);
   DECL_GFX_PREF(Once, "gfx.e10s.hide-plugins-for-scroll",      HidePluginsForScroll, bool, true);
   DECL_GFX_PREF(Live, "gfx.layerscope.enabled",                LayerScopeEnabled, bool, false);
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -168,16 +168,19 @@ GetPrefNameForFeature(int32_t aFeature)
       name = BLACKLIST_PREF_BRANCH "canvas2d.acceleration";
       break;
     case nsIGfxInfo::FEATURE_WEBGL2:
       name = BLACKLIST_PREF_BRANCH "webgl2";
       break;
     case nsIGfxInfo::FEATURE_ADVANCED_LAYERS:
       name = BLACKLIST_PREF_BRANCH "layers.advanced";
       break;
+    case nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX:
+      name = BLACKLIST_PREF_BRANCH "d3d11.keyed.mutex";
+      break;
     case nsIGfxInfo::FEATURE_VP8_HW_DECODE:
     case nsIGfxInfo::FEATURE_VP9_HW_DECODE:
     case nsIGfxInfo::FEATURE_DX_INTEROP2:
     case nsIGfxInfo::FEATURE_GPU_PROCESS:
       // We don't provide prefs for these features.
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!");
@@ -350,16 +353,18 @@ BlacklistFeatureToGfxFeature(const nsASt
   else if (aFeature.EqualsLiteral("WEBRTC_HW_ACCELERATION"))
     return nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION;
   else if (aFeature.EqualsLiteral("CANVAS2D_ACCELERATION"))
       return nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION;
   else if (aFeature.EqualsLiteral("WEBGL2"))
     return nsIGfxInfo::FEATURE_WEBGL2;
   else if (aFeature.EqualsLiteral("ADVANCED_LAYERS"))
     return nsIGfxInfo::FEATURE_ADVANCED_LAYERS;
+  else if (aFeature.EqualsLiteral("D3D11_KEYED_MUTEX"))
+    return nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX;
 
   // If we don't recognize the feature, it may be new, and something
   // this version doesn't understand.  So, nothing to do.  This is
   // different from feature not being specified at all, in which case
   // this method should not get called and we should continue with the
   // "all features" blocklisting.
   return -1;
 }
@@ -981,16 +986,17 @@ GfxInfoBase::EvaluateDownloadedBlacklist
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION_ENCODE,
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION_DECODE,
     nsIGfxInfo::FEATURE_WEBGL_MSAA,
     nsIGfxInfo::FEATURE_STAGEFRIGHT,
     nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION,
     nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION,
     nsIGfxInfo::FEATURE_WEBGL2,
     nsIGfxInfo::FEATURE_ADVANCED_LAYERS,
+    nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX,
     0
   };
 
   // For every feature we know about, we evaluate whether this blacklist has a
   // non-STATUS_OK status. If it does, we set the pref we evaluate in
   // GetFeatureStatus above, so we don't need to hold on to this blacklist
   // anywhere permanent.
   int i = 0;
--- a/widget/nsIGfxInfo.idl
+++ b/widget/nsIGfxInfo.idl
@@ -121,18 +121,20 @@ interface nsIGfxInfo : nsISupports
   /* Whether NV_dx_interop2 is supported, starting in 50. */
   const long FEATURE_DX_INTEROP2 = 19;
   /* Whether the GPU process is supported, starting in 52. */
   const long FEATURE_GPU_PROCESS = 20;
   /* Whether the WebGL2 is supported, starting in 54 */
   const long FEATURE_WEBGL2 = 21;
   /* Whether Advanced Layers is supported, starting in 56 */
   const long FEATURE_ADVANCED_LAYERS = 22;
+  /* Whether D3D11 keyed mutex is supported, starting in 56 */
+  const long FEATURE_D3D11_KEYED_MUTEX = 23;
   /* the maximum feature value. */
-  const long FEATURE_MAX_VALUE = FEATURE_ADVANCED_LAYERS;
+  const long FEATURE_MAX_VALUE = FEATURE_D3D11_KEYED_MUTEX;
 
   /*
    * A set of return values from GetFeatureStatus
    */
 
   /* The driver is safe to the best of our knowledge */
   const long FEATURE_STATUS_OK = 1;
   /* We don't know the status of the feature yet. The analysis probably hasn't finished yet. */
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -1313,16 +1313,27 @@ GfxInfo::GetGfxDriverInfo()
     ////////////////////////////////////
     // FEATURE_DX_INTEROP2
 
     // All AMD.
     APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
       nsIGfxInfo::FEATURE_DX_INTEROP2, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
       DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "DX_INTEROP2_AMD_CRASH");
+
+    ////////////////////////////////////
+    // FEATURE_D3D11_KEYED_MUTEX
+
+    // bug 1359416
+    APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows,
+      (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel),
+      (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelHDGraphicsToSandyBridge),
+      nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
+      DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_BUG_1359416");
+
   }
   return *mDriverInfo;
 }
 
 nsresult
 GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
                               int32_t *aStatus,
                               nsAString & aSuggestedDriverVersion,