Bug 1097321 - Reduce the amount of dual AMD/intel blacklisting. r=Bas, a=sledru
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 04 Dec 2014 23:03:31 -0800
changeset 242369 9003c05353cc0efdbfd5d5069d34ead989e6a541
parent 242368 a00fee43684a8b01444d5cf1d110727f1a6a2394
child 242370 5319eae637608454fcb26e25fdb5325f357f36d9
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas, sledru
bugs1097321
milestone36.0a2
Bug 1097321 - Reduce the amount of dual AMD/intel blacklisting. r=Bas, a=sledru Instead detect the broken shared surfaces and only black list then.
gfx/thebes/gfxWindowsPlatform.cpp
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1547,16 +1547,18 @@ gfxWindowsPlatform::GetDXGIAdapter()
   }
 
   // We leak this module everywhere, we might as well do so here as well.
   dxgiModule.disown();
 
   return mAdapter;
 }
 
+#define TEXTURE_SIZE 32
+
 // See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
 // with E_OUTOFMEMORY.
 bool DoesD3D11DeviceWork(ID3D11Device *device)
 {
   static bool checked;
   static bool result;
 
   if (checked)
@@ -1583,45 +1585,39 @@ bool DoesD3D11DeviceWork(ID3D11Device *d
     if (displayLinkModuleVersion <= V(8,6,1,36484)) {
 #if defined(MOZ_CRASHREPORTER)
       CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DisplayLink: too old version\n"));
 #endif
       return false;
     }
   }
 
-  if (GetModuleHandleW(L"atidxx32.dll")) {
-    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
-    if (gfxInfo) {
-      nsString vendorID, vendorID2;
-      gfxInfo->GetAdapterVendorID(vendorID);
-      gfxInfo->GetAdapterVendorID2(vendorID2);
-      if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
-#if defined(MOZ_CRASHREPORTER)
-        CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("Unexpected Intel/AMD dual-GPU setup\n"));
-#endif
-        return false;
-      }
-    }
-  }
-
   RefPtr<ID3D11Texture2D> texture;
   D3D11_TEXTURE2D_DESC desc;
-  desc.Width = 32;
-  desc.Height = 32;
+  desc.Width = TEXTURE_SIZE;
+  desc.Height = TEXTURE_SIZE;
   desc.MipLevels = 1;
   desc.ArraySize = 1;
   desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
   desc.SampleDesc.Count = 1;
   desc.SampleDesc.Quality = 0;
   desc.Usage = D3D11_USAGE_DEFAULT;
   desc.CPUAccessFlags = 0;
   desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
   desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
-  if (FAILED(device->CreateTexture2D(&desc, NULL, byRef(texture)))) {
+
+  int color[TEXTURE_SIZE * TEXTURE_SIZE];
+  D3D11_SUBRESOURCE_DATA data;
+  data.pSysMem = color;
+  data.SysMemPitch = TEXTURE_SIZE * 4;
+  data.SysMemSlicePitch = 0;
+  for (int i = 0; i < sizeof(color)/sizeof(color[0]); i++) {
+      color[i] = 0xff00ffff;
+  }
+  if (FAILED(device->CreateTexture2D(&desc, &data, byRef(texture)))) {
     return false;
   }
 
   HANDLE shareHandle;
   nsRefPtr<IDXGIResource> otherResource;
   if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
                                      getter_AddRefs(otherResource))))
   {
@@ -1641,16 +1637,57 @@ bool DoesD3D11DeviceWork(ID3D11Device *d
   }
 
   if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
                                             getter_AddRefs(sharedTexture))))
   {
     return false;
   }
 
+  desc.Usage = D3D11_USAGE_STAGING;
+  desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+  desc.MiscFlags = 0;
+  desc.BindFlags = 0;
+
+  RefPtr<ID3D11Texture2D> cpuTexture;
+  if (FAILED(device->CreateTexture2D(&desc, &data, byRef(cpuTexture)))) {
+    return false;
+  }
+
+  nsRefPtr<IDXGIKeyedMutex> sharedMutex;
+  nsRefPtr<ID3D11DeviceContext> deviceContext;
+  sharedResource->QueryInterface(__uuidof(IDXGIKeyedMutex), getter_AddRefs(sharedMutex));
+  device->GetImmediateContext(getter_AddRefs(deviceContext));
+  if (FAILED(sharedMutex->AcquireSync(0, 30*1000))) {
+#if defined(MOZ_CRASHREPORTER)
+    CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("Keyed Mutex timeout\n"));
+#endif
+    // only wait for 30 seconds
+    return false;
+  }
+
+  int resultColor;
+  deviceContext->CopyResource(cpuTexture, sharedTexture);
+
+  D3D11_MAPPED_SUBRESOURCE mapped;
+  deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
+  resultColor = *(int*)mapped.pData;
+  deviceContext->Unmap(cpuTexture, 0);
+
+  sharedMutex->ReleaseSync(0);
+
+  if (resultColor != color[0]) {
+    // Shared surfaces seem to be broken on dual AMD & Intel HW when using the
+    // AMD GPU
+#if defined(MOZ_CRASHREPORTER)
+    CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("Shared Surfaces don't work\n"));
+#endif
+    return false;
+  }
+
   RefPtr<ID3D11ShaderResourceView> sharedView;
 
   // This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
   if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, byRef(sharedView)))) {
     return false;
   }
 
   result = true;