Disable Vulkan backend on old Intel Windows driver version

Skip enabling Vulkan backend on Intel Windows driver version < 30.0.101.2111 due to many flaky issue.

Bug: chromium:1338622, dawn:1392
Change-Id: I6975783bdc18d8a94d6c35e134756e3713833a29
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/105741
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Hao Li <hao.x.li@intel.com>
This commit is contained in:
Li Hao 2022-12-01 10:15:35 +00:00 committed by Dawn LUCI CQ
parent b663db0584
commit 5f8b9d28bc
10 changed files with 167 additions and 58 deletions

View File

@ -15,6 +15,9 @@
#include "dawn/common/GPUInfo.h"
#include <algorithm>
#include <array>
#include <iterator>
#include <sstream>
#include "dawn/common/Assert.h"
@ -33,18 +36,52 @@ const std::array<uint32_t, 25> Skylake = {{0x1902, 0x1906, 0x190A, 0x190B, 0x190
// last two fields.
// See https://www.intel.com/content/www/us/en/support/articles/000005654/graphics.html for
// more details.
uint32_t GetIntelD3DDriverBuildNumber(const D3DDriverVersion& driverVersion) {
return driverVersion[2] * 10000 + driverVersion[3];
uint32_t GetIntelWindowsDriverBuildNumber(const DriverVersion& driverVersion) {
size_t size = driverVersion.size();
ASSERT(size >= 2);
return driverVersion[size - 2] * 10000 + driverVersion[size - 1];
}
} // anonymous namespace
int CompareD3DDriverVersion(PCIVendorID vendorId,
const D3DDriverVersion& version1,
const D3DDriverVersion& version2) {
DriverVersion::DriverVersion() = default;
DriverVersion::DriverVersion(const std::initializer_list<uint16_t>& version) {
ASSERT(version.size() <= kMaxVersionFields);
mDriverVersion->assign(version.begin(), version.end());
}
uint16_t& DriverVersion::operator[](size_t i) {
return mDriverVersion->operator[](i);
}
const uint16_t& DriverVersion::operator[](size_t i) const {
return mDriverVersion->operator[](i);
}
uint32_t DriverVersion::size() const {
return mDriverVersion->size();
}
std::string DriverVersion::ToString() const {
std::ostringstream oss;
if (mDriverVersion->size() > 0) {
// Convert all but the last element to avoid a trailing "."
std::copy(mDriverVersion->begin(), mDriverVersion->end() - 1,
std::ostream_iterator<uint16_t>(oss, "."));
// Add the last element
oss << mDriverVersion->back();
}
return oss.str();
}
int CompareWindowsDriverVersion(PCIVendorID vendorId,
const DriverVersion& version1,
const DriverVersion& version2) {
if (IsIntel(vendorId)) {
uint32_t buildNumber1 = GetIntelD3DDriverBuildNumber(version1);
uint32_t buildNumber2 = GetIntelD3DDriverBuildNumber(version2);
uint32_t buildNumber1 = GetIntelWindowsDriverBuildNumber(version1);
uint32_t buildNumber2 = GetIntelWindowsDriverBuildNumber(version2);
return buildNumber1 < buildNumber2 ? -1 : (buildNumber1 == buildNumber2 ? 0 : 1);
}

View File

@ -15,22 +15,42 @@
#ifndef SRC_DAWN_COMMON_GPUINFO_H_
#define SRC_DAWN_COMMON_GPUINFO_H_
#include "dawn/common/GPUInfo_autogen.h"
#include <string>
#include <array>
#include "dawn/common/GPUInfo_autogen.h"
#include "dawn/common/StackContainer.h"
namespace gpu_info {
using D3DDriverVersion = std::array<uint16_t, 4>;
// Four uint16 fields could cover almost all driver version schemas:
// D3D12: AA.BB.CCC.DDDD
// Vulkan: AAA.BBB.CCC.DDD on Nvidia, CCC.DDDD for Intel Windows, and AA.BB.CCC for others,
// See https://vulkan.gpuinfo.org/
static constexpr uint32_t kMaxVersionFields = 4;
class DriverVersion {
public:
DriverVersion();
DriverVersion(const std::initializer_list<uint16_t>& version);
uint16_t& operator[](size_t i);
const uint16_t& operator[](size_t i) const;
uint32_t size() const;
std::string ToString() const;
private:
StackVector<uint16_t, kMaxVersionFields> mDriverVersion;
};
// Do comparison between two driver versions. Currently we only support the comparison between
// Intel D3D driver versions.
// Intel Windows driver versions.
// - Return -1 if build number of version1 is smaller
// - Return 1 if build number of version1 is bigger
// - Return 0 if version1 and version2 represent same driver version
int CompareD3DDriverVersion(PCIVendorID vendorId,
const D3DDriverVersion& version1,
const D3DDriverVersion& version2);
int CompareWindowsDriverVersion(PCIVendorID vendorId,
const DriverVersion& version1,
const DriverVersion& version2);
// Intel architectures
bool IsSkylake(PCIDeviceID deviceId);

View File

@ -169,6 +169,10 @@ uint32_t AdapterBase::GetDeviceId() const {
return mDeviceId;
}
const gpu_info::DriverVersion& AdapterBase::GetDriverVersion() const {
return mDriverVersion;
}
wgpu::BackendType AdapterBase::GetBackendType() const {
return mBackend;
}

View File

@ -19,6 +19,7 @@
#include "dawn/native/DawnNative.h"
#include "dawn/common/GPUInfo.h"
#include "dawn/common/RefCounted.h"
#include "dawn/common/ityp_span.h"
#include "dawn/native/Error.h"
@ -50,6 +51,7 @@ class AdapterBase : public RefCounted {
uint32_t GetVendorId() const;
uint32_t GetDeviceId() const;
const gpu_info::DriverVersion& GetDriverVersion() const;
wgpu::BackendType GetBackendType() const;
InstanceBase* GetInstance() const;
@ -72,6 +74,7 @@ class AdapterBase : public RefCounted {
uint32_t mDeviceId = 0xFFFFFFFF;
std::string mName;
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
gpu_info::DriverVersion mDriverVersion;
std::string mDriverDescription;
// Features set that CAN be supported by devices of this adapter. Some features in this set may

View File

@ -14,7 +14,7 @@
#include "dawn/native/d3d12/AdapterD3D12.h"
#include <sstream>
#include <string>
#include "dawn/common/Constants.h"
#include "dawn/common/WindowsUtils.h"
@ -57,10 +57,6 @@ ComPtr<ID3D12Device> Adapter::GetDevice() const {
return mD3d12Device;
}
const gpu_info::D3DDriverVersion& Adapter::GetDriverVersion() const {
return mDriverVersion;
}
MaybeError Adapter::InitializeImpl() {
// D3D12 cannot check for feature support without a device.
// Create the device to populate the adapter properties then reuse it when needed for actual
@ -94,14 +90,12 @@ MaybeError Adapter::InitializeImpl() {
if (mHardwareAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umdVersion) !=
DXGI_ERROR_UNSUPPORTED) {
uint64_t encodedVersion = umdVersion.QuadPart;
std::ostringstream o;
o << "D3D12 driver version ";
for (size_t i = 0; i < mDriverVersion.size(); ++i) {
mDriverVersion[i] = (encodedVersion >> (48 - 16 * i)) & 0xFFFF;
o << mDriverVersion[i] << ".";
}
mDriverDescription = o.str();
uint16_t mask = 0xFFFF;
mDriverVersion = {static_cast<uint16_t>((encodedVersion >> 48) & mask),
static_cast<uint16_t>((encodedVersion >> 32) & mask),
static_cast<uint16_t>((encodedVersion >> 16) & mask),
static_cast<uint16_t>(encodedVersion & mask)};
mDriverDescription = std::string("D3D12 driver version ") + mDriverVersion.ToString();
}
return {};

View File

@ -17,7 +17,6 @@
#include "dawn/native/Adapter.h"
#include "dawn/common/GPUInfo.h"
#include "dawn/native/d3d12/D3D12Info.h"
#include "dawn/native/d3d12/d3d12_platform.h"
@ -37,7 +36,6 @@ class Adapter : public AdapterBase {
IDXGIAdapter3* GetHardwareAdapter() const;
Backend* GetBackend() const;
ComPtr<ID3D12Device> GetDevice() const;
const gpu_info::D3DDriverVersion& GetDriverVersion() const;
private:
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
@ -60,7 +58,6 @@ class Adapter : public AdapterBase {
ComPtr<IDXGIAdapter3> mHardwareAdapter;
ComPtr<ID3D12Device> mD3d12Device;
gpu_info::D3DDriverVersion mDriverVersion;
Backend* mBackend;
D3D12DeviceInfo mDeviceInfo = {};

View File

@ -688,9 +688,9 @@ void Device::InitTogglesFromDriver() {
// Currently this workaround is only needed on Intel Gen9, Gen9.5 and Gen11 GPUs.
// See http://crbug.com/1161355 for more information.
if (gpu_info::IsIntelGen9(vendorId, deviceId) || gpu_info::IsIntelGen11(vendorId, deviceId)) {
constexpr gpu_info::D3DDriverVersion kFixedDriverVersion = {31, 0, 101, 2114};
if (gpu_info::CompareD3DDriverVersion(vendorId, ToBackend(GetAdapter())->GetDriverVersion(),
kFixedDriverVersion) < 0) {
const gpu_info::DriverVersion kFixedDriverVersion = {31, 0, 101, 2114};
if (gpu_info::CompareWindowsDriverVersion(vendorId, GetAdapter()->GetDriverVersion(),
kFixedDriverVersion) < 0) {
SetToggle(
Toggle::UseTempBufferInSmallFormatTextureToTextureCopyFromGreaterToLessMipLevel,
true);
@ -721,9 +721,9 @@ void Device::InitTogglesFromDriver() {
// This workaround is only needed on Intel Gen12LP with driver prior to 30.0.101.1692.
// See http://crbug.com/dawn/949 for more information.
if (gpu_info::IsIntelGen12LP(vendorId, deviceId)) {
constexpr gpu_info::D3DDriverVersion kFixedDriverVersion = {30, 0, 101, 1692};
if (gpu_info::CompareD3DDriverVersion(vendorId, ToBackend(GetAdapter())->GetDriverVersion(),
kFixedDriverVersion) == -1) {
const gpu_info::DriverVersion kFixedDriverVersion = {30, 0, 101, 1692};
if (gpu_info::CompareWindowsDriverVersion(vendorId, GetAdapter()->GetDriverVersion(),
kFixedDriverVersion) == -1) {
SetToggle(Toggle::D3D12AllocateExtraMemoryFor2DArrayTexture, true);
}
}

View File

@ -17,14 +17,45 @@
#include <algorithm>
#include <string>
#include "dawn/common/GPUInfo.h"
#include "dawn/native/Limits.h"
#include "dawn/native/vulkan/BackendVk.h"
#include "dawn/native/vulkan/DeviceVk.h"
#include "dawn/common/GPUInfo.h"
namespace dawn::native::vulkan {
namespace {
gpu_info::DriverVersion DecodeVulkanDriverVersion(uint32_t vendorID, uint32_t versionRaw) {
gpu_info::DriverVersion driverVersion;
switch (vendorID) {
case gpu_info::kVendorID_Nvidia:
driverVersion = {static_cast<uint16_t>((versionRaw >> 22) & 0x3FF),
static_cast<uint16_t>((versionRaw >> 14) & 0x0FF),
static_cast<uint16_t>((versionRaw >> 6) & 0x0FF),
static_cast<uint16_t>(versionRaw & 0x003F)};
break;
case gpu_info::kVendorID_Intel:
#if DAWN_PLATFORM_IS(WINDOWS)
// Windows Vulkan driver releases together with D3D driver, so they share the same
// version. But only CCC.DDDD is encoded in 32-bit driverVersion.
driverVersion = {static_cast<uint16_t>(versionRaw >> 14),
static_cast<uint16_t>(versionRaw & 0x3FFF)};
break;
#endif
default:
// Use Vulkan driver conversions for other vendors
driverVersion = {static_cast<uint16_t>(versionRaw >> 22),
static_cast<uint16_t>((versionRaw >> 12) & 0x3FF),
static_cast<uint16_t>(versionRaw & 0xFFF)};
break;
}
return driverVersion;
}
} // anonymous namespace
Adapter::Adapter(InstanceBase* instance,
VulkanInstance* vulkanInstance,
VkPhysicalDevice physicalDevice)
@ -59,14 +90,35 @@ bool Adapter::IsDepthStencilFormatSupported(VkFormat format) {
MaybeError Adapter::InitializeImpl() {
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
mDriverVersion = DecodeVulkanDriverVersion(mDeviceInfo.properties.vendorID,
mDeviceInfo.properties.driverVersion);
const std::string driverVersionStr = mDriverVersion.ToString();
#if DAWN_PLATFORM_IS(WINDOWS)
// Disable Vulkan adapter on Windows Intel driver < 30.0.101.2111 due to flaky
// issues.
const gpu_info::DriverVersion kDriverVersion({30, 0, 101, 2111});
if (gpu_info::IsIntel(mDeviceInfo.properties.vendorID) &&
gpu_info::CompareWindowsDriverVersion(mDeviceInfo.properties.vendorID, mDriverVersion,
kDriverVersion) == -1) {
return DAWN_FORMAT_INTERNAL_ERROR(
"Disable Intel Vulkan adapter on Windows driver version %s. See "
"https://crbug.com/1338622.",
driverVersionStr);
}
#endif
if (mDeviceInfo.HasExt(DeviceExt::DriverProperties)) {
mDriverDescription = mDeviceInfo.driverProperties.driverName;
if (mDeviceInfo.driverProperties.driverInfo[0] != '\0') {
mDriverDescription += std::string(": ") + mDeviceInfo.driverProperties.driverInfo;
}
// There may be no driver version in driverInfo.
if (mDriverDescription.find(driverVersionStr) == std::string::npos) {
mDriverDescription += std::string(" ") + driverVersionStr;
}
} else {
mDriverDescription =
"Vulkan driver version: " + std::to_string(mDeviceInfo.properties.driverVersion);
mDriverDescription = std::string("Vulkan driver version ") + driverVersionStr;
}
mDeviceId = mDeviceInfo.properties.deviceID;

View File

@ -387,16 +387,6 @@ void DawnTestEnvironment::SelectPreferredAdapterProperties(const dawn::native::I
(properties.backendType == wgpu::BackendType::Null);
}
#if DAWN_PLATFORM_IS(WINDOWS)
if (selected && !mRunSuppressedTests &&
properties.backendType == wgpu::BackendType::Vulkan &&
gpu_info::IsIntel(properties.vendorID)) {
dawn::WarningLog()
<< "Deselecting Windows Intel Vulkan adapter. See https://crbug.com/1338622.";
selected &= false;
}
#endif
// In Windows Remote Desktop sessions we may be able to discover multiple adapters that
// have the same name and backend type. We will just choose one adapter from them in our
// tests.

View File

@ -18,14 +18,26 @@
namespace {
const PCIVendorID vendorID = 0x8086;
const gpu_info::D3DDriverVersion version1 = {20, 19, 15, 5107};
const gpu_info::D3DDriverVersion version2 = {21, 20, 16, 5077};
const gpu_info::D3DDriverVersion version3 = {27, 20, 100, 9946};
const gpu_info::D3DDriverVersion version4 = {27, 20, 101, 2003};
// Intel D3D12
const gpu_info::DriverVersion version1 = {20, 19, 15, 5107};
const gpu_info::DriverVersion version2 = {21, 20, 16, 5077};
const gpu_info::DriverVersion version3 = {27, 20, 100, 9946};
const gpu_info::DriverVersion version4 = {27, 20, 101, 2003};
// Intel Vulkan
const gpu_info::DriverVersion version5 = {100, 9466};
const gpu_info::DriverVersion version6 = {101, 3222};
const gpu_info::DriverVersion version7 = {101, 3790};
} // anonymous namespace
TEST(GPUInfo, CompareD3DDriverVersion) {
EXPECT_EQ(gpu_info::CompareD3DDriverVersion(vendorID, version1, version2), -1);
EXPECT_EQ(gpu_info::CompareD3DDriverVersion(vendorID, version2, version3), -1);
EXPECT_EQ(gpu_info::CompareD3DDriverVersion(vendorID, version3, version4), -1);
TEST(GPUInfo, CompareWindowsDriverVersion) {
EXPECT_EQ(gpu_info::CompareWindowsDriverVersion(vendorID, version1, version2), -1);
EXPECT_EQ(gpu_info::CompareWindowsDriverVersion(vendorID, version2, version3), -1);
EXPECT_EQ(gpu_info::CompareWindowsDriverVersion(vendorID, version3, version4), -1);
EXPECT_EQ(gpu_info::CompareWindowsDriverVersion(vendorID, version5, version6), -1);
EXPECT_EQ(gpu_info::CompareWindowsDriverVersion(vendorID, version6, version7), -1);
// Windows Vulkan driver releases together with D3D12 driver, so they share the same version.
// Expect Intel D3D12 driver and Vulkan driver to be comparable.
EXPECT_EQ(gpu_info::CompareWindowsDriverVersion(vendorID, version3, version6), -1);
EXPECT_EQ(gpu_info::CompareWindowsDriverVersion(vendorID, version4, version7), -1);
}