Bug 1292923 - Don't upload to textures during creation on Intel cards as it frequently crashes. r=dvander
☠☠ backed out by c93ea6480724 ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 28 Sep 2016 13:28:47 +1300
changeset 316662 3855dd4690ab8556d38790e86f04fc44a4425865
parent 316661 7d77126c45ee2efee7ce8e9cf2510ffeb531e04d
child 316663 f89ded9191c0bb44134a3253cb3f4aef80f5d09d
push id82515
push usermwoodrow@mozilla.com
push dateThu, 06 Oct 2016 07:50:07 +0000
treeherdermozilla-inbound@3855dd4690ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs1292923
milestone52.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 1292923 - Don't upload to textures during creation on Intel cards as it frequently crashes. r=dvander
gfx/layers/IMFYCbCrImage.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/d3d11/TextureD3D11.cpp
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/DeviceManagerDx.h
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -232,17 +232,18 @@ IMFYCbCrImage::GetTextureClient(KnowsCom
   if (!device || backend != LayersBackend::LAYERS_D3D11) {
     if (backend == LayersBackend::LAYERS_D3D9 ||
         backend == LayersBackend::LAYERS_D3D11) {
       return GetD3D9TextureClient(aForwarder);
     }
     return nullptr;
   }
 
-  if (!gfx::DeviceManagerDx::Get()->AlphaTextureSharingWorks()) {
+  if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures() ||
+      !gfx::DeviceManagerDx::Get()->AlphaTextureSharingWorks()) {
     return nullptr;
   }
 
   if (mData.mYStride < 0 || mData.mCbCrStride < 0) {
     // D3D11 only supports unsigned stride values.
     return nullptr;
   }
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -1083,17 +1083,18 @@ TextureClient::CreateForDrawing(TextureF
 
 #ifdef XP_WIN
   if (aLayersBackend == LayersBackend::LAYERS_D3D11 &&
       (moz2DBackend == gfx::BackendType::DIRECT2D ||
        moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
        (!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
         DeviceManagerDx::Get()->GetContentDevice())) &&
       aSize.width <= aMaxTextureSize &&
-      aSize.height <= aMaxTextureSize)
+      aSize.height <= aMaxTextureSize &&
+      !(aAllocFlags & ALLOC_UPDATE_FROM_SURFACE))
   {
     data = DXGITextureData::Create(aSize, aFormat, aAllocFlags);
   }
   if (aLayersBackend == LayersBackend::LAYERS_D3D9 &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       aAllocator->IsSameProcess() &&
       aSize.width <= aMaxTextureSize &&
       aSize.height <= aMaxTextureSize &&
@@ -1196,19 +1197,19 @@ TextureClient::CreateFromSurface(KnowsCo
   }
 #endif
 
   if (data) {
     return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator->GetTextureForwarder());
   }
 
   // Fall back to using UpdateFromSurface
-
+  TextureAllocationFlags allocFlags = TextureAllocationFlags(aAllocFlags | ALLOC_UPDATE_FROM_SURFACE);
   RefPtr<TextureClient> client = CreateForDrawing(aAllocator, aSurface->GetFormat(), size,
-                                                  aSelector, aTextureFlags, aAllocFlags);
+                                                  aSelector, aTextureFlags, allocFlags);
   if (!client) {
     return nullptr;
   }
 
   TextureClientAutoLock autoLock(client, OpenMode::OPEN_WRITE_ONLY);
   if (!autoLock.Succeeded()) {
     return nullptr;
   }
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -85,16 +85,20 @@ enum TextureAllocationFlags {
   // Allocate the texture for out-of-band content updates. This is mostly for
   // TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex
   // surfaces when used on the main thread.
   ALLOC_FOR_OUT_OF_BAND_CONTENT = 1 << 5,
 
   // Disable any cross-device synchronization. This is also for TextureClientD3D11,
   // and creates a texture without KeyedMutex.
   ALLOC_MANUAL_SYNCHRONIZATION = 1 << 6,
+
+  // The texture is going to be updated using UpdateFromSurface and needs to support
+  // that call.
+  ALLOC_UPDATE_FROM_SURFACE = 1 << 7,
 };
 
 #ifdef XP_WIN
 typedef void* SyncHandle;
 #else
 typedef uintptr_t SyncHandle;
 #endif // XP_WIN
 
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -378,16 +378,21 @@ D3D11TextureData::Create(IntSize aSize, 
   newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
   if (!NS_IsMainThread() || !!(aFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT)) {
     // On the main thread we use the syncobject to handle synchronization.
     if (!(aFlags & ALLOC_MANUAL_SYNCHRONIZATION)) {
       newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
     }
   }
 
+  if (aSurface && newDesc.MiscFlags == D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX &&
+      !DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) {
+    return nullptr;
+  }
+
   D3D11_SUBRESOURCE_DATA uploadData;
   D3D11_SUBRESOURCE_DATA* uploadDataPtr = nullptr;
   RefPtr<DataSourceSurface> srcSurf;
   if (aSurface) {
     srcSurf = aSurface->GetDataSurface();
 
     if (!srcSurf) {
       gfxCriticalError() << "Failed to GetDataSurface in D3D11TextureData::Create";
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -681,16 +681,28 @@ DeviceManagerDx::AlphaTextureSharingWork
   MutexAutoLock lock(mDeviceLock);
   if (!mDeviceStatus) {
     return false;
   }
   return mDeviceStatus->alphaTextureSharingWorks();
 }
 
 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;
+}
+
+bool
 DeviceManagerDx::IsWARP()
 {
   MutexAutoLock lock(mDeviceLock);
   if (!mDeviceStatus) {
     return false;
   }
   return mDeviceStatus->isWARP();
 }
--- a/gfx/thebes/DeviceManagerDx.h
+++ b/gfx/thebes/DeviceManagerDx.h
@@ -56,16 +56,23 @@ public:
   RefPtr<ID3D11Device> CreateDecoderDevice();
   IDirectDraw7* GetDirectDraw();
 
   unsigned GetCompositorFeatureLevel() const;
   bool TextureSharingWorks();
   bool AlphaTextureSharingWorks();
   bool IsWARP();
 
+  // Returns true if we can create a texture with
+  // D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX and also
+  // upload texture data during the CreateTexture2D
+  // call. This crashes on some devices, so we might
+  // need to avoid it.
+  bool CanInitializeKeyedMutexTextures();
+
   bool CreateCompositorDevices();
   void CreateContentDevices();
 
   void ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus);
   void ExportDeviceInfo(D3D11DeviceStatus* aOut);
 
   void ResetDevices();
   void InitializeDirectDraw();