Bug 1286653 - Re-run blacklist on DXGI adapter used for device creation r=BenWa,dvander

MozReview-Commit-ID: 9QV8QFu5WYR

--HG--
extra : rebase_source : d0da9409b2818a1ebce1469daecc3ca436bfa33e
This commit is contained in:
eyim 2016-08-11 18:20:21 -04:00
Родитель 0ccf1ca369
Коммит f6feed92b7
6 изменённых файлов: 228 добавлений и 104 удалений

Просмотреть файл

@ -92,6 +92,35 @@ DeviceManagerD3D11::CreateDevices()
}
if (XRE_IsParentProcess()) {
// reset the primary adapter information, given the adapter from device creation
RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
DXGI_ADAPTER_DESC adapterDesc;
nsString vendorID;
nsString deviceID;
if (!adapter) { // no dxgiadapter
d3d11.SetFailed(FeatureStatus::Failed, "No DXGI adapter found",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGIADAPTER"));
return;
}
adapter->GetDesc(&adapterDesc);
vendorID.AppendPrintf("0x%04x", adapterDesc.VendorId);
deviceID.AppendPrintf("0x%04x", adapterDesc.DeviceId);
if (nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo()) {
gfxInfo->Reset(vendorID, deviceID);
// check device to see if blacklisted after device creation successful
nsCString message;
nsCString failureId;
if (!gfxPlatform::IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, &message, failureId)) {
d3d11.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
return;
}
}
if (!gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
AttemptD3D11DeviceCreation(d3d11);
if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {

Просмотреть файл

@ -575,6 +575,13 @@ GfxInfoBase::Init()
return NS_OK;
}
NS_IMETHODIMP
GfxInfoBase::Reset(const nsAString& aVendorID, const nsAString& aDeviceID)
{
NS_ABORT();
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
GfxInfoBase::GetFeatureStatus(int32_t aFeature, nsACString& aFailureId, int32_t* aStatus)
{

Просмотреть файл

@ -59,6 +59,8 @@ public:
NS_IMETHOD GetFeatureLog(JSContext*, JS::MutableHandle<JS::Value>) override;
NS_IMETHOD GetActiveCrashGuards(JSContext*, JS::MutableHandle<JS::Value>) override;
NS_IMETHOD Reset(const nsAString& aVendorID, const nsAString& aDeviceID) override;
// Initialization function. If you override this, you must call this class's
// version of Init first.
// We need Init to be called separately from the constructor so we can

Просмотреть файл

@ -156,6 +156,12 @@ interface nsIGfxInfo : nsISupports
// only useful on X11
[noscript, notxpcom] void GetData();
/**
* At startup we sometimes have to make a guess what device we're going to be
* using. We can reset this once we've gotten an exact device.
*/
[noscript] void Reset (in AString aVendorID, in AString aDeviceID);
[implicit_jscontext]
jsval getInfo();

Просмотреть файл

@ -299,114 +299,17 @@ GfxInfo::Init()
deviceIndex++;
}
// make sure the string is nullptr terminated
if (wcsnlen(displayDevice.DeviceKey, ArrayLength(displayDevice.DeviceKey))
== ArrayLength(displayDevice.DeviceKey)) {
// we did not find a nullptr
rv = UpdatePrimaryDeviceInfo(displayDevice);
if (rv != NS_OK) {
return rv;
}
mDeviceKeyDebug = displayDevice.DeviceKey;
/* DeviceKey is "reserved" according to MSDN so we'll be careful with it */
/* check that DeviceKey begins with DEVICE_KEY_PREFIX */
/* some systems have a DeviceKey starting with \REGISTRY\Machine\ so we need to compare case insenstively */
if (_wcsnicmp(displayDevice.DeviceKey, DEVICE_KEY_PREFIX, ArrayLength(DEVICE_KEY_PREFIX)-1) != 0)
return rv;
// chop off DEVICE_KEY_PREFIX
mDeviceKey = displayDevice.DeviceKey + ArrayLength(DEVICE_KEY_PREFIX)-1;
mDeviceID = displayDevice.DeviceID;
mDeviceString = displayDevice.DeviceString;
// On Windows 8 and Server 2012 hosts, we want to not block RDP
// sessions from attempting hardware acceleration. RemoteFX
// provides features and functionaltiy that can give a good D3D10 +
// D2D + DirectWrite experience emulated via a software GPU.
//
// Unfortunately, the Device ID is nullptr, and we can't enumerate
// it using the setup infrastructure (SetupDiGetClassDevsW below
// will return INVALID_HANDLE_VALUE).
if (mWindowsVersion == kWindows8 &&
mDeviceID.Length() == 0 &&
mDeviceString.EqualsLiteral("RDPUDD Chained DD"))
{
WCHAR sysdir[255];
UINT len = GetSystemDirectory(sysdir, sizeof(sysdir));
if (len < sizeof(sysdir)) {
nsString rdpudd(sysdir);
rdpudd.AppendLiteral("\\rdpudd.dll");
gfxWindowsPlatform::GetDLLVersion(rdpudd.BeginReading(), mDriverVersion);
mDriverDate.AssignLiteral("01-01-1970");
// 0x1414 is Microsoft; 0xfefe is an invented (and unused) code
mDeviceID.AssignLiteral("PCI\\VEN_1414&DEV_FEFE&SUBSYS_00000000");
}
}
/* create a device information set composed of the current display device */
HDEVINFO devinfo = SetupDiGetClassDevsW(nullptr, mDeviceID.get(), nullptr,
DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
if (devinfo != INVALID_HANDLE_VALUE) {
HKEY key;
LONG result;
WCHAR value[255];
DWORD dwcbData;
SP_DEVINFO_DATA devinfoData;
DWORD memberIndex = 0;
devinfoData.cbSize = sizeof(devinfoData);
NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
/* enumerate device information elements in the device information set */
while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
/* get a string that identifies the device's driver key */
if (SetupDiGetDeviceRegistryPropertyW(devinfo,
&devinfoData,
SPDRP_DRIVER,
nullptr,
(PBYTE)value,
sizeof(value),
nullptr)) {
nsAutoString driverKey(driverKeyPre);
driverKey += value;
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.get(), 0, KEY_QUERY_VALUE, &key);
if (result == ERROR_SUCCESS) {
/* we've found the driver we're looking for */
dwcbData = sizeof(value);
result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr,
(LPBYTE)value, &dwcbData);
if (result == ERROR_SUCCESS) {
mDriverVersion = value;
} else {
// If the entry wasn't found, assume the worst (0.0.0.0).
mDriverVersion.AssignLiteral("0.0.0.0");
}
dwcbData = sizeof(value);
result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr,
(LPBYTE)value, &dwcbData);
if (result == ERROR_SUCCESS) {
mDriverDate = value;
} else {
// Again, assume the worst
mDriverDate.AssignLiteral("01-01-1970");
}
RegCloseKey(key);
break;
}
}
}
SetupDiDestroyDeviceInfoList(devinfo);
}
mAdapterVendorID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "VEN_", 4));
mAdapterDeviceID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "&DEV_", 4));
mAdapterSubsysID.AppendPrintf("%08x", ParseIDFromDeviceID(mDeviceID, "&SUBSYS_", 8));
// We now check for second display adapter.
HDEVINFO devinfo;
// Device interface class for display adapters.
CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
@ -518,6 +421,183 @@ GfxInfo::Init()
}
}
CheckAndUpdateDriverInfo();
AddCrashReportAnnotations();
return rv;
}
nsresult
GfxInfo::Reset(const nsAString& aVendorID, const nsAString& aDeviceID)
{
nsresult rv = NS_OK;
if (aVendorID.IsEmpty() || aDeviceID.IsEmpty()) {
return NS_ERROR_ILLEGAL_VALUE;
}
DISPLAY_DEVICEW displayDevice;
displayDevice.cb = sizeof(displayDevice);
int deviceIndex = 0;
nsString tempDeviceID;
nsString tempAdapterVendorID;
nsString tempAdapterDeviceID;
nsString tempAdapterSubsysID;
while (EnumDisplayDevicesW(nullptr, deviceIndex, &displayDevice, 0)) {
// reset these strings due to append later
tempAdapterVendorID = NS_LITERAL_STRING("");
tempAdapterDeviceID = NS_LITERAL_STRING("");
tempAdapterSubsysID = NS_LITERAL_STRING("");
tempDeviceID = displayDevice.DeviceID;
tempAdapterVendorID.AppendPrintf("0x%04x", ParseIDFromDeviceID(tempDeviceID, "VEN_", 4));
tempAdapterDeviceID.AppendPrintf("0x%04x", ParseIDFromDeviceID(tempDeviceID, "&DEV_", 4));
tempAdapterSubsysID.AppendPrintf("%08x", ParseIDFromDeviceID(tempDeviceID, "&SUBSYS_", 8));
// look for device that has the same vendor and device id as given
if (mAdapterVendorID.Equals(aVendorID) && mAdapterDeviceID.Equals(aDeviceID)){
break;
}
deviceIndex++;
}
if (tempAdapterVendorID.Equals(aVendorID) && tempAdapterDeviceID.Equals(aDeviceID)) {
mDeviceID = tempDeviceID;
mAdapterVendorID = tempAdapterVendorID;
mAdapterDeviceID = tempAdapterDeviceID;
mAdapterSubsysID = tempAdapterSubsysID;
} else { // vendorid and deviceid given cannot be found
return NS_ERROR_UNEXPECTED;
}
rv = UpdatePrimaryDeviceInfo(displayDevice);
if (rv != NS_OK) {
return rv;
}
CheckAndUpdateDriverInfo();
AddCrashReportAnnotations();
return rv;
}
nsresult
GfxInfo::UpdatePrimaryDeviceInfo(DISPLAY_DEVICEW &displayDevice)
{
nsresult rv = NS_ERROR_FAILURE;
// make sure the string is nullptr terminated
if (wcsnlen(displayDevice.DeviceKey, ArrayLength(displayDevice.DeviceKey))
== ArrayLength(displayDevice.DeviceKey)) {
// we did not find a nullptr
return rv;
}
mDeviceKeyDebug = displayDevice.DeviceKey;
/* DeviceKey is "reserved" according to MSDN so we'll be careful with it */
/* check that DeviceKey begins with DEVICE_KEY_PREFIX */
/* some systems have a DeviceKey starting with \REGISTRY\Machine\ so we need to compare case insenstively */
if (_wcsnicmp(displayDevice.DeviceKey, DEVICE_KEY_PREFIX, ArrayLength(DEVICE_KEY_PREFIX)-1) != 0)
return rv;
// chop off DEVICE_KEY_PREFIX
mDeviceKey = displayDevice.DeviceKey + ArrayLength(DEVICE_KEY_PREFIX)-1;
mDeviceID = displayDevice.DeviceID;
mDeviceString = displayDevice.DeviceString;
// On Windows 8 and Server 2012 hosts, we want to not block RDP
// sessions from attempting hardware acceleration. RemoteFX
// provides features and functionaltiy that can give a good D3D10 +
// D2D + DirectWrite experience emulated via a software GPU.
//
// Unfortunately, the Device ID is nullptr, and we can't enumerate
// it using the setup infrastructure (SetupDiGetClassDevsW below
// will return INVALID_HANDLE_VALUE).
if (mWindowsVersion == kWindows8 &&
mDeviceID.Length() == 0 &&
mDeviceString.EqualsLiteral("RDPUDD Chained DD"))
{
WCHAR sysdir[255];
UINT len = GetSystemDirectory(sysdir, sizeof(sysdir));
if (len < sizeof(sysdir)) {
nsString rdpudd(sysdir);
rdpudd.AppendLiteral("\\rdpudd.dll");
gfxWindowsPlatform::GetDLLVersion(rdpudd.BeginReading(), mDriverVersion);
mDriverDate.AssignLiteral("01-01-1970");
// 0x1414 is Microsoft; 0xfefe is an invented (and unused) code
mDeviceID.AssignLiteral("PCI\\VEN_1414&DEV_FEFE&SUBSYS_00000000");
}
}
/* create a device information set composed of the current display device */
HDEVINFO devinfo = SetupDiGetClassDevsW(nullptr, mDeviceID.get(), nullptr,
DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
if (devinfo != INVALID_HANDLE_VALUE) {
HKEY key;
LONG result;
WCHAR value[255];
DWORD dwcbData;
SP_DEVINFO_DATA devinfoData;
DWORD memberIndex = 0;
devinfoData.cbSize = sizeof(devinfoData);
NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
/* enumerate device information elements in the device information set */
while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
/* get a string that identifies the device's driver key */
if (SetupDiGetDeviceRegistryPropertyW(devinfo,
&devinfoData,
SPDRP_DRIVER,
nullptr,
(PBYTE)value,
sizeof(value),
nullptr)) {
nsAutoString driverKey(driverKeyPre);
driverKey += value;
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.get(), 0, KEY_QUERY_VALUE, &key);
if (result == ERROR_SUCCESS) {
/* we've found the driver we're looking for */
dwcbData = sizeof(value);
result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr,
(LPBYTE)value, &dwcbData);
if (result == ERROR_SUCCESS) {
mDriverVersion = value;
} else {
// If the entry wasn't found, assume the worst (0.0.0.0).
mDriverVersion.AssignLiteral("0.0.0.0");
}
dwcbData = sizeof(value);
result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr,
(LPBYTE)value, &dwcbData);
if (result == ERROR_SUCCESS) {
mDriverDate = value;
} else {
// Again, assume the worst
mDriverDate.AssignLiteral("01-01-1970");
}
RegCloseKey(key);
break;
}
}
}
SetupDiDestroyDeviceInfoList(devinfo);
}
return NS_OK;
}
void
GfxInfo::CheckAndUpdateDriverInfo()
{
mHasDriverVersionMismatch = false;
if (mAdapterVendorID == GfxDriverInfo::GetDeviceVendor(VendorIntel)) {
// we've had big crashers (bugs 590373 and 595364) apparently correlated
@ -574,10 +654,6 @@ GfxInfo::Init()
if (spoofedDevice) {
mAdapterDeviceID.AssignASCII(spoofedDevice);
}
AddCrashReportAnnotations();
return rv;
}
NS_IMETHODIMP

Просмотреть файл

@ -46,6 +46,8 @@ public:
using GfxInfoBase::GetFeatureSuggestedDriverVersion;
using GfxInfoBase::GetWebGLParameter;
NS_IMETHOD Reset(const nsAString& aVendorID, const nsAString& aDeviceID) override;
virtual nsresult Init() override;
virtual uint32_t OperatingSystemVersion() override { return mWindowsVersion; }
@ -72,6 +74,8 @@ protected:
private:
void AddCrashReportAnnotations();
nsresult UpdatePrimaryDeviceInfo(DISPLAY_DEVICEW &displayDevice);
void CheckAndUpdateDriverInfo();
nsString mDeviceString;
nsString mDeviceID;