blob: 7f9d2f51cf1b4fd95b6bbe7924646efff00a4c8e [file] [log] [blame]
Avi Drissman05dfbc822022-09-13 21:25:341// Copyright 2016 The Chromium Authors
geofflangdf7fff2d42016-11-11 00:34:032// 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/service_utils.h"
6
Jonathan Backer7bc44592018-04-25 19:59:507#include <string>
8
geofflang3ab039d2017-02-22 15:33:589#include "base/command_line.h"
Corentin Walleze660b152020-07-15 16:07:5410#include "base/logging.h"
Jonathan Backer7bc44592018-04-25 19:59:5011#include "base/strings/string_number_conversions.h"
Jiawei Shao04b8bcd2020-11-14 01:29:4712#include "base/strings/string_split.h"
Sean Gilhuly3e84fc82020-01-22 22:06:4513#include "build/build_config.h"
Jonathan Backerf48f9202021-01-14 18:39:4614#include "build/chromeos_buildflags.h"
geofflangdf7fff2d42016-11-11 00:34:0315#include "gpu/command_buffer/common/gles2_cmd_utils.h"
Geoff Lang619081b2017-08-31 19:23:3116#include "gpu/command_buffer/service/context_group.h"
Geoff Langd72f1e92017-10-12 23:31:3817#include "gpu/command_buffer/service/gpu_switches.h"
Peng Huangdc3c68f42019-09-15 02:27:2218#include "gpu/config/gpu_finch_features.h"
Sean Gilhulye5342322019-11-08 16:40:5319#include "skia/buildflags.h"
geofflang3ab039d2017-02-22 15:33:5820#include "ui/gl/gl_switches.h"
Jonah Ryan-Davis570ab8b92019-07-08 20:03:3321#include "ui/gl/gl_utils.h"
geofflangdf7fff2d42016-11-11 00:34:0322
Geoff Lang619081b2017-08-31 19:23:3123#if defined(USE_EGL)
24#include "ui/gl/gl_surface_egl.h"
25#endif // defined(USE_EGL)
26
geofflangdf7fff2d42016-11-11 00:34:0327namespace gpu {
28namespace gles2 {
29
Jonathan Backer7bc44592018-04-25 19:59:5030namespace {
31
32bool GetUintFromSwitch(const base::CommandLine* command_line,
33 const base::StringPiece& switch_string,
34 uint32_t* value) {
Antonio Maiorano32b31002023-08-30 14:07:1735 if (!command_line->HasSwitch(switch_string)) {
Jonathan Backer7bc44592018-04-25 19:59:5036 return false;
Antonio Maiorano32b31002023-08-30 14:07:1737 }
Jonathan Backer7bc44592018-04-25 19:59:5038 std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
39 return base::StringToUint(switch_value, value);
40}
41
42} // namespace
43
geofflangdf7fff2d42016-11-11 00:34:0344gl::GLContextAttribs GenerateGLContextAttribs(
Antoine Labourfeab2392017-12-21 20:28:3945 const ContextCreationAttribs& attribs_helper,
Geoff Lang619081b2017-08-31 19:23:3146 const ContextGroup* context_group) {
Khushalb2c140b2018-07-09 20:21:1647 return GenerateGLContextAttribs(attribs_helper,
48 context_group->use_passthrough_cmd_decoder());
49}
50
51gl::GLContextAttribs GenerateGLContextAttribs(
52 const ContextCreationAttribs& attribs_helper,
53 bool use_passthrough_cmd_decoder) {
geofflangdf7fff2d42016-11-11 00:34:0354 gl::GLContextAttribs attribs;
55 attribs.gpu_preference = attribs_helper.gpu_preference;
Khushalb2c140b2018-07-09 20:21:1656 if (use_passthrough_cmd_decoder) {
geofflangdf7fff2d42016-11-11 00:34:0357 attribs.bind_generates_resource = attribs_helper.bind_generates_resource;
58 attribs.webgl_compatibility_context =
59 IsWebGLContextType(attribs_helper.context_type);
geofflang3ab039d2017-02-22 15:33:5860
Jonathan Ross6b1ca232020-07-31 16:43:3661 // Always use the global texture and semaphore share group for the
62 // passthrough command decoder
geofflang3ab039d2017-02-22 15:33:5863 attribs.global_texture_share_group = true;
Jonathan Ross6b1ca232020-07-31 16:43:3664 attribs.global_semaphore_share_group = true;
geofflang3ab039d2017-02-22 15:33:5865
Geoff Lang7f82ef42017-09-23 17:56:0266 attribs.robust_resource_initialization = true;
Jiajia Qin69aeeb22017-11-09 05:16:1867 attribs.robust_buffer_access = true;
Geoff Lang7f82ef42017-09-23 17:56:0268
geofflang3ab039d2017-02-22 15:33:5869 // Request a specific context version instead of always 3.0
Geoff Langd0c755c2021-01-18 21:58:1670 if (IsWebGL2OrES3ContextType(attribs_helper.context_type)) {
geofflang3ab039d2017-02-22 15:33:5871 attribs.client_major_es_version = 3;
72 attribs.client_minor_es_version = 0;
73 } else {
74 DCHECK(IsWebGL1OrES2ContextType(attribs_helper.context_type));
75 attribs.client_major_es_version = 2;
76 attribs.client_minor_es_version = 0;
77 }
78 } else {
79 attribs.client_major_es_version = 3;
80 attribs.client_minor_es_version = 0;
geofflangdf7fff2d42016-11-11 00:34:0381 }
geofflang3ab039d2017-02-22 15:33:5882
Will Harrisc5313ac2023-03-01 23:42:0383 if (gl::GetGlWorkarounds().disable_es3gl_context) {
geofflang3ab039d2017-02-22 15:33:5884 // Forcefully disable ES3 contexts
85 attribs.client_major_es_version = 2;
86 attribs.client_minor_es_version = 0;
87 }
88
Geoff Langd0c755c2021-01-18 21:58:1689 if (IsES31ForTestingContextType(attribs_helper.context_type)) {
90 // Forcefully disable ES 3.1 contexts. Tests create contexts by initializing
91 // the attributes directly.
92 attribs.client_major_es_version = 2;
93 attribs.client_minor_es_version = 0;
94 }
95
geofflangdf7fff2d42016-11-11 00:34:0396 return attribs;
97}
98
Geoff Langd72f1e92017-10-12 23:31:3899bool UsePassthroughCommandDecoder(const base::CommandLine* command_line) {
Jonah Ryan-Davis570ab8b92019-07-08 20:03:33100 return gl::UsePassthroughCommandDecoder(command_line);
Geoff Langd72f1e92017-10-12 23:31:38101}
102
Geoff Lang619081b2017-08-31 19:23:31103bool PassthroughCommandDecoderSupported() {
Jonah Ryan-Davis77b562dc2020-07-17 19:11:23104 return gl::PassthroughCommandDecoderSupported();
Jonathan Backer7bc44592018-04-25 19:59:50105}
106
107GpuPreferences ParseGpuPreferences(const base::CommandLine* command_line) {
108 GpuPreferences gpu_preferences;
109 gpu_preferences.compile_shader_always_succeeds =
110 command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds);
111 gpu_preferences.disable_gl_error_limit =
112 command_line->HasSwitch(switches::kDisableGLErrorLimit);
113 gpu_preferences.disable_glsl_translator =
114 command_line->HasSwitch(switches::kDisableGLSLTranslator);
115 gpu_preferences.disable_shader_name_hashing =
116 command_line->HasSwitch(switches::kDisableShaderNameHashing);
117 gpu_preferences.enable_gpu_command_logging =
118 command_line->HasSwitch(switches::kEnableGPUCommandLogging);
119 gpu_preferences.enable_gpu_debugging =
120 command_line->HasSwitch(switches::kEnableGPUDebugging);
121 gpu_preferences.enable_gpu_service_logging_gpu =
122 command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU);
123 gpu_preferences.enable_gpu_driver_debug_logging =
124 command_line->HasSwitch(switches::kEnableGPUDriverDebugLogging);
125 gpu_preferences.disable_gpu_program_cache =
126 command_line->HasSwitch(switches::kDisableGpuProgramCache);
127 gpu_preferences.enforce_gl_minimums =
128 command_line->HasSwitch(switches::kEnforceGLMinimums);
129 if (GetUintFromSwitch(command_line, switches::kForceGpuMemAvailableMb,
Wez4f8b5432019-12-31 06:40:11130 &gpu_preferences.force_gpu_mem_available_bytes)) {
131 gpu_preferences.force_gpu_mem_available_bytes *= 1024 * 1024;
132 }
133 if (GetUintFromSwitch(
134 command_line, switches::kForceGpuMemDiscardableLimitMb,
135 &gpu_preferences.force_gpu_mem_discardable_limit_bytes)) {
136 gpu_preferences.force_gpu_mem_discardable_limit_bytes *= 1024 * 1024;
Jonathan Backer7bc44592018-04-25 19:59:50137 }
Sergey Ulanov689c31f2020-01-24 23:21:16138 GetUintFromSwitch(command_line, switches::kForceMaxTextureSize,
139 &gpu_preferences.force_max_texture_size);
Jonathan Backer7bc44592018-04-25 19:59:50140 if (GetUintFromSwitch(command_line, switches::kGpuProgramCacheSizeKb,
141 &gpu_preferences.gpu_program_cache_size)) {
142 gpu_preferences.gpu_program_cache_size *= 1024;
143 }
144 gpu_preferences.disable_gpu_shader_disk_cache =
145 command_line->HasSwitch(switches::kDisableGpuShaderDiskCache);
146 gpu_preferences.enable_threaded_texture_mailboxes =
147 command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
148 gpu_preferences.gl_shader_interm_output =
149 command_line->HasSwitch(switches::kGLShaderIntermOutput);
Jonathan Backer7bc44592018-04-25 19:59:50150 gpu_preferences.enable_gpu_service_logging =
151 command_line->HasSwitch(switches::kEnableGPUServiceLogging);
152 gpu_preferences.enable_gpu_service_tracing =
153 command_line->HasSwitch(switches::kEnableGPUServiceTracing);
154 gpu_preferences.use_passthrough_cmd_decoder =
155 gpu::gles2::UsePassthroughCommandDecoder(command_line);
Corentin Wallez5cbffcc2020-07-08 10:23:57156 gpu_preferences.ignore_gpu_blocklist =
Corentin Walleze660b152020-07-15 16:07:54157 command_line->HasSwitch(switches::kIgnoreGpuBlocklist);
Kai Ninomiya328e07a2018-08-23 01:08:16158 gpu_preferences.enable_webgpu =
shrekshaoc6539252021-04-29 19:21:56159 command_line->HasSwitch(switches::kEnableUnsafeWebGPU) ||
Corentin Walleza059a3a22021-07-30 09:44:54160 base::FeatureList::IsEnabled(features::kWebGPUService);
Austin Enga442d5832022-01-15 03:00:15161 gpu_preferences.enable_unsafe_webgpu =
Corentin Wallez721293f2021-06-03 22:42:00162 command_line->HasSwitch(switches::kEnableUnsafeWebGPU);
Austin Eng80eb7962022-02-07 20:35:37163 gpu_preferences.use_webgpu_adapter = ParseWebGPUAdapterName(command_line);
Shrek Shaod457e862023-03-22 23:06:05164 gpu_preferences.use_webgpu_power_preference =
165 ParseWebGPUPowerPreference(command_line);
Stephen White602bf502023-05-17 21:10:50166 gpu_preferences.force_webgpu_compat =
167 command_line->HasSwitch(switches::kForceWebGPUCompat);
Austin Engbac59e692021-05-13 16:46:54168 if (command_line->HasSwitch(switches::kEnableDawnBackendValidation)) {
169 auto value = command_line->GetSwitchValueASCII(
170 switches::kEnableDawnBackendValidation);
171 if (value.empty() || value == "full") {
172 gpu_preferences.enable_dawn_backend_validation =
173 DawnBackendValidationLevel::kFull;
174 } else if (value == "partial") {
175 gpu_preferences.enable_dawn_backend_validation =
176 DawnBackendValidationLevel::kPartial;
177 }
178 }
Jiawei Shao04b8bcd2020-11-14 01:29:47179 if (command_line->HasSwitch(switches::kEnableDawnFeatures)) {
180 gpu_preferences.enabled_dawn_features_list = base::SplitString(
181 command_line->GetSwitchValueASCII(switches::kEnableDawnFeatures), ",",
182 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
183 }
184 if (command_line->HasSwitch(switches::kDisableDawnFeatures)) {
185 gpu_preferences.disabled_dawn_features_list = base::SplitString(
186 command_line->GetSwitchValueASCII(switches::kDisableDawnFeatures), ",",
187 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
188 }
Antonio Maiorano32b31002023-08-30 14:07:17189#ifdef DAWN_USE_BUILT_DXC
190 // Drive "use_dxc" with Finch feature flag, unless user forces option via
191 // command line.
192 if (!base::Contains(gpu_preferences.enabled_dawn_features_list, "use_dxc") &&
193 !base::Contains(gpu_preferences.disabled_dawn_features_list, "use_dxc")) {
194 if (base::FeatureList::IsEnabled(features::kWebGPUUseDXC)) {
195 gpu_preferences.enabled_dawn_features_list.push_back("use_dxc");
196 } else {
197 gpu_preferences.disabled_dawn_features_list.push_back("use_dxc");
198 }
199 }
200#endif
Sunny Sachanandanifb74c17f2023-04-10 21:29:17201 gpu_preferences.gr_context_type = ParseGrContextType(command_line);
Peng Huang07ed18642020-06-09 00:58:17202 gpu_preferences.use_vulkan = ParseVulkanImplementationName(command_line);
Sergey Ulanovefa2af12022-06-28 23:17:47203
204#if BUILDFLAG(IS_FUCHSIA)
205 // Vulkan Surface is not used on Fuchsia.
206 gpu_preferences.disable_vulkan_surface = true;
207#else
Peng Huang556da902019-03-22 17:49:40208 gpu_preferences.disable_vulkan_surface =
209 command_line->HasSwitch(switches::kDisableVulkanSurface);
Sergey Ulanovefa2af12022-06-28 23:17:47210#endif
Vasiliy Telezhnikov533c5642019-12-03 15:10:16211
212 gpu_preferences.enable_gpu_blocked_time_metric =
213 command_line->HasSwitch(switches::kEnableGpuBlockedTime);
214
Jonathan Backer7bc44592018-04-25 19:59:50215 return gpu_preferences;
216}
Geoff Lang619081b2017-08-31 19:23:31217
Sunny Sachanandanifb74c17f2023-04-10 21:29:17218GrContextType ParseGrContextType(const base::CommandLine* command_line) {
Sunny Sachanandaniaba318bb2023-09-06 20:22:22219 if (features::IsSkiaGraphiteEnabled(command_line)) {
Sunny Sachanandanifb74c17f2023-04-10 21:29:17220 [[maybe_unused]] auto value =
221 command_line->GetSwitchValueASCII(switches::kSkiaGraphiteBackend);
Sean Gilhuly3e84fc82020-01-22 22:06:45222#if BUILDFLAG(SKIA_USE_DAWN)
Sunny Sachanandaniddc82cc2023-08-30 16:16:21223 if (value.empty() ||
224 base::StartsWith(value, switches::kSkiaGraphiteBackendDawn)) {
Sunny Sachanandanifb74c17f2023-04-10 21:29:17225 return GrContextType::kGraphiteDawn;
226 }
227#endif // BUILDFLAG(SKIA_USE_DAWN)
228#if BUILDFLAG(SKIA_USE_METAL)
Ian Vollicke4832bd2023-07-24 21:29:47229 if (
230#if BUILDFLAG(IS_IOS)
231 value.empty() ||
232#endif // BUILDFLAG(IS_IOS)
233 value == switches::kSkiaGraphiteBackendMetal) {
Sunny Sachanandanifb74c17f2023-04-10 21:29:17234 return GrContextType::kGraphiteMetal;
235 }
236#endif // BUILDFLAG(SKIA_USE_METAL)
Sunny Sachanandani0a26ac5b2023-05-01 22:05:42237 LOG(ERROR) << "Skia Graphite backend = \"" << value
238 << "\" not found - falling back to Ganesh!";
Sunny Sachanandanifb74c17f2023-04-10 21:29:17239 }
Sunny Sachanandanifb74c17f2023-04-10 21:29:17240 if (features::IsUsingVulkan()) {
Peng Huangdbde9c72022-02-18 21:48:44241 return GrContextType::kVulkan;
Sunny Sachanandanifb74c17f2023-04-10 21:29:17242 }
Peng Huangdbde9c72022-02-18 21:48:44243 return GrContextType::kGL;
Sean Gilhuly3e84fc82020-01-22 22:06:45244}
245
246VulkanImplementationName ParseVulkanImplementationName(
Peng Huang07ed18642020-06-09 00:58:17247 const base::CommandLine* command_line) {
Xiaohan Wangfa22d3e2022-01-15 02:02:43248#if BUILDFLAG(IS_ANDROID)
Bo Liu693cea52020-11-05 21:52:44249 if (command_line->HasSwitch(switches::kWebViewDrawFunctorUsesVulkan) &&
250 base::FeatureList::IsEnabled(features::kWebViewVulkan)) {
251 return VulkanImplementationName::kForcedNative;
252 }
253#endif
254
Sean Gilhuly3e84fc82020-01-22 22:06:45255 if (command_line->HasSwitch(switches::kUseVulkan)) {
256 auto value = command_line->GetSwitchValueASCII(switches::kUseVulkan);
257 if (value.empty() || value == switches::kVulkanImplementationNameNative) {
258 return VulkanImplementationName::kForcedNative;
259 } else if (value == switches::kVulkanImplementationNameSwiftshader) {
260 return VulkanImplementationName::kSwiftshader;
261 }
262 }
Peng Huang07ed18642020-06-09 00:58:17263
Jonathan Backerf48f9202021-01-14 18:39:46264 if (features::IsUsingVulkan()) {
265 // If the vulkan feature is enabled from command line, we will force to use
266 // vulkan even if it is blocklisted.
267 return base::FeatureList::GetInstance()->IsFeatureOverriddenFromCommandLine(
268 features::kVulkan.name,
269 base::FeatureList::OVERRIDE_ENABLE_FEATURE)
270 ? VulkanImplementationName::kForcedNative
271 : VulkanImplementationName::kNative;
272 }
Peng Huang07ed18642020-06-09 00:58:17273
Jonathan Backerf48f9202021-01-14 18:39:46274 // GrContext is not going to use Vulkan.
275 return VulkanImplementationName::kNone;
Sean Gilhuly3e84fc82020-01-22 22:06:45276}
277
Austin Eng80eb7962022-02-07 20:35:37278WebGPUAdapterName ParseWebGPUAdapterName(
279 const base::CommandLine* command_line) {
280 if (command_line->HasSwitch(switches::kUseWebGPUAdapter)) {
281 auto value = command_line->GetSwitchValueASCII(switches::kUseWebGPUAdapter);
Peng Huang8db6546e2023-05-15 19:13:19282
283 static const struct {
284 const char* name;
285 WebGPUAdapterName value;
286 } kAdapterNames[] = {
287 {"", WebGPUAdapterName::kDefault},
288 {"default", WebGPUAdapterName::kDefault},
289 {"d3d11", WebGPUAdapterName::kD3D11},
290 {"opengles", WebGPUAdapterName::kOpenGLES},
291 {"swiftshader", WebGPUAdapterName::kSwiftShader},
292 };
293
294 for (const auto& adapter_name : kAdapterNames) {
295 if (value == adapter_name.name) {
296 return adapter_name.value;
297 }
Austin Eng80eb7962022-02-07 20:35:37298 }
Peng Huang8db6546e2023-05-15 19:13:19299
300 DLOG(ERROR) << "Invalid switch " << switches::kUseWebGPUAdapter << "="
301 << value << ".";
Austin Eng80eb7962022-02-07 20:35:37302 }
303 return WebGPUAdapterName::kDefault;
304}
305
Shrek Shaod457e862023-03-22 23:06:05306WebGPUPowerPreference ParseWebGPUPowerPreference(
307 const base::CommandLine* command_line) {
308 if (command_line->HasSwitch(switches::kUseWebGPUPowerPreference)) {
309 auto value =
310 command_line->GetSwitchValueASCII(switches::kUseWebGPUPowerPreference);
311 if (value.empty()) {
Austin Eng34ba1d92023-05-04 01:39:47312 return WebGPUPowerPreference::kNone;
313 } else if (value == "none") {
314 return WebGPUPowerPreference::kNone;
Shrek Shaod457e862023-03-22 23:06:05315 } else if (value == "default-low-power") {
316 return WebGPUPowerPreference::kDefaultLowPower;
317 } else if (value == "default-high-performance") {
318 return WebGPUPowerPreference::kDefaultHighPerformance;
319 } else if (value == "force-low-power") {
320 return WebGPUPowerPreference::kForceLowPower;
321 } else if (value == "force-high-performance") {
322 return WebGPUPowerPreference::kForceHighPerformance;
323 } else {
324 DLOG(ERROR) << "Invalid switch " << switches::kUseWebGPUPowerPreference
325 << "=" << value << ".";
326 }
327 }
Austin Eng34ba1d92023-05-04 01:39:47328 return WebGPUPowerPreference::kNone;
Shrek Shaod457e862023-03-22 23:06:05329}
330
Justin Novosad5730d362023-07-19 22:05:47331bool MSAAIsSlow(const GpuDriverBugWorkarounds& workarounds) {
Justin Novosad5730d362023-07-19 22:05:47332 // Only query the kEnableMSAAOnNewIntelGPUs feature flag if the host device
333 // is affected by the experiment (i.e. is a new Intel GPU).
334 // This is to avoid activating the experiment on hosts that are irrelevant
335 // to the study in order to boost statistical power.
336 bool affected_by_experiment =
337 workarounds.msaa_is_slow && !workarounds.msaa_is_slow_2;
338
339 return affected_by_experiment ? !base::FeatureList::IsEnabled(
340 features::kEnableMSAAOnNewIntelGPUs)
341 : workarounds.msaa_is_slow;
342}
343
geofflangdf7fff2d42016-11-11 00:34:03344} // namespace gles2
345} // namespace gpu