| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "gpu/config/webgpu_blocklist.h" |
| |
| #include "base/metrics/field_trial_params.h" |
| #include "base/strings/pattern.h" |
| #include "base/strings/string_split.h" |
| #include "gpu/config/gpu_finch_features.h" |
| #include "ui/gl/buildflags.h" |
| |
| #if BUILDFLAG(IS_MAC) |
| #include "base/mac/mac_util.h" |
| #endif |
| |
| #if BUILDFLAG(USE_DAWN) |
| #include "third_party/dawn/include/dawn/webgpu.h" // nogncheck |
| #endif |
| |
| namespace gpu { |
| |
| namespace { |
| |
| // List of patterns, delimited by |. Each pattern is of the form: |
| // `vendorId(:deviceIdOrArchitecture(:driverDescription)?)?` |
| // Vendor and device ids should be in hexadecimal representation, without a |
| // leading `0x`. |
| // The FeatureParam may be overriden via Finch config, or via the command line |
| // with |
| // --force-fieldtrial-params=WebGPUOriginTrial.Enabled:AdapterBlockList/params |
| // where `params` is URL-encoded. |
| const base::FeatureParam<std::string> kAdapterBlockList{ |
| &features::kWebGPUService, "AdapterBlockList", ""}; |
| |
| } // namespace |
| |
| bool IsWebGPUAdapterBlocklisted(const WGPUAdapterProperties& properties) { |
| return IsWebGPUAdapterBlocklisted(properties, kAdapterBlockList.Get()); |
| } |
| |
| bool IsWebGPUAdapterBlocklisted(const WGPUAdapterProperties& properties, |
| const std::string& blocklist) { |
| #if BUILDFLAG(USE_DAWN) |
| #if BUILDFLAG(IS_MAC) |
| constexpr uint32_t kAMDVendorID = 0x1002; |
| // Blocklisted due to crbug.com/tint/1094 |
| if (!base::mac::IsAtLeastOS13() && properties.vendorID == kAMDVendorID && |
| properties.backendType == WGPUBackendType_Metal) { |
| return true; |
| } |
| #endif |
| |
| // TODO(crbug.com/1266550): SwiftShader and CPU adapters are blocked until |
| // fully tested. |
| if (properties.adapterType == WGPUAdapterType_CPU) { |
| return true; |
| } |
| |
| auto U32ToHexString = [](uint32_t value) { |
| std::ostringstream o; |
| o << std::hex << value; |
| return o.str(); |
| }; |
| |
| auto blocked_patterns = base::SplitString( |
| blocklist, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| |
| for (const auto& blocked_pattern : blocked_patterns) { |
| std::vector<std::string> segments = base::SplitString( |
| blocked_pattern, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| |
| // Check if the vendorID matches the first segment. |
| if (segments.size() >= 1) { |
| if (!base::MatchPattern(U32ToHexString(properties.vendorID), |
| segments[0])) { |
| continue; |
| } |
| } |
| |
| // Check if the deviceID or architecture matches the second segment. |
| if (segments.size() >= 2) { |
| if (!base::MatchPattern(U32ToHexString(properties.deviceID), |
| segments[1]) && |
| !base::MatchPattern(properties.architecture, segments[1])) { |
| continue; |
| } |
| } |
| |
| // Check if the driver description matches the third segment. |
| if (segments.size() >= 3) { |
| if (!base::MatchPattern(properties.driverDescription, segments[2])) { |
| continue; |
| } |
| } |
| |
| // Adapter is blocked. |
| return true; |
| } |
| return false; |
| #else |
| return true; |
| #endif |
| } |
| |
| } // namespace gpu |