Bug 1292923 - Don't upload to textures during creation on Intel cards as it frequently crashes. r=dvander, a=gchang
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 06 Oct 2016 14:32:55 +0200
changeset 340567 bdff84e3875eef2c713550705ba0e629270e7a69
parent 340566 2235c46ad1be7a13f7176b5573b743fb69a6be48
child 340568 7accfe73f21270e6ce3763309690876f62f0fd23
push id10139
push userryanvm@gmail.com
push dateThu, 13 Oct 2016 17:19:41 +0000
treeherdermozilla-aurora@28cea4babaf8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander, gchang
bugs1292923
milestone51.0a2
Bug 1292923 - Don't upload to textures during creation on Intel cards as it frequently crashes. r=dvander, a=gchang
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
@@ -233,16 +233,20 @@ IMFYCbCrImage::GetTextureClient(Composit
   if (!device || backend != LayersBackend::LAYERS_D3D11) {
     if (backend == LayersBackend::LAYERS_D3D9 ||
         backend == LayersBackend::LAYERS_D3D11) {
       return GetD3D9TextureClient(aClient);
     }
     return nullptr;
   }
 
+  if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) {
+    return nullptr;
+  }
+
   if (mData.mYStride < 0 || mData.mCbCrStride < 0) {
     // D3D11 only supports unsigned stride values.
     return nullptr;
   }
 
   CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM,
                                 mData.mYSize.width, mData.mYSize.height, 1, 1);
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -1047,17 +1047,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 <= maxTextureSize &&
-      aSize.height <= maxTextureSize)
+      aSize.height <= maxTextureSize &&
+      !(aAllocFlags & ALLOC_UPDATE_FROM_SURFACE))
   {
     data = DXGITextureData::Create(aSize, aFormat, aAllocFlags);
   }
   if (aLayersBackend == LayersBackend::LAYERS_D3D9 &&
       moz2DBackend == gfx::BackendType::CAIRO &&
       aAllocator->IsSameProcess() &&
       aSize.width <= maxTextureSize &&
       aSize.height <= maxTextureSize &&
@@ -1164,18 +1165,19 @@ TextureClient::CreateFromSurface(Texture
 #endif
 
   if (data) {
     return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
   }
 
   // Fall back to using UpdateFromSurface
 
+  TextureAllocationFlags allocFlags = TextureAllocationFlags(aAllocFlags | ALLOC_UPDATE_FROM_SURFACE);
   RefPtr<TextureClient> client = CreateForDrawing(aAllocator, aSurface->GetFormat(), size,
-                                                  aLayersBackend, aSelector, aTextureFlags, aAllocFlags);
+                                                   aLayersBackend, 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
@@ -83,16 +83,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
@@ -667,16 +667,28 @@ DeviceManagerDx::TextureSharingWorks()
   MutexAutoLock lock(mDeviceLock);
   if (!mDeviceStatus) {
     return false;
   }
   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;
+}
+
+bool
 DeviceManagerDx::IsWARP()
 {
   MutexAutoLock lock(mDeviceLock);
   if (!mDeviceStatus) {
     return false;
   }
   return mDeviceStatus->isWARP();
 }
--- a/gfx/thebes/DeviceManagerDx.h
+++ b/gfx/thebes/DeviceManagerDx.h
@@ -55,16 +55,23 @@ public:
   RefPtr<ID3D11Device> GetContentDevice();
   RefPtr<ID3D11Device> CreateDecoderDevice();
   IDirectDraw7* GetDirectDraw();
 
   unsigned GetCompositorFeatureLevel() const;
   bool TextureSharingWorks();
   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();