Avi Drissman | 05dfbc82 | 2022-09-13 21:25:34 | [diff] [blame] | 1 | // Copyright 2022 The Chromium Authors |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "gpu/command_buffer/service/dawn_instance.h" |
| 6 | |
Loko Kung | f9f7637 | 2023-05-09 23:21:56 | [diff] [blame] | 7 | #include <dawn/webgpu_cpp.h> |
| 8 | |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 9 | #include "base/base_paths.h" |
| 10 | #include "base/files/file_path.h" |
| 11 | #include "base/path_service.h" |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 12 | #include "base/strings/string_split.h" |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 13 | #include "build/buildflag.h" |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 14 | #include "gpu/config/gpu_finch_features.h" |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 15 | #include "gpu/config/gpu_preferences.h" |
| 16 | |
| 17 | #if BUILDFLAG(IS_MAC) |
Avi Drissman | d4f0708 | 2023-05-12 18:05:44 | [diff] [blame] | 18 | #include "base/apple/bundle_locations.h" |
Avi Drissman | eac566b0 | 2023-08-18 02:56:21 | [diff] [blame] | 19 | #include "base/apple/foundation_util.h" |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 20 | #endif |
| 21 | |
| 22 | namespace gpu::webgpu { |
| 23 | |
| 24 | // static |
| 25 | std::unique_ptr<DawnInstance> DawnInstance::Create( |
| 26 | dawn::platform::Platform* platform, |
Corentin Wallez | 7d6a4f1 | 2023-12-05 19:44:16 | [diff] [blame] | 27 | const GpuPreferences& gpu_preferences, |
Peng Huang | 55a881da | 2024-02-22 10:57:05 | [diff] [blame] | 28 | SafetyLevel safety, |
Lokbondo Kung | a1226d8 | 2025-01-15 02:13:59 | [diff] [blame] | 29 | dawn::native::DawnInstanceDescriptor* dawn_instance_descriptor) { |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 30 | // Populate the WGSL blocklist based on the Finch feature. |
| 31 | std::vector<std::string> wgsl_unsafe_features_owned; |
| 32 | std::vector<const char*> wgsl_unsafe_features; |
| 33 | |
| 34 | if (safety != SafetyLevel::kUnsafe) { |
| 35 | wgsl_unsafe_features_owned = |
| 36 | base::SplitString(features::kWGSLUnsafeFeatures.Get(), ",", |
| 37 | base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 38 | wgsl_unsafe_features.reserve(wgsl_unsafe_features_owned.size()); |
| 39 | for (const auto& f : wgsl_unsafe_features_owned) { |
| 40 | wgsl_unsafe_features.push_back(f.c_str()); |
| 41 | } |
| 42 | } |
| 43 | wgpu::DawnWGSLBlocklist wgsl_blocklist; |
| 44 | wgsl_blocklist.nextInChain = nullptr; |
| 45 | wgsl_blocklist.blocklistedFeatureCount = wgsl_unsafe_features.size(); |
| 46 | wgsl_blocklist.blocklistedFeatures = wgsl_unsafe_features.data(); |
| 47 | |
| 48 | // Populate the instance toggles becaused on command line parameters and |
| 49 | // safety levels. Toggles which are not instance toggles will be ignored by |
| 50 | // the instance. |
| 51 | std::vector<const char*> require_instance_enabled_toggles; |
| 52 | std::vector<const char*> require_instance_disabled_toggles; |
| 53 | |
| 54 | if (safety == SafetyLevel::kSafeExperimental) { |
| 55 | require_instance_enabled_toggles.push_back( |
| 56 | "expose_wgsl_experimental_features"); |
| 57 | } else if (safety == SafetyLevel::kUnsafe) { |
| 58 | require_instance_enabled_toggles.push_back("allow_unsafe_apis"); |
| 59 | } |
| 60 | |
Brian Sheedy | 2084c13 | 2024-01-17 23:16:12 | [diff] [blame] | 61 | for (const std::string& toggles : |
| 62 | gpu_preferences.enabled_dawn_features_list) { |
| 63 | require_instance_enabled_toggles.push_back(toggles.c_str()); |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 64 | } |
Brian Sheedy | 2084c13 | 2024-01-17 23:16:12 | [diff] [blame] | 65 | for (const std::string& toggles : |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 66 | gpu_preferences.disabled_dawn_features_list) { |
Brian Sheedy | 2084c13 | 2024-01-17 23:16:12 | [diff] [blame] | 67 | require_instance_disabled_toggles.push_back(toggles.c_str()); |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | wgpu::DawnTogglesDescriptor dawn_toggle_desc; |
| 71 | dawn_toggle_desc.nextInChain = &wgsl_blocklist; |
| 72 | dawn_toggle_desc.enabledToggleCount = require_instance_enabled_toggles.size(); |
| 73 | dawn_toggle_desc.enabledToggles = require_instance_enabled_toggles.data(); |
| 74 | dawn_toggle_desc.disabledToggleCount = |
| 75 | require_instance_disabled_toggles.size(); |
| 76 | dawn_toggle_desc.disabledToggles = require_instance_disabled_toggles.data(); |
| 77 | |
| 78 | // Use DawnInstanceDescriptor to pass in the platform and additional search |
| 79 | // paths |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 80 | std::string dawn_search_path; |
| 81 | base::FilePath module_path; |
| 82 | #if BUILDFLAG(IS_MAC) |
Avi Drissman | eac566b0 | 2023-08-18 02:56:21 | [diff] [blame] | 83 | if (base::apple::AmIBundled()) { |
Avi Drissman | d4f0708 | 2023-05-12 18:05:44 | [diff] [blame] | 84 | dawn_search_path = base::apple::FrameworkBundlePath() |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 85 | .Append("Libraries") |
| 86 | .AsEndingWithSeparator() |
| 87 | .MaybeAsASCII(); |
| 88 | } |
| 89 | if (dawn_search_path.empty()) |
| 90 | #endif |
| 91 | { |
Ian Vollick | 12a7241 | 2023-06-20 18:36:17 | [diff] [blame] | 92 | #if BUILDFLAG(IS_IOS) |
| 93 | if (base::PathService::Get(base::DIR_ASSETS, &module_path)) { |
| 94 | #else |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 95 | if (base::PathService::Get(base::DIR_MODULE, &module_path)) { |
Ian Vollick | 12a7241 | 2023-06-20 18:36:17 | [diff] [blame] | 96 | #endif |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 97 | dawn_search_path = module_path.AsEndingWithSeparator().MaybeAsASCII(); |
| 98 | } |
| 99 | } |
| 100 | const char* dawn_search_path_c_str = dawn_search_path.c_str(); |
| 101 | |
Jiawei Shao | 920a179 | 2023-09-01 00:59:32 | [diff] [blame] | 102 | dawn::native::DawnInstanceDescriptor dawn_instance_desc; |
Lokbondo Kung | a1226d8 | 2025-01-15 02:13:59 | [diff] [blame] | 103 | if (dawn_instance_descriptor) { |
| 104 | dawn_instance_desc = *dawn_instance_descriptor; |
| 105 | } |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 106 | dawn_instance_desc.nextInChain = &dawn_toggle_desc; |
Loko Kung | f9f7637 | 2023-05-09 23:21:56 | [diff] [blame] | 107 | dawn_instance_desc.additionalRuntimeSearchPathsCount = |
| 108 | dawn_search_path.empty() ? 0u : 1u; |
| 109 | dawn_instance_desc.additionalRuntimeSearchPaths = &dawn_search_path_c_str; |
Loko Kung | 4083b35 | 2023-05-17 06:26:04 | [diff] [blame] | 110 | dawn_instance_desc.platform = platform; |
Loko Kung | f9f7637 | 2023-05-09 23:21:56 | [diff] [blame] | 111 | |
Corentin Wallez | a70e8468 | 2023-12-18 19:23:40 | [diff] [blame] | 112 | // Create the instance with all the previous descriptors chained. |
Loko Kung | f9f7637 | 2023-05-09 23:21:56 | [diff] [blame] | 113 | wgpu::InstanceDescriptor instance_desc; |
| 114 | instance_desc.nextInChain = &dawn_instance_desc; |
FranΓ§ois Beaufort | 4ffd2dc | 2025-07-10 08:53:12 | [diff] [blame] | 115 | static constexpr auto kInstanceFeatures = std::array{ |
| 116 | wgpu::InstanceFeatureName::MultipleDevicesPerAdapter, |
| 117 | wgpu::InstanceFeatureName::TimedWaitAny, |
| 118 | }; |
| 119 | instance_desc.requiredFeatureCount = kInstanceFeatures.size(); |
| 120 | instance_desc.requiredFeatures = kInstanceFeatures.data(); |
Brian Sheedy | 2084c13 | 2024-01-17 23:16:12 | [diff] [blame] | 121 | |
| 122 | auto instance = std::make_unique<DawnInstance>( |
Loko Kung | f9f7637 | 2023-05-09 23:21:56 | [diff] [blame] | 123 | reinterpret_cast<const WGPUInstanceDescriptor*>(&instance_desc)); |
Brian Sheedy | 2084c13 | 2024-01-17 23:16:12 | [diff] [blame] | 124 | |
| 125 | switch (gpu_preferences.enable_dawn_backend_validation) { |
| 126 | case DawnBackendValidationLevel::kDisabled: |
| 127 | break; |
| 128 | case DawnBackendValidationLevel::kPartial: |
| 129 | instance->SetBackendValidationLevel( |
| 130 | dawn::native::BackendValidationLevel::Partial); |
| 131 | break; |
| 132 | case DawnBackendValidationLevel::kFull: |
| 133 | instance->SetBackendValidationLevel( |
| 134 | dawn::native::BackendValidationLevel::Full); |
| 135 | break; |
| 136 | } |
| 137 | |
| 138 | return instance; |
Austin Eng | 0fa5bb6 | 2022-05-11 20:33:05 | [diff] [blame] | 139 | } |
| 140 | |
Loko Kung | f9f7637 | 2023-05-09 23:21:56 | [diff] [blame] | 141 | } // namespace gpu::webgpu |