Bug 1083071 - Disable D3D11 and D3D9 layers on broken drivers. r=bjacob

This will hopefully prevent black screen problems that people are seeing.
This commit is contained in:
Jeff Muizelaar 2014-10-23 00:15:22 -04:00
parent c47f85d5a5
commit 1509c79b2d
3 changed files with 84 additions and 4 deletions

View File

@ -391,7 +391,10 @@ gfxWindowsPlatform::UpdateRenderMode()
tryD2D = false;
}
if (isVistaOrHigher && !safeMode && tryD2D) {
ID3D11Device *device = GetD3D11Device();
if (isVistaOrHigher && !safeMode && tryD2D && device &&
DoesD3D11DeviceSupportResourceSharing(device)) {
VerifyD2DDevice(d2dForceEnabled);
if (mD2DDevice) {
mRenderMode = RENDER_DIRECT2D;
@ -1500,6 +1503,70 @@ gfxWindowsPlatform::GetDXGIAdapter()
return mAdapter;
}
// See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
// with E_OUTOFMEMORY.
bool DoesD3D11DeviceSupportResourceSharing(ID3D11Device *device)
{
static bool checked;
static bool result;
if (checked)
return result;
checked = true;
RefPtr<ID3D11Texture2D> texture;
D3D11_TEXTURE2D_DESC desc;
desc.Width = 32;
desc.Height = 32;
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)))) {
return false;
}
HANDLE shareHandle;
nsRefPtr<IDXGIResource> otherResource;
if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
getter_AddRefs(otherResource))))
{
return false;
}
if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
return false;
}
nsRefPtr<ID3D11Resource> sharedResource;
nsRefPtr<ID3D11Texture2D> sharedTexture;
if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
getter_AddRefs(sharedResource))))
{
return false;
}
if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
getter_AddRefs(sharedTexture))))
{
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;
return true;
}
void
gfxWindowsPlatform::InitD3D11Devices()
{

View File

@ -305,4 +305,6 @@ private:
nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
};
bool DoesD3D11DeviceSupportResourceSharing(ID3D11Device *device);
#endif /* GFX_WINDOWS_PLATFORM_H */

View File

@ -6733,10 +6733,21 @@ nsWindow::GetPreferredCompositorBackends(nsTArray<LayersBackend>& aHints)
if (prefs.mPreferOpenGL) {
aHints.AppendElement(LayersBackend::LAYERS_OPENGL);
}
if (!prefs.mPreferD3D9) {
aHints.AppendElement(LayersBackend::LAYERS_D3D11);
ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
if (device && !DoesD3D11DeviceSupportResourceSharing(device)) {
// bug 1083071 - bad things - fall back to basic layers
// This should not happen aside from driver bugs, and in particular
// should not happen on our test machines, so let's NS_ERROR to ensure
// that we would catch it as a test failure.
NS_ERROR("Can't use Direct3D 11 because of a driver bug "
"causing resource sharing to fail");
} else {
if (!prefs.mPreferD3D9) {
aHints.AppendElement(LayersBackend::LAYERS_D3D11);
}
aHints.AppendElement(LayersBackend::LAYERS_D3D9);
}
aHints.AppendElement(LayersBackend::LAYERS_D3D9);
}
aHints.AppendElement(LayersBackend::LAYERS_BASIC);
}