diff options
author | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2024-05-03 18:10:16 +0000 |
---|---|---|
committer | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2024-05-03 18:10:16 +0000 |
commit | c858c20c5936e15def2fef97e1e372a16fb7ac1a (patch) | |
tree | 05277d8a62574b55fe256aa1f2cb376a0dfeec79 | |
parent | 31f475da9b7d2a2becddeb0898b35699835cbdaa (diff) | |
parent | 9aa6d3daf6a34207ac655b1c1f099951c53bcb90 (diff) | |
download | angle-main.tar.gz |
https://chromium.googlesource.com/angle/angle.git/+log/44bdc2af94e0..9aa6d3daf6a3
Please enable autosubmit on changes if possible when approving them.
If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/angle-android-autoroll
Please CC angle-team@google.com,cnorthrop@google.com,rmistry@google.com on the revert to ensure that a human
is aware of the problem.
To file a bug in ANGLE: https://bugs.chromium.org/p/angleproject/issues/entry
To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622
Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Test: Presubmit checks will test this change.
Exempt-From-Owner-Approval: The autoroll bot does not require owner approval.
Bug: b/336386662
Bug: b/336844257
Bug: b/338429767
Change-Id: I6b4f2d99251ea86fa328bb5984a9d39205fdec63
71 files changed, 1556 insertions, 544 deletions
diff --git a/Android.bp b/Android.bp index 1eee1b63c8..8bbd862182 100644 --- a/Android.bp +++ b/Android.bp @@ -58,7 +58,7 @@ cc_defaults { cflags: [ "-DANDROID", "-DANDROID_NDK_VERSION_ROLL=r26b_1", - "-DCR_CLANG_REVISION=\"llvmorg-19-init-8943-gd8503a38-3\"", + "-DCR_CLANG_REVISION=\"llvmorg-19-init-9433-g76ea5feb-1\"", "-DDYNAMIC_ANNOTATIONS_ENABLED=0", "-DHAVE_SYS_UIO_H", "-DNDEBUG", @@ -536,6 +536,7 @@ cc_defaults { "src/libANGLE/renderer/vulkan/vk_helpers.cpp", "src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp", "src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp", + "src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp", "src/libANGLE/renderer/vulkan/vk_renderer.cpp", "src/libANGLE/renderer/vulkan/vk_resource.cpp", "src/libANGLE/renderer/vulkan/vk_utils.cpp", @@ -2537,6 +2538,8 @@ cc_genrule { "src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp", "src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h", "src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp", + "src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp", + "src/libANGLE/renderer/vulkan/vk_ref_counted_event.h", "src/libANGLE/renderer/vulkan/vk_renderer.cpp", "src/libANGLE/renderer/vulkan/vk_renderer.h", "src/libANGLE/renderer/vulkan/vk_resource.cpp", @@ -3275,7 +3278,7 @@ cc_defaults { "third_party_abseil_cpp_absl_algorithm_container", "third_party_abseil_cpp_absl_base_core_headers", "third_party_abseil_cpp_absl_container_container_memory", - "third_party_abseil_cpp_absl_container_hash_function_defaults", + "third_party_abseil_cpp_absl_container_hash_container_defaults", "third_party_abseil_cpp_absl_container_raw_hash_set", "third_party_abseil_cpp_absl_memory_memory", ], @@ -5518,6 +5521,31 @@ cc_defaults { } cc_defaults { + name: "third_party_abseil_cpp_absl_container_hash_container_defaults", + defaults: [ + "angle_common_auto_cflags", + "angle_common_library_cflags", + "third_party_abseil_cpp_absl_base_config", + "third_party_abseil_cpp_absl_container_hash_function_defaults", + ], + local_include_dirs: [ + "", + "third_party/abseil-cpp/", + ], + cflags: [ + "-DABSL_ALLOCATOR_NOTHROW=1", + "-Wno-c++11-narrowing", + "-Wno-gcc-compat", + "-Wno-misleading-indentation", + "-Wno-unreachable-code-break", + "-Wno-unused-but-set-variable", + "-Wno-unused-variable", + ], + sdk_version: "28", + stl: "libc++_static", +} + +cc_defaults { name: "third_party_abseil_cpp_absl_base_base_internal", defaults: [ "angle_common_auto_cflags", @@ -5776,7 +5804,7 @@ cc_defaults { "third_party_abseil_cpp_absl_algorithm_container", "third_party_abseil_cpp_absl_base_core_headers", "third_party_abseil_cpp_absl_container_container_memory", - "third_party_abseil_cpp_absl_container_hash_function_defaults", + "third_party_abseil_cpp_absl_container_hash_container_defaults", "third_party_abseil_cpp_absl_container_raw_hash_map", "third_party_abseil_cpp_absl_memory_memory", ], @@ -43,7 +43,7 @@ vars = { 'checkout_angle_mesa': False, # Version of Chromium our Chromium-based DEPS are mirrored from. - 'chromium_revision': 'bc4f0a08ba8d4453fc183d3ef4d59889a3b1cdde', + 'chromium_revision': 'b689a9ee3ba235e256fd93c93247692e1e260351', # We never want to checkout chromium, # but need a dummy DEPS entry for the autoroller 'dummy_checkout_chromium': False, @@ -88,7 +88,7 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'e84a4942dc4ae51442d256009f9d75a98ac680ac', + 'catapult_revision': '0421a22c029768a46f06bdcd399fa2d0db6a66cb', # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. @@ -97,7 +97,7 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling luci-go # and whatever else without interference from each other. - 'luci_go': 'git_revision:01d1863acbd3d4c41da2aa7407a0ea6a195c770f', + 'luci_go': 'git_revision:69f852c6aea2797c75712d59145efd38d7032196', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_build-tools_version @@ -415,7 +415,7 @@ vars = { deps = { 'build': { - 'url': Var('chromium_git') + '/chromium/src/build.git@0347db4c4f2ea6518b19403284bc31fbb46d1e2a', + 'url': Var('chromium_git') + '/chromium/src/build.git@ce8359ec575d6e0c0427414fd5cc7e4b02c42acd', 'condition': 'not build_with_chromium', }, @@ -474,12 +474,12 @@ deps = { }, 'testing': { - 'url': '{chromium_git}/chromium/src/testing@6ed3b71a7d8bee00517b5fb7d459628ae9661ad9', + 'url': '{chromium_git}/chromium/src/testing@cdf49d0710d7c3fdefb2557b16a39b06ea00e61e', 'condition': 'not build_with_chromium', }, 'third_party/abseil-cpp': { - 'url': Var('chromium_git') + '/chromium/src/third_party/abseil-cpp@2c1ad970da6bd5837bcee6671da262eac0bd5397', + 'url': Var('chromium_git') + '/chromium/src/third_party/abseil-cpp@31bdf8fec41f04dfe86976734cbad22ded4ca1f7', 'condition': 'not build_with_chromium', }, @@ -656,7 +656,7 @@ deps = { }, 'third_party/depot_tools': { - 'url': Var('chromium_git') + '/chromium/tools/depot_tools.git@e75b940aeabcca1ea7e38881231e73a32a352753', + 'url': Var('chromium_git') + '/chromium/tools/depot_tools.git@39c8c75cf6a2690957f3de7367a301358c5f3c15', 'condition': 'not build_with_chromium', }, @@ -859,7 +859,7 @@ deps = { }, 'third_party/protobuf': { - 'url': Var('chromium_git') + '/chromium/src/third_party/protobuf@4da68f31de3c95cc15ef5c381d05290eaf5f4585', + 'url': Var('chromium_git') + '/chromium/src/third_party/protobuf@4abbe88863a7dd75dd11da0487e9b995133f7592', 'condition': 'not build_with_chromium', }, @@ -872,7 +872,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'eec4ZxEvkO7Pa1LUWDkVKiCv0bZjS7ctubjxW94ZYVYC', + 'version': 'fXvmQSzprkeb1fs3dnkBm_gsAhb5aUtQGRmUq3Oi1WYC', }, ], 'condition': 'checkout_android and not build_with_chromium', @@ -959,12 +959,12 @@ deps = { }, 'tools/android': { - 'url': Var('chromium_git') + '/chromium/src/tools/android@49bb033593621ee4977cd0dd58e0412035d6bab5', + 'url': Var('chromium_git') + '/chromium/src/tools/android@cc51a5ea8611565ff48db1a11c08e90d03484bd2', 'condition': 'checkout_android and not build_with_chromium', }, 'tools/clang': { - 'url': Var('chromium_git') + '/chromium/src/tools/clang.git@cc8e1423f4ade8b4871bc33fa44f061826bff2ff', + 'url': Var('chromium_git') + '/chromium/src/tools/clang.git@17956d4ffb817dcd19e19c60d5162bcf15ff2034', 'condition': 'not build_with_chromium', }, @@ -995,7 +995,7 @@ deps = { }, 'tools/mb': { - 'url': Var('chromium_git') + '/chromium/src/tools/mb@880331b699ae470dbb88118f9155a238fe0d1b0f', + 'url': Var('chromium_git') + '/chromium/src/tools/mb@668bf195ba3390e4208cc1edc4777fa5747cb9f7', 'condition': 'not build_with_chromium', }, @@ -1010,7 +1010,7 @@ deps = { }, 'tools/perf': { - 'url': Var('chromium_git') + '/chromium/src/tools/perf@73a1c67b512eb876d032ebfb3b539150a4fcd801', + 'url': Var('chromium_git') + '/chromium/src/tools/perf@7ef4ff5ba36be22f641d0f08f34402f85db18492', 'condition': 'not build_with_chromium', }, @@ -1028,7 +1028,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': 'AJacKGh5nnjmNZk56j2ia4-QtIE8eEAFELw48t8XinEC', + 'version': '4Ox2OXGb8xipJPUsrFptKWJNJelzwWHBB3ORF1iHt94C', }, ], 'dep_type': 'cipd', @@ -1039,7 +1039,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': '4bTyiie8-MG6hBk2yGEE9d8p3HWHGevaAouvGfKKwtQC', + 'version': 'CBmdgsk0TAPgochRHBMBS9LZzdhYMOsNaJSAPvA-e-YC', }, ], 'dep_type': 'cipd', @@ -1050,7 +1050,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': 'uJJWpJUp-FSzEXlwqzoUD41p5swLKyDhxXdJBLShbMsC', + 'version': '-H7DJpIRXUmi9ddRqVRJXThT1nlK7ns94UOnHMmeP4IC', }, ], 'dep_type': 'cipd', @@ -1061,7 +1061,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/mac-arm64', - 'version': 'ekRiJKPFBJKiZ3N4ev_vRuf2X13dgTDcZNXKYt2qZPoC', + 'version': 'FclksBOdZsrGv0dS7P163Fl3zi60z6nQCDXMNOoAYLYC', }, ], 'dep_type': 'cipd', diff --git a/build/android/docs/java_optimization.md b/build/android/docs/java_optimization.md index da10222a44..7d3229449c 100644 --- a/build/android/docs/java_optimization.md +++ b/build/android/docs/java_optimization.md @@ -118,7 +118,7 @@ the name of the offending class). * Caching the result of `ClassNameJni.get()` in a member variable. * Passing a native wrapper method reference instead of using a lambda (i.e. `Jni.get()::methodName` vs. `() -> Jni.get.methodName()`). - * For more debugging info, add to `base/android/proguard/chromium_code.flags`: + * For more debugging info, add to `base/android/proguard/chromium_apk.flags`: ``` -whyareyounotinlining class org.chromium.base.library_loader.LibraryPrefetcherJni { <init>(); diff --git a/build/android/gyp/gcc_preprocess.py b/build/android/gyp/gcc_preprocess.py index 0302c073a0..b43a55df47 100755 --- a/build/android/gyp/gcc_preprocess.py +++ b/build/android/gyp/gcc_preprocess.py @@ -15,6 +15,10 @@ from util import build_utils import action_helpers # build_utils adds //build to sys.path. import zip_helpers +_CHROMIUM_SRC = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, + os.pardir) +_LLVM_CLANG_PATH = os.path.join(_CHROMIUM_SRC, 'third_party', 'llvm-build', + 'Release+Asserts', 'bin', 'clang') def _ParsePackageName(data): m = re.match(r'^\s*package\s+(.*?)\s*;', data, re.MULTILINE) @@ -22,17 +26,17 @@ def _ParsePackageName(data): def ProcessJavaFile(template, defines, include_dirs): - gcc_cmd = [ - 'gcc', + clang_cmd = [ + _LLVM_CLANG_PATH, '-E', # stop after preprocessing. '-DANDROID', # Specify ANDROID define for pre-processor. '-x', 'c-header', # treat sources as C header files '-P', # disable line markers, i.e. '#line 309' ] - gcc_cmd.extend('-D' + x for x in defines) - gcc_cmd.extend('-I' + x for x in include_dirs) - data = build_utils.CheckOutput(gcc_cmd + [template]) + clang_cmd.extend('-D' + x for x in defines) + clang_cmd.extend('-I' + x for x in include_dirs) + data = build_utils.CheckOutput(clang_cmd + [template]) package_name = _ParsePackageName(data) if not package_name: raise Exception('Could not find java package of ' + template) diff --git a/build/android/gyp/util/diff_utils.py b/build/android/gyp/util/diff_utils.py index 445bbe3d21..6d980b51f6 100644 --- a/build/android/gyp/util/diff_utils.py +++ b/build/android/gyp/util/diff_utils.py @@ -4,6 +4,7 @@ import difflib import os +import pathlib import sys from util import build_utils @@ -48,6 +49,8 @@ def _GenerateDiffWithOnlyAdditons(expected_path, actual_data): return ''.join(filtered_diff) +_REBASELINE_PROGUARD = os.environ.get('REBASELINE_PROGUARD', '0') != '0' + def _DiffFileContents(expected_path, actual_data): """Check file contents for equality and return the diff or None.""" # Remove all trailing whitespace and add it explicitly in the end. @@ -60,6 +63,11 @@ def _DiffFileContents(expected_path, actual_data): if expected_lines == actual_lines: return None + if _REBASELINE_PROGUARD: + pathlib.Path(expected_path).write_text('\n'.join(actual_lines)) + print(f'Updated {expected_path}') + return None + expected_path = os.path.relpath(expected_path, build_utils.DIR_SOURCE_ROOT) diff = difflib.unified_diff( @@ -94,7 +102,6 @@ def AddCommandLineFlags(parser): action='store_true', help='Verify the expectation and exit.') - def CheckExpectations(actual_data, options, custom_msg=''): if options.actual_file: with action_helpers.atomic_output(options.actual_file) as f: @@ -107,6 +114,8 @@ def CheckExpectations(actual_data, options, custom_msg=''): if not diff_text: fail_msg = '' else: + # The space before the `patch` command is intentional, as it causes the line + # to not be saved in bash history for most configurations. fail_msg = """ Expectations need updating: https://chromium.googlesource.com/chromium/src/+/HEAD/chrome/android/expectations/README.md @@ -122,6 +131,9 @@ To update expectations, run: {} END_DIFF ############ END ############ + +If you are running this locally, you can `export REBASELINE_PROGUARD=1` to +automatically apply this patch. """.format(custom_msg, diff_text) sys.stderr.write(fail_msg) diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 26fad5adf9..b8cac29305 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -713,6 +713,11 @@ if (is_component_build) { default_component_configs -= [ "//build/config/android:hide_all_but_jni_onload" ] } + if (is_win) { + # We don't want component dlls to statically load OS dlls that aren't + # loaded normally. + default_component_configs += [ "//build/config/win:delayloads" ] + } } else { default_component_configs = default_compiler_configs } diff --git a/build/config/android/abi.gni b/build/config/android/abi.gni index 09f0af8062..0f1eb65c0d 100644 --- a/build/config/android/abi.gni +++ b/build/config/android/abi.gni @@ -8,7 +8,7 @@ # NOTE: Because Chrome OS builds may depend on targets built with the Android # toolchain, this GNI file may be read and processed from within Chrome OS # toolchains. Checking |is_android| here would therefore be too restrictive. -assert(is_android || is_chromeos) +assert(is_android || is_chromeos || is_robolectric) declare_args() { # Adds intrumentation to each function. Writes a file with the order that diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 20bd196b8c..87fc7c9882 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni @@ -2,127 +2,122 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/android/abi.gni") +import("//build/config/android/copy_ex.gni") +import("//build/config/clang/clang.gni") +import("//build/config/sanitizers/sanitizers.gni") import("//build_overrides/build.gni") assert( is_android || is_robolectric, "current_toolchain=$current_toolchain default_toolchain=$default_toolchain") -if (is_robolectric) { - template("create_native_executable_dist") { - not_needed(invoker, [ "*" ]) +_sanitizer_runtimes = [] +if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) { + _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.ubsan_standalone-$sanitizer_arch-android.so" ] +} +if (is_asan) { + _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.asan-$sanitizer_arch-android.so" ] +} + +# Creates a dist directory for a native executable. +# +# Running a native executable on a device requires all the shared library +# dependencies of that executable. To make it easier to install and run such an +# executable, this will create a directory containing the native exe and all +# it's library dependencies. +# +# Note: It's usually better to package things as an APK than as a native +# executable. +# +# Variables +# dist_dir: Directory for the exe and libraries. Everything in this directory +# will be deleted before copying in the exe and libraries. +# binary: Path to (stripped) executable. +# extra_files: List of extra files to copy in (optional). +# +# Example +# create_native_executable_dist("foo_dist") { +# dist_dir = "$root_build_dir/foo_dist" +# binary = "$root_build_dir/foo" +# deps = [ ":the_thing_that_makes_foo" ] +# } +template("create_native_executable_dist") { + forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) + + _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list" + + _sanitizer_runtimes_target_name = "${target_name}__sanitizer_runtimes" + group(_sanitizer_runtimes_target_name) { + metadata = { + shared_libraries = _sanitizer_runtimes + } + } + + generated_file("${target_name}__library_list") { + forward_variables_from(invoker, [ "deps" ]) + if (!defined(deps)) { + deps = [] + } + deps += [ ":${_sanitizer_runtimes_target_name}" ] + output_conversion = "json" + outputs = [ _libraries_list ] + data_keys = [ "shared_libraries" ] + walk_keys = [ "shared_libraries_barrier" ] + rebase = root_build_dir } -} else if (enable_java_templates) { - import("//build/config/android/abi.gni") + + copy_ex(target_name) { + inputs = [ + _libraries_list, + invoker.binary, + ] + + dest = invoker.dist_dir + data = [ "${invoker.dist_dir}/" ] + + _rebased_libraries_list = rebase_path(_libraries_list, root_build_dir) + _rebased_binaries_list = rebase_path([ invoker.binary ], root_build_dir) + args = [ + "--clear", + "--files=@FileArg($_rebased_libraries_list)", + "--files=$_rebased_binaries_list", + ] + if (defined(invoker.extra_files)) { + _rebased_extra_files = rebase_path(invoker.extra_files, root_build_dir) + args += [ "--files=$_rebased_extra_files" ] + } + + _depfile = "$target_gen_dir/$target_name.d" + _stamp_file = "$target_gen_dir/$target_name.stamp" + outputs = [ _stamp_file ] + args += [ + "--depfile", + rebase_path(_depfile, root_build_dir), + "--stamp", + rebase_path(_stamp_file, root_build_dir), + ] + + deps = [ ":${target_name}__library_list" ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + } +} + +if (!is_robolectric && enable_java_templates) { import("//build/config/android/config.gni") - import("//build/config/android/copy_ex.gni") import("//build/config/android/internal_rules.gni") - import("//build/config/clang/clang.gni") import("//build/config/compiler/compiler.gni") import("//build/config/coverage/coverage.gni") import("//build/config/profiling/profiling.gni") import("//build/config/python.gni") - import("//build/config/sanitizers/sanitizers.gni") import("//build/config/zip.gni") import("//build/toolchain/toolchain.gni") _BUNDLETOOL_JAR_PATH = "//third_party/android_build_tools/bundletool/bundletool.jar" - _sanitizer_runtimes = [] - if (use_cfi_diag || is_ubsan || is_ubsan_security || is_ubsan_vptr) { - _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.ubsan_standalone-$sanitizer_arch-android.so" ] - } - if (is_asan) { - _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.asan-$sanitizer_arch-android.so" ] - } - - # Creates a dist directory for a native executable. - # - # Running a native executable on a device requires all the shared library - # dependencies of that executable. To make it easier to install and run such an - # executable, this will create a directory containing the native exe and all - # it's library dependencies. - # - # Note: It's usually better to package things as an APK than as a native - # executable. - # - # Variables - # dist_dir: Directory for the exe and libraries. Everything in this directory - # will be deleted before copying in the exe and libraries. - # binary: Path to (stripped) executable. - # extra_files: List of extra files to copy in (optional). - # - # Example - # create_native_executable_dist("foo_dist") { - # dist_dir = "$root_build_dir/foo_dist" - # binary = "$root_build_dir/foo" - # deps = [ ":the_thing_that_makes_foo" ] - # } - template("create_native_executable_dist") { - forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - - _libraries_list = - "${target_gen_dir}/${target_name}_library_dependencies.list" - - _sanitizer_runtimes_target_name = "${target_name}__sanitizer_runtimes" - group(_sanitizer_runtimes_target_name) { - metadata = { - shared_libraries = _sanitizer_runtimes - } - } - - generated_file("${target_name}__library_list") { - forward_variables_from(invoker, [ "deps" ]) - if (!defined(deps)) { - deps = [] - } - deps += [ ":${_sanitizer_runtimes_target_name}" ] - output_conversion = "json" - outputs = [ _libraries_list ] - data_keys = [ "shared_libraries" ] - walk_keys = [ "shared_libraries_barrier" ] - rebase = root_build_dir - } - - copy_ex(target_name) { - inputs = [ - _libraries_list, - invoker.binary, - ] - - dest = invoker.dist_dir - data = [ "${invoker.dist_dir}/" ] - - _rebased_libraries_list = rebase_path(_libraries_list, root_build_dir) - _rebased_binaries_list = rebase_path([ invoker.binary ], root_build_dir) - args = [ - "--clear", - "--files=@FileArg($_rebased_libraries_list)", - "--files=$_rebased_binaries_list", - ] - if (defined(invoker.extra_files)) { - _rebased_extra_files = rebase_path(invoker.extra_files, root_build_dir) - args += [ "--files=$_rebased_extra_files" ] - } - - _depfile = "$target_gen_dir/$target_name.d" - _stamp_file = "$target_gen_dir/$target_name.stamp" - outputs = [ _stamp_file ] - args += [ - "--depfile", - rebase_path(_depfile, root_build_dir), - "--stamp", - rebase_path(_stamp_file, root_build_dir), - ] - - deps = [ ":${target_name}__library_list" ] - if (defined(invoker.deps)) { - deps += invoker.deps - } - } - } - # Declare a target for c-preprocessor-generated java files # # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index dff295865e..0cfbb31d68 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni @@ -39,7 +39,8 @@ declare_args() { # If true, optimize for size. # Default to favoring speed over size for platforms not listed below. - optimize_for_size = !is_high_end_android && (is_android || is_castos) + optimize_for_size = + !is_high_end_android && (is_android || is_castos || is_fuchsia) } declare_args() { diff --git a/build/config/fuchsia/size_optimized_cast_receiver_args.gn b/build/config/fuchsia/size_optimized_cast_receiver_args.gn index 86abbc1bf6..c716dab11b 100644 --- a/build/config/fuchsia/size_optimized_cast_receiver_args.gn +++ b/build/config/fuchsia/size_optimized_cast_receiver_args.gn @@ -34,7 +34,6 @@ enable_library_cdms = false enable_logging_override = true enable_pdf = false enable_plugins = false -optimize_for_size = true optional_trace_events_enabled = false # Ensure PGO and ThinLTO are disabled as these optimizations increase the binary diff --git a/build/config/siso/clang_linux.star b/build/config/siso/clang_linux.star index f0ad598bcd..5604113cb2 100644 --- a/build/config/siso/clang_linux.star +++ b/build/config/siso/clang_linux.star @@ -124,6 +124,9 @@ def __step_config(ctx, step_config): ], }) step_config["input_deps"].update(clang_all.input_deps) + + # Disable remote compiles on Clang ToT builds. + remote = not config.get(ctx, "clang-tot") step_config["rules"].extend([ { "name": "clang/cxx", @@ -133,7 +136,7 @@ def __step_config(ctx, step_config): "third_party/llvm-build/Release+Asserts/bin/clang++", ], "exclude_input_patterns": ["*.stamp"], - "remote": True, + "remote": remote, "canonicalize_dir": True, "timeout": "2m", }, @@ -145,7 +148,7 @@ def __step_config(ctx, step_config): "third_party/llvm-build/Release+Asserts/bin/clang", ], "exclude_input_patterns": ["*.stamp"], - "remote": True, + "remote": remote, "canonicalize_dir": True, "timeout": "2m", }, @@ -156,7 +159,7 @@ def __step_config(ctx, step_config): "inputs": [ "third_party/llvm-build/Release+Asserts/bin/clang", ], - "remote": config.get(ctx, "cog"), + "remote": remote and config.get(ctx, "cog"), "canonicalize_dir": True, "timeout": "2m", }, @@ -169,7 +172,7 @@ def __step_config(ctx, step_config): ], "exclude_input_patterns": ["*.stamp"], "handler": "clang_compile_coverage", - "remote": True, + "remote": remote, "canonicalize_dir": True, "timeout": "2m", }, @@ -182,7 +185,7 @@ def __step_config(ctx, step_config): ], "exclude_input_patterns": ["*.stamp"], "handler": "clang_compile_coverage", - "remote": True, + "remote": remote, "canonicalize_dir": True, "timeout": "2m", }, diff --git a/build/config/siso/clang_mac.star b/build/config/siso/clang_mac.star index 5af698a06b..852189fe72 100644 --- a/build/config/siso/clang_mac.star +++ b/build/config/siso/clang_mac.star @@ -9,6 +9,7 @@ load("@builtin//path.star", "path") load("@builtin//struct.star", "module") load("./clang_all.star", "clang_all") load("./clang_code_coverage_wrapper.star", "clang_code_coverage_wrapper") +load("./config.star", "config") load("./rewrapper_cfg.star", "rewrapper_cfg") def __filegroups(ctx): @@ -94,6 +95,9 @@ def __step_config(ctx, step_config): # objc/objcxx uses hmap, which contains absolute path # see also b/256536089 need_input_root_absolute_path_for_objc = True + + # Disable remote compiles on Clang ToT builds. + remote = not config.get(ctx, "clang-tot") step_config["rules"].extend([ { "name": "clang/cxx", @@ -104,7 +108,7 @@ def __step_config(ctx, step_config): ], "exclude_input_patterns": ["*.stamp"], "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", }, @@ -117,7 +121,7 @@ def __step_config(ctx, step_config): ], "exclude_input_patterns": ["*.stamp"], "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", }, @@ -130,7 +134,7 @@ def __step_config(ctx, step_config): ], "exclude_input_patterns": ["*.stamp"], "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", "input_root_absolute_path": need_input_root_absolute_path_for_objc, @@ -144,7 +148,7 @@ def __step_config(ctx, step_config): ], "exclude_input_patterns": ["*.stamp"], "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", "input_root_absolute_path": need_input_root_absolute_path_for_objc, @@ -159,7 +163,7 @@ def __step_config(ctx, step_config): "exclude_input_patterns": ["*.stamp"], "handler": "clang_compile_coverage", "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", }, @@ -173,7 +177,7 @@ def __step_config(ctx, step_config): "exclude_input_patterns": ["*.stamp"], "handler": "clang_compile_coverage", "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", }, @@ -187,7 +191,7 @@ def __step_config(ctx, step_config): "exclude_input_patterns": ["*.stamp"], "handler": "clang_compile_coverage", "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", "input_root_absolute_path": need_input_root_absolute_path_for_objc, @@ -202,7 +206,7 @@ def __step_config(ctx, step_config): "exclude_input_patterns": ["*.stamp"], "handler": "clang_compile_coverage", "platform_ref": "clang", - "remote": True, + "remote": remote, "remote_wrapper": reproxy_config["remote_wrapper"], "timeout": "2m", "input_root_absolute_path": need_input_root_absolute_path_for_objc, diff --git a/build/config/siso/clang_windows.star b/build/config/siso/clang_windows.star index 3d755eb89d..42f306cad7 100644 --- a/build/config/siso/clang_windows.star +++ b/build/config/siso/clang_windows.star @@ -9,6 +9,7 @@ load("@builtin//path.star", "path") load("@builtin//struct.star", "module") load("./clang_all.star", "clang_all") load("./clang_code_coverage_wrapper.star", "clang_code_coverage_wrapper") +load("./config.star", "config") load("./rewrapper_cfg.star", "rewrapper_cfg") def __win_toolchain_dir(ctx): @@ -75,9 +76,11 @@ def __step_config(ctx, step_config): # missing build/win_toolchain.json), we can't run # clang-cl remotely as we can find sysroot files # under exec_root, so just run locally. + # When building with ToT Clang, we can't run clang-cl + # remotely, too. remote = False win_toolchain_dir = __win_toolchain_dir(ctx) - if win_toolchain_dir: + if win_toolchain_dir and not config.get(ctx, "clang-tot"): remote = True if reproxy_config["platform"]["OSFamily"] == "Windows": step_config["input_deps"].update({ diff --git a/build/config/siso/config.star b/build/config/siso/config.star index 800b90ee41..95c0c476f9 100644 --- a/build/config/siso/config.star +++ b/build/config/siso/config.star @@ -23,6 +23,9 @@ __KNOWN_CONFIG_OPTIONS = [ # TODO: b/316267242 - Enable remote links after confirming performance. "remote-library-link", "remote-exec-link", + + # Clang ToT builds don't run compile actions remotely. + "clang-tot", ] def __check(ctx): diff --git a/build/config/siso/rust_linux.star b/build/config/siso/rust_linux.star index 3301aa6745..7b47477124 100644 --- a/build/config/siso/rust_linux.star +++ b/build/config/siso/rust_linux.star @@ -103,12 +103,20 @@ def __rust_bin_handler(ctx, cmd): ctx.actions.fix(inputs = cmd.inputs + inputs) +def __rust_build_handler(ctx, cmd): + inputs = [] + for i, arg in enumerate(cmd.args): + if arg == "--src-dir": + inputs.append(ctx.fs.canonpath(cmd.args[i + 1])) + ctx.actions.fix(inputs = cmd.inputs + inputs) + __handlers = { "rust_bin_handler": __rust_bin_handler, + "rust_build_handler": __rust_build_handler, } def __step_config(ctx, step_config): - remote_run = True # Turn this to False when you do file access trace. + remote_run = not config.get(ctx, "clang-tot") # Turn this to False when you do file access trace. platform_ref = "large" # Rust actions run faster on large workers. clang_inputs = [ "build/linux/debian_bullseye_amd64-sysroot:rustlink", @@ -195,12 +203,8 @@ def __step_config(ctx, step_config): "build/gn_helpers.py", "third_party/rust-toolchain:toolchain", "third_party/rust:rustlib", - # XXX: -src-dir? - "third_party/rust-toolchain/lib/rustlib/src/rust/library/std", - "third_party/rust-toolchain/lib/rustlib/src/rust/vendor/libc-0.2.153", - "third_party/rust-toolchain/lib/rustlib/src/rust/vendor/memchr-2.5.0", - "third_party/rust-toolchain/lib/rustlib/src/rust/vendor/compiler_builtins-0.1.108", ], + "handler": "rust_build_handler", "remote": config.get(ctx, "cog"), "input_root_absolute_path": True, "timeout": "2m", diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE index 6dbe648f19..1a15bf9257 100644 --- a/build/util/LASTCHANGE +++ b/build/util/LASTCHANGE @@ -1,2 +1,2 @@ -LASTCHANGE=0347db4c4f2ea6518b19403284bc31fbb46d1e2a-refs/heads/main@{#1294809} +LASTCHANGE=ce8359ec575d6e0c0427414fd5cc7e4b02c42acd-refs/heads/main@{#1295863} LASTCHANGE_YEAR=2024 diff --git a/build/util/LASTCHANGE.committime b/build/util/LASTCHANGE.committime index 95451e6425..2bb340c540 100644 --- a/build/util/LASTCHANGE.committime +++ b/build/util/LASTCHANGE.committime @@ -1 +1 @@ -1714550162
\ No newline at end of file +1714695969
\ No newline at end of file diff --git a/build/util/ide_query b/build/util/ide_query index 5286df4417..7f0fec7a10 100755 --- a/build/util/ide_query +++ b/build/util/ide_query @@ -89,7 +89,9 @@ def main(): options.out_dir, ]) args.extend(targets) - p = subprocess.run(args, cwd=repo_root, stdout=2, stderr=2) + env = os.environ.copy() + env['SISO_EXPERIMENTS'] = 'no-fast-deps' + p = subprocess.run(args, cwd=repo_root, stdout=2, stderr=2, env=env) if p.returncode != 0: # TODO: report error in IdeAnalysis.Status? sys.stderr.write('build failed with %d\n' % p.returncode) diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index 0d6ca0f8a5..f1983aa985 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg @@ -46,6 +46,11 @@ consoles { short_name: "asan" } builders { + name: "buildbucket/luci.angle.ci/linux-exp-test" + category: "test|linux|x64" + short_name: "exp" + } + builders { name: "buildbucket/luci.angle.ci/linux-tsan-test" category: "test|linux|x64" short_name: "tsan" @@ -178,9 +183,6 @@ consoles { name: "buildbucket/luci.angle.ci/linux-exp-asan-test" } builders { - name: "buildbucket/luci.angle.ci/linux-exp-test" - } - builders { name: "buildbucket/luci.angle.ci/linux-exp-tsan-test" } builders { diff --git a/infra/config/main.star b/infra/config/main.star index cd94109820..1533f831f6 100755 --- a/infra/config/main.star +++ b/infra/config/main.star @@ -322,6 +322,7 @@ def angle_builder(name, cpu): active_experimental_builders = [ "android-arm64-exp-test", "android-arm64-exp-s22-test", + "linux-exp-test", "mac-exp-test", ] diff --git a/infra/specs/angle.json b/infra/specs/angle.json index 560f08d5a5..2d2cbff576 100644 --- a/infra/specs/angle.json +++ b/infra/specs/angle.json @@ -16,7 +16,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -43,7 +43,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -70,7 +70,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -96,7 +96,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -122,7 +122,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -149,7 +149,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -175,7 +175,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -201,7 +201,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -231,7 +231,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -260,7 +260,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -289,7 +289,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -318,7 +318,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -348,7 +348,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -378,7 +378,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -407,7 +407,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -436,7 +436,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -465,7 +465,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -494,7 +494,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -521,7 +521,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -546,7 +546,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -572,7 +572,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -604,7 +604,7 @@ "swarming": { "containment_type": "AUTO", "dimensions": { - "device_os": "UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002", + "device_os": "AP1A.240405.002", "device_os_type": "userdebug", "device_type": "oriole", "os": "Android", @@ -2795,7 +2795,291 @@ ] }, "linux-amd": {}, - "linux-exp-intel": {}, + "linux-exp-intel": { + "gtest_tests": [ + { + "args": [ + "--use-angle=gl", + "--no-xvfb" + ], + "merge": { + "script": "//scripts/angle_deqp_test_merge.py" + }, + "name": "angle_deqp_gles2_gl_tests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_deqp_gles2_tests", + "test_id_prefix": "ninja://src/tests:angle_deqp_gles2_tests/", + "use_isolated_scripts_api": true + }, + { + "args": [ + "--gtest_filter=-*Vulkan_SwiftShader*", + "--max-processes=4", + "--no-xvfb" + ], + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_end2end_tests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "angle_end2end_tests", + "test_id_prefix": "ninja://src/tests:angle_end2end_tests/", + "use_isolated_scripts_api": true + }, + { + "args": [ + "--test-timeout=300", + "--batch-size=10", + "--no-xvfb" + ], + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_gles1_conformance_tests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_gles1_conformance_tests", + "test_id_prefix": "ninja://src/tests:angle_gles1_conformance_tests/", + "use_isolated_scripts_api": true + }, + { + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_unittests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_unittests", + "test_id_prefix": "ninja://src/tests:angle_unittests/", + "use_isolated_scripts_api": true + }, + { + "args": [ + "--no-xvfb" + ], + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_white_box_tests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_white_box_tests", + "test_id_prefix": "ninja://src/tests:angle_white_box_tests/", + "use_isolated_scripts_api": true + } + ], + "isolated_scripts": [ + { + "args": [ + "--log=debug" + ], + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_capture_tests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_capture_tests", + "test_id_prefix": "ninja://src/tests:angle_capture_tests/" + }, + { + "args": [ + "--log=debug", + "--smoke-test-mode", + "--show-test-stdout" + ], + "merge": { + "args": [ + "--smoke-test-mode" + ], + "script": "//scripts/process_angle_perf_results.py" + }, + "name": "angle_perftests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "angle_perftests", + "test_id_prefix": "ninja://src/tests:angle_perftests/" + }, + { + "args": [ + "--test-machine-name", + "${buildername}", + "--trace-interpreter=gz", + "--filter=fishdom:geometry_dash:merge_dragons:minecraft_bedrock:new_legend_of_the_condor_heroes:street_fighter_duel:teslagrad:vainglory", + "--git-revision=${got_angle_revision}" + ], + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_restricted_trace_gold_interpreted_tests", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}", + "--use-permissive-pixel-comparison=${use_permissive_angle_pixel_comparison}" + ], + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_restricted_trace_gold_tests", + "test_id_prefix": "ninja://src/tests/restricted_traces:angle_restricted_trace_gold_tests/" + }, + { + "args": [ + "--test-machine-name", + "${buildername}", + "--git-revision=${got_angle_revision}" + ], + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "angle_restricted_trace_gold_tests", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}", + "--use-permissive-pixel-comparison=${use_permissive_angle_pixel_comparison}" + ], + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_restricted_trace_gold_tests", + "test_id_prefix": "ninja://src/tests/restricted_traces:angle_restricted_trace_gold_tests/" + }, + { + "args": [ + "--log=debug", + "--smoke-test-mode", + "--show-test-stdout", + "--use-gl=native", + "--trace-tests" + ], + "merge": { + "args": [ + "--smoke-test-mode" + ], + "script": "//scripts/process_angle_perf_results.py" + }, + "name": "angle_trace_perf_native_tests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "angle_trace_perf_tests", + "test_id_prefix": "ninja://src/tests:angle_trace_perf_tests/" + }, + { + "args": [ + "--log=debug", + "--smoke-test-mode", + "--show-test-stdout", + "--use-angle=vulkan", + "--trace-tests" + ], + "merge": { + "args": [ + "--smoke-test-mode" + ], + "script": "//scripts/process_angle_perf_results.py" + }, + "name": "angle_trace_perf_vulkan_tests", + "swarming": { + "containment_type": "AUTO", + "dimensions": { + "display_attached": "1", + "gpu": "8086:9bc5-23.2.1", + "os": "Ubuntu-22.04.4", + "pool": "chromium.tests.gpu" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "angle_trace_perf_tests", + "test_id_prefix": "ninja://src/tests:angle_trace_perf_tests/" + } + ] + }, "linux-exp-swiftshader": {}, "linux-exp-swiftshader-asan": {}, "linux-exp-swiftshader-tsan": {}, @@ -5743,7 +6027,9 @@ } ] }, - "mac-exp-intel": { + "mac-exp-intel": {}, + "mac-exp-nvidia": {}, + "mac-intel": { "gtest_tests": [ { "args": [ @@ -5929,193 +6215,6 @@ } ] }, - "mac-exp-nvidia": {}, - "mac-intel": { - "gtest_tests": [ - { - "args": [ - "--use-angle=gl", - "--max-processes=1" - ], - "merge": { - "script": "//scripts/angle_deqp_test_merge.py" - }, - "name": "angle_deqp_egl_gl_tests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_egl_tests", - "test_id_prefix": "ninja://src/tests:angle_deqp_egl_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "--use-angle=metal" - ], - "merge": { - "script": "//scripts/angle_deqp_test_merge.py" - }, - "name": "angle_deqp_egl_metal_tests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_egl_tests", - "test_id_prefix": "ninja://src/tests:angle_deqp_egl_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "--use-angle=gl", - "--flaky-retries=2" - ], - "merge": { - "script": "//scripts/angle_deqp_test_merge.py" - }, - "name": "angle_deqp_gles2_gl_tests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles2_tests", - "test_id_prefix": "ninja://src/tests:angle_deqp_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "--use-angle=metal", - "--flaky-retries=2" - ], - "merge": { - "script": "//scripts/angle_deqp_test_merge.py" - }, - "name": "angle_deqp_gles2_metal_tests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_deqp_gles2_tests", - "test_id_prefix": "ninja://src/tests:angle_deqp_gles2_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "--use-angle=gl", - "--flaky-retries=2" - ], - "merge": { - "script": "//scripts/angle_deqp_test_merge.py" - }, - "name": "angle_deqp_gles3_gl_tests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test": "angle_deqp_gles3_tests", - "test_id_prefix": "ninja://src/tests:angle_deqp_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "--use-angle=metal", - "--flaky-retries=2" - ], - "merge": { - "script": "//scripts/angle_deqp_test_merge.py" - }, - "name": "angle_deqp_gles3_metal_tests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test": "angle_deqp_gles3_tests", - "test_id_prefix": "ninja://src/tests:angle_deqp_gles3_tests/", - "use_isolated_scripts_api": true - }, - { - "args": [ - "--gtest_filter=-*Vulkan_SwiftShader*", - "--flaky-retries=2" - ], - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "angle_end2end_tests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 - }, - "test": "angle_end2end_tests", - "test_id_prefix": "ninja://src/tests:angle_end2end_tests/", - "use_isolated_scripts_api": true - }, - { - "merge": { - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "angle_unittests", - "swarming": { - "containment_type": "AUTO", - "dimensions": { - "cpu": "x86-64", - "display_attached": "1", - "gpu": "8086:3e9b", - "os": "Mac-13.5|Mac-14.4.1" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "angle_unittests", - "test_id_prefix": "ninja://src/tests:angle_unittests/", - "use_isolated_scripts_api": true - } - ] - }, "mac-nvidia": { "gtest_tests": [ { diff --git a/infra/specs/mixins.pyl b/infra/specs/mixins.pyl index 2b6c0c6722..5d1b22e1a2 100644 --- a/infra/specs/mixins.pyl +++ b/infra/specs/mixins.pyl @@ -15,7 +15,7 @@ { 'android_r': {'swarming': {'dimensions': {'device_os': 'R'}}}, 'android_t': {'swarming': {'dimensions': {'device_os': 'TP1A.220624.021'}}}, - 'android_u': { 'swarming': { 'dimensions': { 'device_os': 'UQ1A.240105.002|UQ1A.240205.002|AP1A.240405.002'}}}, + 'android_u': {'swarming': {'dimensions': {'device_os': 'AP1A.240405.002'}}}, 'angle_skia_gold_test': { 'args': ['--git-revision=${got_angle_revision}'], 'precommit_args': [ '--gerrit-issue=${patch_issue}', '--gerrit-patchset=${patch_set}', @@ -31,6 +31,10 @@ 'gpu': '1002:7340-23.2.1', 'os': 'Ubuntu-22.04', 'pool': 'chromium.tests.gpu'}}}, + 'linux_intel_uhd_630_experimental': { 'swarming': { 'dimensions': { 'display_attached': '1', + 'gpu': '8086:9bc5-23.2.1', + 'os': 'Ubuntu-22.04.4', + 'pool': 'chromium.tests.gpu'}}}, 'linux_intel_uhd_630_stable': { 'swarming': { 'dimensions': { 'gpu': '8086:9bc5-20.0.8', 'os': 'Ubuntu-18.04.6', 'pool': 'chromium.tests.gpu'}}}, @@ -44,7 +48,7 @@ 'mac_mini_intel_gpu_stable': { 'swarming': { 'dimensions': { 'cpu': 'x86-64', 'display_attached': '1', 'gpu': '8086:3e9b', - 'os': 'Mac-13.5|Mac-14.4.1'}}}, + 'os': 'Mac-14.4.1'}}}, 'mac_retina_amd_gpu_experimental': { 'swarming': { 'dimensions': { 'cpu': 'x86-64', 'display_attached': '1', 'gpu': '1002:67ef', diff --git a/infra/specs/waterfalls.pyl b/infra/specs/waterfalls.pyl index 717f8f263b..da96a99bac 100644 --- a/infra/specs/waterfalls.pyl +++ b/infra/specs/waterfalls.pyl @@ -102,9 +102,11 @@ 'linux-exp-intel': { 'os_type': 'linux', 'mixins': [ - 'linux_intel_uhd_630_stable', + 'linux_intel_uhd_630_experimental', ], 'test_suites': { + 'gtest_tests': 'linux_intel_gtests', + 'isolated_scripts': 'isolated_scripts_group_common', }, }, 'linux-exp-swiftshader': { @@ -247,7 +249,6 @@ 'mac_mini_intel_gpu_experimental', ], 'test_suites': { - 'gtest_tests': 'mac_amd_and_intel_gtests', }, }, 'mac-exp-nvidia': { diff --git a/scripts/code_generation_hashes/SPIR-V_helpers.json b/scripts/code_generation_hashes/SPIR-V_helpers.json index cb1b596b6d..944cf1a2cb 100644 --- a/scripts/code_generation_hashes/SPIR-V_helpers.json +++ b/scripts/code_generation_hashes/SPIR-V_helpers.json @@ -1,8 +1,8 @@ { "src/common/spirv/gen_spirv_builder_and_parser.py": - "e95670a30a4eda80a146b61c986fb03c", + "868a697edbc38c95e36be54cf5c71435", "src/common/spirv/spirv_instruction_builder_autogen.cpp": - "1b5f60a24d459e7a30c29cf7acfa2106", + "c149de371bcd571bd31cc8eb1e517910", "src/common/spirv/spirv_instruction_builder_autogen.h": "56b1309d8afabb2b64d7e16f0c4a4898", "src/common/spirv/spirv_instruction_parser_autogen.cpp": diff --git a/src/common/MemoryBuffer.cpp b/src/common/MemoryBuffer.cpp index aadffe8bbe..2a6f572283 100644 --- a/src/common/MemoryBuffer.cpp +++ b/src/common/MemoryBuffer.cpp @@ -62,6 +62,12 @@ bool MemoryBuffer::resize(size_t size) return true; } +void MemoryBuffer::trim(size_t size) +{ + ASSERT(size <= mSize); + mSize = size; +} + void MemoryBuffer::fill(uint8_t datum) { if (!empty()) diff --git a/src/common/MemoryBuffer.h b/src/common/MemoryBuffer.h index aeb96b94a2..9b3f97623b 100644 --- a/src/common/MemoryBuffer.h +++ b/src/common/MemoryBuffer.h @@ -27,6 +27,7 @@ class MemoryBuffer final : NonCopyable MemoryBuffer &operator=(MemoryBuffer &&other); [[nodiscard]] bool resize(size_t size); + void trim(size_t size); void clear() { (void)resize(0); } size_t size() const { return mSize; } bool empty() const { return mSize == 0; } diff --git a/src/common/spirv/gen_spirv_builder_and_parser.py b/src/common/spirv/gen_spirv_builder_and_parser.py index 5e8e9bc4e8..c7e1f401b3 100755 --- a/src/common/spirv/gen_spirv_builder_and_parser.py +++ b/src/common/spirv/gen_spirv_builder_and_parser.py @@ -93,6 +93,15 @@ uint32_t MakeLengthOp(size_t length, spv::Op op) ASSERT(length <= 0xFFFFu); ASSERT(op <= 0xFFFFu); + // It's easy for a complex shader to be crafted to hit the length limit, + // turn that into a crash instead of a security bug. Ideally, the compiler + // would gracefully fail compilation, so this is more of a safety net. + if (ANGLE_UNLIKELY(length > 0xFFFFu)) + { + ERR() << "Complex shader not representible in SPIR-V"; + ANGLE_CRASH(); + } + return static_cast<uint32_t>(length) << 16 | op; } } // anonymous namespace diff --git a/src/common/spirv/spirv_instruction_builder_autogen.cpp b/src/common/spirv/spirv_instruction_builder_autogen.cpp index 3c73c58e3c..6e6ad6f510 100644 --- a/src/common/spirv/spirv_instruction_builder_autogen.cpp +++ b/src/common/spirv/spirv_instruction_builder_autogen.cpp @@ -25,6 +25,15 @@ uint32_t MakeLengthOp(size_t length, spv::Op op) ASSERT(length <= 0xFFFFu); ASSERT(op <= 0xFFFFu); + // It's easy for a complex shader to be crafted to hit the length limit, + // turn that into a crash instead of a security bug. Ideally, the compiler + // would gracefully fail compilation, so this is more of a safety net. + if (ANGLE_UNLIKELY(length > 0xFFFFu)) + { + ERR() << "Complex shader not representible in SPIR-V"; + ANGLE_CRASH(); + } + return static_cast<uint32_t>(length) << 16 | op; } } // anonymous namespace diff --git a/src/common/spirv/spirv_types.h b/src/common/spirv/spirv_types.h index 2b060d2cfe..c97e4db477 100644 --- a/src/common/spirv/spirv_types.h +++ b/src/common/spirv/spirv_types.h @@ -128,8 +128,9 @@ enum HeaderIndex // Returns whether SPIR-V is valid. Useful for ASSERTs. Automatically generates a warning if // SPIR-V is not valid. bool Validate(const Blob &blob); +#if defined(ANGLE_ENABLE_ASSERTS) void Print(const Blob &blob); - +#endif } // namespace spirv } // namespace angle diff --git a/src/libANGLE/angletypes.cpp b/src/libANGLE/angletypes.cpp index d06db485f9..d8f3e2f6ca 100644 --- a/src/libANGLE/angletypes.cpp +++ b/src/libANGLE/angletypes.cpp @@ -1074,6 +1074,7 @@ bool CompressBlob(const size_t cacheSize, const uint8_t *cacheData, MemoryBuffer { uLong uncompressedSize = static_cast<uLong>(cacheSize); uLong expectedCompressedSize = zlib_internal::GzipExpectedCompressedSize(uncompressedSize); + uLong actualCompressedSize = expectedCompressedSize; // Allocate memory. if (!compressedData->resize(expectedCompressedSize)) @@ -1082,7 +1083,7 @@ bool CompressBlob(const size_t cacheSize, const uint8_t *cacheData, MemoryBuffer return false; } - int zResult = zlib_internal::GzipCompressHelper(compressedData->data(), &expectedCompressedSize, + int zResult = zlib_internal::GzipCompressHelper(compressedData->data(), &actualCompressedSize, cacheData, uncompressedSize, nullptr, nullptr); if (zResult != Z_OK) @@ -1091,11 +1092,9 @@ bool CompressBlob(const size_t cacheSize, const uint8_t *cacheData, MemoryBuffer return false; } - // Resize it to expected size. - if (!compressedData->resize(expectedCompressedSize)) - { - return false; - } + // Trim to actual size. + ASSERT(actualCompressedSize <= expectedCompressedSize); + compressedData->trim(actualCompressedSize); return true; } diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index bd27717cf0..44b937d2b9 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -1165,7 +1165,12 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, vk::Rendere } if (mRenderer->useDepthTestEnableDynamicState()) { - mPipelineDirtyBitsMask.reset(gl::state::DIRTY_BIT_DEPTH_TEST_ENABLED); + // Depth test affects depth write state too in GraphicsPipelineDesc, so the pipeline needs + // to stay dirty if depth test changes while depth write state is static. + if (mRenderer->useDepthWriteEnableDynamicState()) + { + mPipelineDirtyBitsMask.reset(gl::state::DIRTY_BIT_DEPTH_TEST_ENABLED); + } } if (mRenderer->useDepthWriteEnableDynamicState()) { @@ -6619,6 +6624,8 @@ angle::Result ContextVk::dispatchCompute(const gl::Context *context, ANGLE_TRY(setupDispatch(context)); mOutsideRenderPassCommands->getCommandBuffer().dispatch(numGroupsX, numGroupsY, numGroupsZ); + // Track completion of compute. + mOutsideRenderPassCommands->flushSetEvents(this); return angle::Result::Continue; } @@ -6646,6 +6653,9 @@ angle::Result ContextVk::dispatchComputeIndirect(const gl::Context *context, GLi mOutsideRenderPassCommands->getCommandBuffer().dispatchIndirect(buffer.getBuffer(), buffer.getOffset() + indirect); + // Track completion of compute. + mOutsideRenderPassCommands->flushSetEvents(this); + return angle::Result::Continue; } diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h index b11ffb46ae..ed473f791e 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/src/libANGLE/renderer/vulkan/ContextVk.h @@ -588,6 +588,28 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText return angle::Result::Continue; } + void trackImageWithOutsideRenderPassEvent(vk::ImageHelper *image) + { + if (mRenderer->getFeatures().useVkEventForImageBarrier.enabled) + { + mOutsideRenderPassCommands->trackImageWithEvent(this, image); + } + } + void trackImagesWithOutsideRenderPassEvent(vk::ImageHelper *srcImage, vk::ImageHelper *dstImage) + { + if (mRenderer->getFeatures().useVkEventForImageBarrier.enabled) + { + mOutsideRenderPassCommands->trackImagesWithEvent(this, srcImage, dstImage); + } + } + void trackImagesWithOutsideRenderPassEvent(const vk::ImageHelperPtr *images, size_t count) + { + if (mRenderer->getFeatures().useVkEventForImageBarrier.enabled) + { + mOutsideRenderPassCommands->trackImagesWithEvent(this, images, count); + } + } + angle::Result submitStagedTextureUpdates() { // Staged updates are recorded in outside RP cammand buffer, submit them. diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp index 8c77f510b1..07554f8a7e 100644 --- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp @@ -1386,13 +1386,20 @@ angle::Result FramebufferVk::blit(const gl::Context *context, if (canBlitWithCommand && areChannelsBlitCompatible && !reinterpretsColorspace) { + // Stash all images that involved with blit so that we can track them all at once. + angle::FixedVector<vk::ImageHelper *, 1 + gl::IMPLEMENTATION_MAX_DRAW_BUFFERS> + accessedImages; + accessedImages.push_back(&readRenderTarget->getImageForCopy()); for (size_t colorIndexGL : mState.getEnabledDrawBuffers()) { RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorIndexGL]; ANGLE_TRY(blitWithCommand(contextVk, sourceArea, destArea, readRenderTarget, drawRenderTarget, filter, true, false, false, flipX, flipY)); + accessedImages.push_back(&drawRenderTarget->getImageForWrite()); } + contextVk->trackImagesWithOutsideRenderPassEvent(accessedImages.data(), + accessedImages.size()); } // If we're not flipping or rotating, use Vulkan's builtin resolve. else if (isColorResolve && !flipX && !flipY && areChannelsBlitCompatible && @@ -1500,6 +1507,8 @@ angle::Result FramebufferVk::blit(const gl::Context *context, ANGLE_TRY(blitWithCommand(contextVk, sourceArea, destArea, readRenderTarget, drawRenderTarget, filter, false, blitDepthBuffer, blitStencilBuffer, flipX, flipY)); + contextVk->trackImagesWithOutsideRenderPassEvent(&readRenderTarget->getImageForCopy(), + &drawRenderTarget->getImageForWrite()); } else { @@ -1843,6 +1852,9 @@ angle::Result FramebufferVk::generateFragmentShadingRateWithCPU( dataUpload->copyBufferToImage(buffer->getBuffer().getHandle(), mFragmentShadingRateImage.getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©); + + contextVk->trackImageWithOutsideRenderPassEvent(&mFragmentShadingRateImage); + return angle::Result::Continue; } @@ -1997,6 +2009,8 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk, resolveRegion.extent.depth = 1; angle::VulkanPerfCounters &perfCounters = contextVk->getPerfCounters(); + angle::FixedVector<vk::ImageHelperPtr, 1 + gl::IMPLEMENTATION_MAX_DRAW_BUFFERS> accessedImages; + accessedImages.push_back(srcImage); for (size_t colorIndexGL : mState.getEnabledDrawBuffers()) { RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorIndexGL]; @@ -2009,7 +2023,9 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk, srcImage->resolve(&dstImage, resolveRegion, commandBuffer); perfCounters.resolveImageCommands++; + accessedImages.push_back(&dstImage); } + contextVk->trackImagesWithOutsideRenderPassEvent(accessedImages.data(), accessedImages.size()); return angle::Result::Continue; } diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp index 7bac2b9e5d..326b8c73fe 100644 --- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp +++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp @@ -2212,6 +2212,8 @@ angle::Result WindowSurfaceVk::prePresentSubmit(ContextVk *contextVk, mColorImageMS.resolve(image.image.get(), resolveRegion, &commandBufferHelper->getCommandBuffer()); + + contextVk->trackImagesWithOutsideRenderPassEvent(&mColorImageMS, image.image.get()); contextVk->getPerfCounters().swapchainResolveOutsideSubpass++; } diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp index baa66a1410..f49b975d43 100644 --- a/src/libANGLE/renderer/vulkan/TextureVk.cpp +++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp @@ -1449,6 +1449,8 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk, vk::ImageHelper::Copy(contextVk, srcImage, mImage, srcOffset, dstOffsetModified, extents, srcSubresource, destSubresource, commandBuffer); + + contextVk->trackImagesWithOutsideRenderPassEvent(srcImage, mImage); } else { @@ -1483,6 +1485,8 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk, vk::ImageHelper::Copy(contextVk, srcImage, &stagingImage->get(), srcOffset, gl::kOffsetZero, extents, srcSubresource, destSubresource, commandBuffer); + contextVk->trackImagesWithOutsideRenderPassEvent(srcImage, &stagingImage->get()); + // Stage the copy for when the image storage is actually created. VkImageType imageType = gl_vk::GetImageType(mState.getType()); const gl::ImageIndex stagingIndex = @@ -2209,6 +2213,8 @@ angle::Result TextureVk::copyBufferDataToImage(ContextVk *contextVk, commandBuffer->copyBufferToImage(srcBuffer->getBuffer().getHandle(), mImage->getImage(), mImage->getCurrentLayout(contextVk), 1, ®ion); + contextVk->trackImageWithOutsideRenderPassEvent(mImage); + return angle::Result::Continue; } @@ -2318,6 +2324,8 @@ angle::Result TextureVk::generateMipmapsWithCompute(ContextVk *contextVk) } } + contextVk->trackImageWithOutsideRenderPassEvent(mImage); + return angle::Result::Continue; } @@ -2519,6 +2527,8 @@ angle::Result TextureVk::copyAndStageImageData(ContextVk *contextVk, stagingImage->get().getCurrentLayout(contextVk), 1, ©Region); } + contextVk->trackImagesWithOutsideRenderPassEvent(srcImage, &stagingImage->get()); + // Stage the staging image in the destination dstImage->stageSubresourceUpdatesFromAllImageLevels(stagingImage.release(), previousFirstAllocateLevel); diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp index 46c259230c..e1d1b3cd23 100644 --- a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp +++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp @@ -4274,10 +4274,8 @@ bool operator==(const AttachmentOpsArray &lhs, const AttachmentOpsArray &rhs) // DescriptorSetLayoutDesc implementation. DescriptorSetLayoutDesc::DescriptorSetLayoutDesc() - : mPackedDescriptorSetLayout{}, mValidDescriptorSetLayoutIndexMask() -{ - mImmutableSamplers.fill(VK_NULL_HANDLE); -} + : mDescriptorSetLayoutBindings{}, mImmutableSamplers{} +{} DescriptorSetLayoutDesc::~DescriptorSetLayoutDesc() = default; @@ -4288,20 +4286,32 @@ DescriptorSetLayoutDesc &DescriptorSetLayoutDesc::operator=(const DescriptorSetL size_t DescriptorSetLayoutDesc::hash() const { - size_t genericHash = angle::ComputeGenericHash(mValidDescriptorSetLayoutIndexMask); - for (size_t bindingIndex : mValidDescriptorSetLayoutIndexMask) + size_t validDescriptorSetLayoutBindingsCount = mDescriptorSetLayoutBindings.size(); + size_t validImmutableSamplersCount = mImmutableSamplers.size(); + + ASSERT(validDescriptorSetLayoutBindingsCount != 0 || validImmutableSamplersCount == 0); + + size_t genericHash = 0; + if (validDescriptorSetLayoutBindingsCount > 0) { - genericHash ^= angle::ComputeGenericHash(mPackedDescriptorSetLayout[bindingIndex]) ^ - angle::ComputeGenericHash(mImmutableSamplers[bindingIndex]); + genericHash = angle::ComputeGenericHash( + mDescriptorSetLayoutBindings.data(), + validDescriptorSetLayoutBindingsCount * sizeof(PackedDescriptorSetBinding)); } + + if (validImmutableSamplersCount > 0) + { + genericHash ^= angle::ComputeGenericHash(mImmutableSamplers.data(), + validImmutableSamplersCount * sizeof(VkSampler)); + } + return genericHash; } bool DescriptorSetLayoutDesc::operator==(const DescriptorSetLayoutDesc &other) const { - return memcmp(&mPackedDescriptorSetLayout, &other.mPackedDescriptorSetLayout, - sizeof(mPackedDescriptorSetLayout)) == 0 && - memcmp(&mImmutableSamplers, &other.mImmutableSamplers, sizeof(mImmutableSamplers)) == 0; + return mDescriptorSetLayoutBindings == other.mDescriptorSetLayoutBindings && + mImmutableSamplers == other.mImmutableSamplers; } void DescriptorSetLayoutDesc::update(uint32_t bindingIndex, @@ -4310,43 +4320,46 @@ void DescriptorSetLayoutDesc::update(uint32_t bindingIndex, VkShaderStageFlags stages, const Sampler *immutableSampler) { - ASSERT(static_cast<size_t>(descriptorType) < std::numeric_limits<uint16_t>::max()); + ASSERT(static_cast<size_t>(descriptorType) < std::numeric_limits<uint8_t>::max()); ASSERT(count < std::numeric_limits<uint16_t>::max()); + ASSERT(bindingIndex < std::numeric_limits<uint16_t>::max()); - PackedDescriptorSetBinding &packedBinding = mPackedDescriptorSetLayout[bindingIndex]; - + PackedDescriptorSetBinding packedBinding = {}; SetBitField(packedBinding.type, descriptorType); SetBitField(packedBinding.count, count); SetBitField(packedBinding.stages, stages); + SetBitField(packedBinding.bindingIndex, bindingIndex); + SetBitField(packedBinding.hasImmutableSampler, 0); if (immutableSampler) { ASSERT(count == 1); - ASSERT(bindingIndex < gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES); - - mImmutableSamplers[bindingIndex] = immutableSampler->getHandle(); + SetBitField(packedBinding.hasImmutableSampler, 1); + mImmutableSamplers.push_back(immutableSampler->getHandle()); } - mValidDescriptorSetLayoutIndexMask.set(bindingIndex, count > 0); + mDescriptorSetLayoutBindings.push_back(std::move(packedBinding)); } void DescriptorSetLayoutDesc::unpackBindings(DescriptorSetLayoutBindingVector *bindings) const { - for (size_t bindingIndex : mValidDescriptorSetLayoutIndexMask) + size_t immutableSamplersIndex = 0; + + // Unpack all valid descriptor set layout bindings + for (const PackedDescriptorSetBinding &packedBinding : mDescriptorSetLayoutBindings) { - const PackedDescriptorSetBinding &packedBinding = mPackedDescriptorSetLayout[bindingIndex]; ASSERT(packedBinding.count != 0); VkDescriptorSetLayoutBinding binding = {}; - binding.binding = static_cast<uint32_t>(bindingIndex); + binding.binding = static_cast<uint32_t>(packedBinding.bindingIndex); binding.descriptorCount = packedBinding.count; binding.descriptorType = static_cast<VkDescriptorType>(packedBinding.type); binding.stageFlags = static_cast<VkShaderStageFlags>(packedBinding.stages); - if (mImmutableSamplers[bindingIndex] != VK_NULL_HANDLE) + + if (packedBinding.hasImmutableSampler) { ASSERT(packedBinding.count == 1); - ASSERT(bindingIndex < gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES); - binding.pImmutableSamplers = &mImmutableSamplers[bindingIndex]; + binding.pImmutableSamplers = &mImmutableSamplers[immutableSamplersIndex++]; } bindings->push_back(binding); @@ -4371,12 +4384,18 @@ PipelineLayoutDesc &PipelineLayoutDesc::operator=(const PipelineLayoutDesc &rhs) size_t PipelineLayoutDesc::hash() const { - return angle::ComputeGenericHash(*this); + size_t genericHash = angle::ComputeGenericHash(mPushConstantRange); + for (const DescriptorSetLayoutDesc &descriptorSetLayoutDesc : mDescriptorSetLayouts) + { + genericHash ^= descriptorSetLayoutDesc.hash(); + } + return genericHash; } bool PipelineLayoutDesc::operator==(const PipelineLayoutDesc &other) const { - return memcmp(this, &other, sizeof(PipelineLayoutDesc)) == 0; + return mPushConstantRange == other.mPushConstantRange && + mDescriptorSetLayouts == other.mDescriptorSetLayouts; } void PipelineLayoutDesc::updateDescriptorSetLayout(DescriptorSetIndex setIndex, diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.h b/src/libANGLE/renderer/vulkan/vk_cache_utils.h index 4db163d9de..b04b604403 100644 --- a/src/libANGLE/renderer/vulkan/vk_cache_utils.h +++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.h @@ -984,17 +984,11 @@ class GraphicsPipelineDesc final constexpr size_t kGraphicsPipelineDescSize = sizeof(GraphicsPipelineDesc); static_assert(kGraphicsPipelineDescSize == kGraphicsPipelineDescSumOfSizes, "Size mismatch"); -constexpr uint32_t kMaxDescriptorSetLayoutBindings = - std::max(gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES, - gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS); - +// Values are based on data recorded here -> https://anglebug.com/8677#c4 +constexpr size_t kDefaultDescriptorSetLayoutBindingsCount = 8; +constexpr size_t kDefaultImmutableSamplerBindingsCount = 1; using DescriptorSetLayoutBindingVector = - angle::FixedVector<VkDescriptorSetLayoutBinding, kMaxDescriptorSetLayoutBindings>; - -// Technically this needs to only be kMaxDescriptorSetLayoutBindings but due to struct padding -// issues round up size to 64. -constexpr uint32_t kMaxDescriptorSetLayoutCount = roundUpPow2(kMaxDescriptorSetLayoutBindings, 64u); -using DescriptorSetLayoutIndexMask = angle::BitSet<kMaxDescriptorSetLayoutCount>; + angle::FastVector<VkDescriptorSetLayoutBinding, kDefaultDescriptorSetLayoutBindingsCount>; // A packed description of a descriptor set layout. Use similarly to RenderPassDesc and // GraphicsPipelineDesc. Currently we only need to differentiate layouts based on sampler and ubo @@ -1018,39 +1012,53 @@ class DescriptorSetLayoutDesc final void unpackBindings(DescriptorSetLayoutBindingVector *bindings) const; - bool empty() const { return !mValidDescriptorSetLayoutIndexMask.any(); } + bool empty() const { return mDescriptorSetLayoutBindings.empty(); } private: // There is a small risk of an issue if the sampler cache is evicted but not the descriptor // cache we would have an invalid handle here. Thus propose follow-up work: // TODO: https://issuetracker.google.com/issues/159156775: Have immutable sampler use serial - struct PackedDescriptorSetBinding + union PackedDescriptorSetBinding { - uint8_t type; // Stores a packed VkDescriptorType descriptorType. - uint8_t stages; // Stores a packed VkShaderStageFlags. - uint16_t count; // Stores a packed uint32_t descriptorCount. + struct + { + uint8_t type; // Stores a packed VkDescriptorType descriptorType. + uint8_t stages; // Stores a packed VkShaderStageFlags. + uint16_t count; // Stores a packed uint32_t descriptorCount + uint16_t bindingIndex; // Stores the binding index + uint16_t hasImmutableSampler; // Whether this binding has an immutable sampler + }; + uint64_t value; + + bool operator==(const PackedDescriptorSetBinding &other) const + { + return value == other.value; + } }; - // 1x 32bit - static_assert(sizeof(PackedDescriptorSetBinding) == 4, "Unexpected size"); - - // This is a compact representation of a descriptor set layout. - std::array<PackedDescriptorSetBinding, kMaxDescriptorSetLayoutBindings> - mPackedDescriptorSetLayout; - gl::ActiveTextureArray<VkSampler> mImmutableSamplers; + // 1x 64bit + static_assert(sizeof(PackedDescriptorSetBinding) == 8, "Unexpected size"); - DescriptorSetLayoutIndexMask mValidDescriptorSetLayoutIndexMask; + angle::FastVector<PackedDescriptorSetBinding, kDefaultDescriptorSetLayoutBindingsCount> + mDescriptorSetLayoutBindings; + angle::FastVector<VkSampler, kDefaultImmutableSamplerBindingsCount> mImmutableSamplers; }; // The following are for caching descriptor set layouts. Limited to max three descriptor set // layouts. This can be extended in the future. -constexpr size_t kMaxDescriptorSetLayouts = 3; +constexpr size_t kMaxDescriptorSetLayouts = ToUnderlying(DescriptorSetIndex::EnumCount); -struct PackedPushConstantRange +union PackedPushConstantRange { - uint8_t offset; - uint8_t size; - uint16_t stageMask; + struct + { + uint8_t offset; + uint8_t size; + uint16_t stageMask; + }; + uint32_t value; + + bool operator==(const PackedPushConstantRange &other) const { return value == other.value; } }; static_assert(sizeof(PackedPushConstantRange) == sizeof(uint32_t), "Unexpected Size"); @@ -2559,6 +2567,10 @@ class DescriptorSetLayoutCache final : angle::NonCopyable const vk::DescriptorSetLayoutDesc &desc, vk::AtomicBindingPointer<vk::DescriptorSetLayout> *descriptorSetLayoutOut); + // Helpers for white box tests + size_t getCacheHitCount() const { return mCacheStats.getHitCount(); } + size_t getCacheMissCount() const { return mCacheStats.getMissCount(); } + private: mutable std::mutex mMutex; std::unordered_map<vk::DescriptorSetLayoutDesc, vk::RefCountedDescriptorSetLayout> mPayload; diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp index 1ad847e359..109bb099f8 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp +++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp @@ -1507,10 +1507,18 @@ void CommandBufferHelperCommon::initializeImpl() mCommandAllocator.init(); } -void CommandBufferHelperCommon::resetImpl() +void CommandBufferHelperCommon::resetImpl(Context *context) { ASSERT(!mAcquireNextImageSemaphore.valid()); mCommandAllocator.resetAllocator(); + + // Clean up event garbage. Note that ImageHelper object may still holding reference count to it, + // so the event itself will not gets destroyed until the last refCount goes away. + if (!mRefCountedEventGarbage.empty()) + { + context->getRenderer()->collectRefCountedEventGarbage(mQueueSerial, + std::move(mRefCountedEventGarbage)); + } } template <class DerivedT> @@ -1693,6 +1701,46 @@ void CommandBufferHelperCommon::updateImageLayoutAndBarrier(Context *context, } } +void CommandBufferHelperCommon::retainImage(Context *context, ImageHelper *image) +{ + image->setQueueSerial(mQueueSerial); + + if (context->getRenderer()->getFeatures().useVkEventForImageBarrier.enabled) + { + image->setCurrentRefCountedEvent(context, mRefCountedEvents); + } +} + +template <typename CommandBufferT> +void CommandBufferHelperCommon::flushSetEventsImpl(Context *context, CommandBufferT *commandBuffer) +{ + if (mRefCountedEvents.mask.none()) + { + return; + } + + // Add VkCmdSetEvent here to track the completion of this renderPass. + for (ImageLayout layout : mRefCountedEvents.mask) + { + RefCountedEvent &refCountedEvent = mRefCountedEvents.map[layout]; + ASSERT(refCountedEvent.valid()); + const ImageMemoryBarrierData &layoutData = + kImageMemoryBarrierData[refCountedEvent.getImageLayout()]; + commandBuffer->setEvent(refCountedEvent.getEvent().getHandle(), + GetImageLayoutDstStageMask(context, layoutData)); + // We no longer need event, so garbage collect it. + mRefCountedEventGarbage.add(&refCountedEvent); + } + mRefCountedEvents.mask.reset(); +} + +template void CommandBufferHelperCommon::flushSetEventsImpl<priv::SecondaryCommandBuffer>( + Context *context, + priv::SecondaryCommandBuffer *commandBuffer); +template void CommandBufferHelperCommon::flushSetEventsImpl<VulkanSecondaryCommandBuffer>( + Context *context, + VulkanSecondaryCommandBuffer *commandBuffer); + void CommandBufferHelperCommon::addCommandDiagnosticsCommon(std::ostringstream *out) { mPipelineBarriers.addDiagnosticsString(*out); @@ -1723,7 +1771,7 @@ angle::Result OutsideRenderPassCommandBufferHelper::reset( Context *context, SecondaryCommandBufferCollector *commandBufferCollector) { - resetImpl(); + resetImpl(context); // Collect/Reset the command buffer commandBufferCollector->collectCommandBuffer(std::move(mCommandBuffer)); @@ -1760,13 +1808,17 @@ void OutsideRenderPassCommandBufferHelper::imageRead(ContextVk *contextVk, { imageReadImpl(contextVk, aspectFlags, imageLayout, image); - if (!contextVk->isRenderPassStartedAndUsesImage(*image)) + if (contextVk->isRenderPassStartedAndUsesImage(*image)) { // Usually an image can only used by a RenderPassCommands or OutsideRenderPassCommands // because the layout will be different, except with image sampled from compute shader. In // this case, the renderPassCommands' read will override the outsideRenderPassCommands' - // read, since its queueSerial must be greater than outsideRP. - image->setQueueSerial(mQueueSerial); + // read, since its queueSerial must be greater than outsideRP. So dont update queueSerial + // here. + } + else + { + retainImage(contextVk, image); } } @@ -1779,7 +1831,33 @@ void OutsideRenderPassCommandBufferHelper::imageWrite(ContextVk *contextVk, ImageHelper *image) { imageWriteImpl(contextVk, level, layerStart, layerCount, aspectFlags, imageLayout, image); - image->setQueueSerial(mQueueSerial); + retainImage(contextVk, image); +} + +void OutsideRenderPassCommandBufferHelper::trackImageWithEvent(Context *context, ImageHelper *image) +{ + image->setCurrentRefCountedEvent(context, mRefCountedEvents); + flushSetEventsImpl(context, &mCommandBuffer); +} + +void OutsideRenderPassCommandBufferHelper::trackImagesWithEvent(Context *context, + ImageHelper *srcImage, + ImageHelper *dstImage) +{ + srcImage->setCurrentRefCountedEvent(context, mRefCountedEvents); + dstImage->setCurrentRefCountedEvent(context, mRefCountedEvents); + flushSetEventsImpl(context, &mCommandBuffer); +} + +void OutsideRenderPassCommandBufferHelper::trackImagesWithEvent(Context *context, + const ImageHelperPtr *images, + size_t count) +{ + for (size_t i = 0; i < count; i++) + { + images[i]->setCurrentRefCountedEvent(context, mRefCountedEvents); + } + flushSetEventsImpl(context, &mCommandBuffer); } angle::Result OutsideRenderPassCommandBufferHelper::flushToPrimary(Context *context, @@ -1805,6 +1883,9 @@ angle::Result OutsideRenderPassCommandBufferHelper::flushToPrimary(Context *cont ASSERT(mIsCommandBufferEnded); mCommandBuffer.executeCommands(&commandsState->primaryCommands); + // Call VkCmdSetEvent to track the completion of this renderPass. + flushSetEventsImpl(context, &commandsState->primaryCommands); + // Restart the command buffer. return reset(context, &commandsState->secondaryCommands); } @@ -1986,7 +2067,7 @@ angle::Result RenderPassCommandBufferHelper::reset( Context *context, SecondaryCommandBufferCollector *commandBufferCollector) { - resetImpl(); + resetImpl(context); for (PackedAttachmentIndex index = kAttachmentIndexZero; index < mColorAttachmentsCount; ++index) @@ -2039,7 +2120,7 @@ void RenderPassCommandBufferHelper::imageRead(ContextVk *contextVk, imageReadImpl(contextVk, aspectFlags, imageLayout, image); // As noted in the header we don't support multiple read layouts for Images. // We allow duplicate uses in the RP to accommodate for normal GL sampler usage. - image->setQueueSerial(mQueueSerial); + retainImage(contextVk, image); } void RenderPassCommandBufferHelper::imageWrite(ContextVk *contextVk, @@ -2051,7 +2132,7 @@ void RenderPassCommandBufferHelper::imageWrite(ContextVk *contextVk, ImageHelper *image) { imageWriteImpl(contextVk, level, layerStart, layerCount, aspectFlags, imageLayout, image); - image->setQueueSerial(mQueueSerial); + retainImage(contextVk, image); } void RenderPassCommandBufferHelper::colorImagesDraw(gl::LevelIndex level, @@ -2571,6 +2652,16 @@ void RenderPassCommandBufferHelper::finalizeDepthStencilImageLayoutAndLoadStore( mDepthAttachment.getImage()->resetRenderPassUsageFlags(); } +void RenderPassCommandBufferHelper::trackImagesWithEvent(Context *context, + const ImageHelperPtr *images, + size_t count) +{ + for (size_t i = 0; i < count; i++) + { + images[i]->setCurrentRefCountedEvent(context, mRefCountedEvents); + } +} + angle::Result RenderPassCommandBufferHelper::beginRenderPass( ContextVk *contextVk, RenderPassFramebuffer &&framebuffer, @@ -2615,40 +2706,55 @@ angle::Result RenderPassCommandBufferHelper::endRenderPass(ContextVk *contextVk) { ANGLE_TRY(endRenderPassCommandBuffer(contextVk)); + // *2 for resolve attachments + angle::FixedVector<ImageHelperPtr, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS << 1> + accessedImages; for (PackedAttachmentIndex index = kAttachmentIndexZero; index < mColorAttachmentsCount; ++index) { if (mColorAttachments[index].getImage() != nullptr) { finalizeColorImageLayoutAndLoadStore(contextVk, index); + accessedImages.push_back(mColorAttachments[index].getImage()); } if (mColorResolveAttachments[index].getImage() != nullptr) { finalizeColorImageLayout(contextVk, mColorResolveAttachments[index].getImage(), index, true); + accessedImages.push_back(mColorResolveAttachments[index].getImage()); } } if (mFragmentShadingRateAtachment.getImage() != nullptr) { finalizeFragmentShadingRateImageLayout(contextVk); + accessedImages.push_back(mFragmentShadingRateAtachment.getImage()); } - if (mDepthStencilAttachmentIndex == kAttachmentIndexInvalid) + if (mDepthStencilAttachmentIndex != kAttachmentIndexInvalid) { - return angle::Result::Continue; + // Do depth stencil layout change and load store optimization. + ASSERT(mDepthAttachment.getImage() == mStencilAttachment.getImage()); + ASSERT(mDepthResolveAttachment.getImage() == mStencilResolveAttachment.getImage()); + if (mDepthAttachment.getImage() != nullptr) + { + finalizeDepthStencilImageLayoutAndLoadStore(contextVk); + accessedImages.push_back(mDepthAttachment.getImage()); + } + if (mDepthResolveAttachment.getImage() != nullptr) + { + finalizeDepthStencilResolveImageLayout(contextVk); + accessedImages.push_back(mDepthResolveAttachment.getImage()); + } } - // Do depth stencil layout change and load store optimization. - ASSERT(mDepthAttachment.getImage() == mStencilAttachment.getImage()); - ASSERT(mDepthResolveAttachment.getImage() == mStencilResolveAttachment.getImage()); - if (mDepthAttachment.getImage() != nullptr) - { - finalizeDepthStencilImageLayoutAndLoadStore(contextVk); - } - if (mDepthResolveAttachment.getImage() != nullptr) + if (contextVk->getRenderer()->getFeatures().useVkEventForImageBarrier.enabled) { - finalizeDepthStencilResolveImageLayout(contextVk); + // Even if there is no layout change, we always have to update event. In case of feedback + // loop, the sampler code should already set the event, which means we will be set it twice + // here. But since they uses the same layout and event is refCounted, it should work just + // fine. + trackImagesWithEvent(contextVk, accessedImages.data(), accessedImages.size()); } return angle::Result::Continue; @@ -2819,6 +2925,9 @@ angle::Result RenderPassCommandBufferHelper::flushToPrimary(Context *context, } primary.endRenderPass(); + // Call VkCmdSetEvent to track the completion of this renderPass. + flushSetEventsImpl(context, &primary); + // Restart the command buffer. return reset(context, &commandsState->secondaryCommands); } @@ -6002,6 +6111,7 @@ void ImageHelper::releaseImage(Renderer *renderer) renderer->onMemoryDealloc(mMemoryAllocationType, mAllocationSize, mMemoryTypeIndex, mVmaAllocation.getHandle()); } + mCurrentEvent.release(renderer->getDevice()); renderer->collectGarbage(mUse, &mImage, &mDeviceMemory, &mVmaAllocation); mViewFormats.clear(); @@ -6477,6 +6587,7 @@ void ImageHelper::destroy(Renderer *renderer) mVmaAllocation.getHandle()); } + mCurrentEvent.release(device); mImage.destroy(device); mDeviceMemory.destroy(device); mVmaAllocation.destroy(renderer->getAllocator()); @@ -7213,6 +7324,26 @@ void ImageHelper::updateLayoutAndBarrier(Context *context, *semaphoreOut = mAcquireNextImageSemaphore.release(); } +void ImageHelper::setCurrentRefCountedEvent(Context *context, ImageLayoutEventMaps &layoutEventMaps) +{ + ASSERT(context->getRenderer()->getFeatures().useVkEventForImageBarrier.enabled); + + // Create the event if we have not yet so. Otherwise just use the already created event. This + // means all images used in the same render pass that has the same layout will be tracked by the + // same event. + if (!layoutEventMaps.map[mCurrentLayout].valid()) + { + layoutEventMaps.map[mCurrentLayout].init(context, mCurrentLayout); + layoutEventMaps.mask.set(mCurrentLayout); + } + + // If there is already an event, release it first. + mCurrentEvent.release(context->getDevice()); + // Copy the event to mCurrentEvent so that we can wait for it in future. This will add extra + // refcount to the underlying VkEvent. + mCurrentEvent = layoutEventMaps.map[mCurrentLayout]; +} + void ImageHelper::clearColor(Context *context, const VkClearColorValue &color, LevelIndex baseMipLevelVk, @@ -7476,6 +7607,8 @@ angle::Result ImageHelper::CopyImageSubData(const gl::Context *context, ANGLE_VK_CHECK(contextVk, false, VK_ERROR_FEATURE_NOT_PRESENT); } + contextVk->trackImagesWithOutsideRenderPassEvent(srcImage, dstImage); + return angle::Result::Continue; } @@ -7587,6 +7720,8 @@ angle::Result ImageHelper::generateMipmapsWithBlit(ContextVk *contextVk, mCurrentShaderReadStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; mCurrentLayout = ImageLayout::FragmentShaderReadOnly; + contextVk->trackImageWithOutsideRenderPassEvent(this); + return angle::Result::Continue; } @@ -9364,6 +9499,12 @@ angle::Result ImageHelper::flushStagedUpdatesImpl(ContextVk *contextVk, *levelUpdates = std::move(updatesToKeep); } + if (commandBuffer != nullptr) + { + // Track completion of this copy operation. + contextVk->trackImageWithOutsideRenderPassEvent(this); + } + return angle::Result::Continue; } @@ -9828,6 +9969,8 @@ angle::Result ImageHelper::copyImageDataToBuffer(ContextVk *contextVk, commandBuffer->copyImageToBuffer(mImage, getCurrentLayout(contextVk), bufferHandle, regionCount, ®ions); + // Track completion of this copy. + contextVk->trackImageWithOutsideRenderPassEvent(this); return angle::Result::Continue; } @@ -10446,12 +10589,15 @@ angle::Result ImageHelper::readPixelsImpl(ContextVk *contextVk, copyCommandBuffer->copyImageToBuffer(src->getImage(), src->getCurrentLayout(contextVk), packBuffer.getBuffer().getHandle(), 1, ®ion); + contextVk->trackImageWithOutsideRenderPassEvent(this); return angle::Result::Continue; } if (canCopyWithComputeForReadPixels(packPixelsParams, readFormat, pixelsOffset)) { - return readPixelsWithCompute(contextVk, src, packPixelsParams, srcOffset, srcExtent, - pixelsOffset, srcSubresource); + ANGLE_TRY(readPixelsWithCompute(contextVk, src, packPixelsParams, srcOffset, srcExtent, + pixelsOffset, srcSubresource)); + contextVk->trackImageWithOutsideRenderPassEvent(this); + return angle::Result::Continue; } } diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h index 1d0a79b7f9..f93c40a1a3 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.h +++ b/src/libANGLE/renderer/vulkan/vk_helpers.h @@ -14,6 +14,7 @@ #include "libANGLE/renderer/vulkan/Suballocation.h" #include "libANGLE/renderer/vulkan/vk_cache_utils.h" #include "libANGLE/renderer/vulkan/vk_format_utils.h" +#include "libANGLE/renderer/vulkan/vk_ref_counted_event.h" #include <functional> @@ -167,6 +168,14 @@ GLenum ConvertImageLayoutToGLImageLayout(ImageLayout imageLayout); VkImageLayout ConvertImageLayoutToVkImageLayout(Context *context, ImageLayout imageLayout); +struct ImageLayoutEventMaps +{ + // The list of RefCountedEvents that have been tracked. The mask is used to accelerate the + // loop of map + angle::PackedEnumMap<ImageLayout, RefCountedEvent> map; + angle::PackedEnumBitSet<ImageLayout, uint64_t> mask; +}; + // A dynamic buffer is conceptually an infinitely long buffer. Each time you write to the buffer, // you will always write to a previously unused portion. After a series of writes, you must flush // the buffer data to the device. Buffer lifetime currently assumes that each new allocation will @@ -1123,6 +1132,7 @@ class PackedClearValuesArray final }; class ImageHelper; +using ImageHelperPtr = ImageHelper *; // Reference to a render pass attachment (color or depth/stencil) alongside render-pass-related // tracking such as when the attachment is last written to or invalidated. This is used to @@ -1322,6 +1332,14 @@ class CommandBufferHelperCommon : angle::NonCopyable writeResource->setWriteQueueSerial(mQueueSerial); } + // Update image with this command buffer's queueSerial. If VkEvent is enabled, image's current + // event is also updated with this command's event. + void retainImage(Context *context, ImageHelper *image); + + // Issue VkCmdSetEvent call for events in this command buffer. + template <typename CommandBufferT> + void flushSetEventsImpl(Context *context, CommandBufferT *commandBuffer); + const QueueSerial &getQueueSerial() const { return mQueueSerial; } void setAcquireNextImageSemaphore(VkSemaphore semaphore) @@ -1340,7 +1358,7 @@ class CommandBufferHelperCommon : angle::NonCopyable void initializeImpl(); - void resetImpl(); + void resetImpl(Context *context); template <class DerivedT> angle::Result attachCommandPoolImpl(Context *context, SecondaryCommandPool *commandPool); @@ -1413,6 +1431,11 @@ class CommandBufferHelperCommon : angle::NonCopyable // Only used for swapChain images Semaphore mAcquireNextImageSemaphore; + + // The list of RefCountedEvents that have be tracked + ImageLayoutEventMaps mRefCountedEvents; + // The list of RefCountedEvents that should be garbage collected when it gets reset. + RefCountedEventGarbageObjects mRefCountedEventGarbage; }; class SecondaryCommandBufferCollector; @@ -1480,6 +1503,14 @@ class OutsideRenderPassCommandBufferHelper final : public CommandBufferHelperCom ImageLayout imageLayout, ImageHelper *image); + // Call SetEvent and have image's current event pointing to it. + void trackImageWithEvent(Context *context, ImageHelper *image); + void trackImagesWithEvent(Context *context, ImageHelper *srcImage, ImageHelper *dstImage); + void trackImagesWithEvent(Context *context, const ImageHelperPtr *images, size_t count); + + // Issues VkCmdSetEvent calls. + void flushSetEvents(Context *context) { flushSetEventsImpl(context, &mCommandBuffer); } + angle::Result flushToPrimary(Context *context, CommandsState *commandsState); void setGLMemoryBarrierIssued() @@ -1864,6 +1895,8 @@ class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon void finalizeDepthStencilImageLayoutAndLoadStore(Context *context); void finalizeFragmentShadingRateImageLayout(Context *context); + void trackImagesWithEvent(Context *context, const ImageHelperPtr *images, size_t count); + // When using Vulkan secondary command buffers, each subpass must be recorded in a separate // command buffer. Currently ANGLE produces render passes with at most 2 subpasses. static constexpr size_t kMaxSubpassCount = 2; @@ -2684,6 +2717,9 @@ class ImageHelper final : public Resource, public angle::Subject size_t getLevelUpdateCount(gl::LevelIndex level) const; + // Create event if needed and record the event in ImageHelper::mCurrentEvent. + void setCurrentRefCountedEvent(Context *context, ImageLayoutEventMaps &layoutEventMaps); + private: ANGLE_ENABLE_STRUCT_PADDING_WARNINGS struct ClearUpdate @@ -3028,6 +3064,10 @@ class ImageHelper final : public Resource, public angle::Subject // The QueueSerial that associated with the last barrier. QueueSerial mBarrierQueueSerial; + // The current refCounted event. When barrier or layout change is needed, we should wait for + // this event. + RefCountedEvent mCurrentEvent; + // Whether ANGLE currently has ownership of this resource or it's released to external. bool mIsReleasedToExternal; diff --git a/src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp new file mode 100644 index 0000000000..22b5a81ec7 --- /dev/null +++ b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp @@ -0,0 +1,58 @@ +// +// Copyright 2024 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RefCountedEvent: +// Manages reference count of VkEvent and its associated functions. +// + +#include "libANGLE/renderer/vulkan/vk_ref_counted_event.h" +#include "libANGLE/renderer/vulkan/vk_helpers.h" +#include "libANGLE/renderer/vulkan/vk_renderer.h" + +namespace rx +{ +namespace vk +{ + +void ReleaseRefcountedEvent(VkDevice device, RefCountedEventAndLayoutHandle atomicRefCountedEvent) +{ + const bool isLastReference = atomicRefCountedEvent->getAndReleaseRef() == 1; + if (isLastReference) + { + atomicRefCountedEvent->get().event.destroy(device); + SafeDelete(atomicRefCountedEvent); + } +} + +void RefCountedEvent::init(Context *context, ImageLayout layout) +{ + ASSERT(mHandle == nullptr); + ASSERT(layout != ImageLayout::Undefined); + + mHandle = new AtomicRefCounted<EventAndLayout>; + VkEventCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; + createInfo.flags = 0; + mHandle->get().event.init(context->getDevice(), createInfo); + mHandle->addRef(); + mHandle->get().imageLayout = layout; +} + +// RefCountedEventGarbageObjects implementation +void RefCountedEventGarbageObjects::add(RefCountedEvent *event) +{ + mGarbageObjects.emplace_back(GetGarbage(event)); +} + +void RefCountedEventGarbageObjects::add(std::vector<RefCountedEvent> *events) +{ + while (!events->empty()) + { + mGarbageObjects.emplace_back(GetGarbage(&events->back())); + events->pop_back(); + } +} +} // namespace vk +} // namespace rx diff --git a/src/libANGLE/renderer/vulkan/vk_ref_counted_event.h b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.h new file mode 100644 index 0000000000..1667dad0b8 --- /dev/null +++ b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.h @@ -0,0 +1,163 @@ +// +// Copyright 2024 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RefCountedEvent: +// Manages reference count of VkEvent and its associated functions. +// + +#ifndef LIBANGLE_RENDERER_VULKAN_REFCOUNTED_EVENT_H_ +#define LIBANGLE_RENDERER_VULKAN_REFCOUNTED_EVENT_H_ + +#include <atomic> +#include <limits> +#include <queue> + +#include "common/PackedEnums.h" +#include "common/debug.h" +#include "libANGLE/renderer/serial_utils.h" +#include "libANGLE/renderer/vulkan/vk_utils.h" +#include "libANGLE/renderer/vulkan/vk_wrapper.h" + +namespace rx +{ +namespace vk +{ +enum class ImageLayout; + +// There are two ways to implement a barrier: Using VkCmdPipelineBarrier or VkCmdWaitEvents. The +// BarrierType enum will be passed around to indicate which barrier caller want to use. +enum class BarrierType +{ + Pipeline, + Event, +}; + +// VkCmdWaitEvents requires srcStageMask must be the bitwise OR of the stageMask parameter used in +// previous calls to vkCmdSetEvent (See VUID-vkCmdWaitEvents-srcStageMask-01158). This mean we must +// keep the record of what stageMask each event has been used in VkCmdSetEvent call so that we can +// retrieve that information when we need to wait for the event. Instead of keeping just stageMask +// here, we keep the ImageLayout for now which gives us more information for debugging. +struct EventAndLayout +{ + bool valid() const { return event.valid(); } + Event event; + ImageLayout imageLayout; +}; + +// The VkCmdSetEvent is called after VkCmdEndRenderPass and all images that used at the given +// pipeline stage (i.e, they have the same stageMask) will be tracked by the same event. This means +// there will be multiple objects pointing to the same event. Events are thus reference counted so +// that we do not destroy it while other objects still referencing to it. +using RefCountedEventAndLayoutHandle = AtomicRefCounted<EventAndLayout> *; + +void ReleaseRefcountedEvent(VkDevice device, RefCountedEventAndLayoutHandle atomicRefCountedEvent); + +// Wrapper for RefCountedEventAndLayoutHandle. +class RefCountedEvent final : public WrappedObject<RefCountedEvent, RefCountedEventAndLayoutHandle> +{ + public: + RefCountedEvent() = default; + + // Move constructor moves reference of the underline object from other to this. + RefCountedEvent(RefCountedEvent &&other) + { + mHandle = other.mHandle; + other.mHandle = nullptr; + } + + // Copy constructor adds reference to the underline object. + RefCountedEvent(const RefCountedEvent &other) + { + mHandle = other.mHandle; + if (mHandle != nullptr) + { + mHandle->addRef(); + } + } + + // Move assignment moves reference of the underline object from other to this. + RefCountedEvent &operator=(RefCountedEvent &&other) + { + ASSERT(!valid()); + std::swap(mHandle, other.mHandle); + return *this; + } + + // Copy assignment adds reference to the underline object. + RefCountedEvent &operator=(const RefCountedEvent &other) + { + ASSERT(!valid()); + ASSERT(other.valid()); + mHandle = other.mHandle; + mHandle->addRef(); + return *this; + } + + // Returns true if both points to the same underline object. + bool operator==(const RefCountedEvent &other) const { return mHandle == other.mHandle; } + + // Create VkEvent and associated it with given layout + void init(Context *context, ImageLayout layout); + + // Release one reference count to the underline Event object and destroy if this is the + // very last reference. + void release(VkDevice device) + { + if (!valid()) + { + return; + } + ReleaseRefcountedEvent(device, mHandle); + mHandle = nullptr; + } + + bool valid() const { return mHandle != nullptr; } + + // Returns the underlying Event object + const Event &getEvent() const + { + ASSERT(valid()); + return mHandle->get().event; + } + + // Returns the ImageLayout associated with the event. + ImageLayout getImageLayout() const + { + ASSERT(valid()); + return mHandle->get().imageLayout; + } +}; + +template <> +struct HandleTypeHelper<RefCountedEvent> +{ + constexpr static HandleType kHandleType = HandleType::RefCountedEvent; +}; + +// This class tracks a vector of RefcountedEvent garbage. For performance reason, instead of +// individually tracking each VkEvent garbage, we collect all events that are accessed in the +// CommandBufferHelper into this class. After we submit the command buffer, we treat this vector of +// events as one garbage object and add it to renderer's garbage list. The garbage clean up will +// decrement the refCount and destroy event only when last refCount goes away. Basically all GPU +// usage will use one refCount and that refCount ensures we never destroy event until GPU is +// finished. +class RefCountedEventGarbageObjects final +{ + public: + // Move event to the garbage list + void add(RefCountedEvent *event); + // Move the vector of events to the garbage list + void add(std::vector<RefCountedEvent> *events); + + bool empty() const { return mGarbageObjects.empty(); } + + GarbageObjects &&release() { return std::move(mGarbageObjects); } + + private: + GarbageObjects mGarbageObjects; +}; +} // namespace vk +} // namespace rx +#endif // LIBANGLE_RENDERER_VULKAN_REFCOUNTED_EVENT_H_ diff --git a/src/libANGLE/renderer/vulkan/vk_renderer.cpp b/src/libANGLE/renderer/vulkan/vk_renderer.cpp index 8b4ef65e27..5386378954 100644 --- a/src/libANGLE/renderer/vulkan/vk_renderer.cpp +++ b/src/libANGLE/renderer/vulkan/vk_renderer.cpp @@ -284,6 +284,8 @@ constexpr const char *kSkippedMessages[] = { // https://issuetracker.google.com/336847261 "VUID-VkImageCreateInfo-pNext-02397", "VUID-vkCmdDraw-None-06550", + // https://anglebug.com/8680 + "VUID-VkSwapchainCreateInfoKHR-presentMode-02839", }; // Validation messages that should be ignored only when VK_EXT_primitive_topology_list_restart is diff --git a/src/libANGLE/renderer/vulkan/vk_renderer.h b/src/libANGLE/renderer/vulkan/vk_renderer.h index 306482126c..dde956b2a5 100644 --- a/src/libANGLE/renderer/vulkan/vk_renderer.h +++ b/src/libANGLE/renderer/vulkan/vk_renderer.h @@ -338,6 +338,14 @@ class Renderer : angle::NonCopyable mSuballocationGarbageList.add(this, std::move(garbage)); } + void collectRefCountedEventGarbage(const QueueSerial &queueSerial, + vk::RefCountedEventGarbageObjects &&garbageObjets) + { + ASSERT(!garbageObjets.empty()); + vk::SharedGarbage garbage(vk::ResourceUse(queueSerial), std::move(garbageObjets.release())); + mSharedGarbageList.add(this, std::move(garbage)); + } + angle::Result getPipelineCache(vk::Context *context, vk::PipelineCacheAccess *pipelineCacheOut); angle::Result mergeIntoPipelineCache(vk::Context *context, const vk::PipelineCache &pipelineCache); diff --git a/src/libANGLE/renderer/vulkan/vk_utils.cpp b/src/libANGLE/renderer/vulkan/vk_utils.cpp index c7fd784619..d49bdccf81 100644 --- a/src/libANGLE/renderer/vulkan/vk_utils.cpp +++ b/src/libANGLE/renderer/vulkan/vk_utils.cpp @@ -16,6 +16,7 @@ #include "libANGLE/renderer/vulkan/DisplayVk.h" #include "libANGLE/renderer/vulkan/android/vk_android_utils.h" #include "libANGLE/renderer/vulkan/vk_mem_alloc_wrapper.h" +#include "libANGLE/renderer/vulkan/vk_ref_counted_event.h" #include "libANGLE/renderer/vulkan/vk_renderer.h" #include "libANGLE/renderer/vulkan/vk_resource.h" @@ -714,6 +715,9 @@ void GarbageObject::destroy(Renderer *renderer) case HandleType::PipelineLayout: vkDestroyPipelineLayout(device, (VkPipelineLayout)mHandle, nullptr); break; + case HandleType::RefCountedEvent: + ReleaseRefcountedEvent(device, (RefCountedEventAndLayoutHandle)mHandle); + break; case HandleType::RenderPass: vkDestroyRenderPass(device, (VkRenderPass)mHandle, nullptr); break; diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h index a4e53d3f1b..1eec37a180 100644 --- a/src/libANGLE/renderer/vulkan/vk_utils.h +++ b/src/libANGLE/renderer/vulkan/vk_utils.h @@ -701,7 +701,9 @@ class AtomicRefCounted : angle::NonCopyable unsigned int getAndReleaseRef() { ASSERT(isReferenced()); - return mRefCount.fetch_sub(1, std::memory_order_relaxed); + // This is used by RefCountedEvent which will decrement in clean up thread, so + // memory_order_acq_rel is needed. + return mRefCount.fetch_sub(1, std::memory_order_acq_rel); } bool isReferenced() const { return mRefCount.load(std::memory_order_relaxed) != 0; } diff --git a/src/libANGLE/renderer/vulkan/vk_wrapper.h b/src/libANGLE/renderer/vulkan/vk_wrapper.h index c0ab78d908..098ac432dd 100644 --- a/src/libANGLE/renderer/vulkan/vk_wrapper.h +++ b/src/libANGLE/renderer/vulkan/vk_wrapper.h @@ -61,6 +61,7 @@ enum class HandleType { Invalid, CommandBuffer, + RefCountedEvent, ANGLE_HANDLE_TYPES_X(ANGLE_COMMA_SEP_FUNC) EnumCount }; diff --git a/src/libANGLE/renderer/vulkan/vulkan_backend.gni b/src/libANGLE/renderer/vulkan/vulkan_backend.gni index 225d31c7e7..89b80cfad1 100644 --- a/src/libANGLE/renderer/vulkan/vulkan_backend.gni +++ b/src/libANGLE/renderer/vulkan/vulkan_backend.gni @@ -98,6 +98,8 @@ vulkan_backend_sources = [ "vk_internal_shaders_autogen.cpp", "vk_internal_shaders_autogen.h", "vk_mandatory_format_support_table_autogen.cpp", + "vk_ref_counted_event.cpp", + "vk_ref_counted_event.h", "vk_renderer.cpp", "vk_renderer.h", "vk_resource.cpp", diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt index 9ed33d0ee5..769939a6d4 100644 --- a/src/tests/angle_end2end_tests_expectations.txt +++ b/src/tests/angle_end2end_tests_expectations.txt @@ -1409,6 +1409,18 @@ b/292285899 PIXEL4ORXL GLES : EGLSurfaceTest.DestroyAndRecreateWhileCurrent/* = 8485 WGPU : RendererTest.SimpleOperation/* = SKIP 8582 WGPU : ClearTest.* = SKIP +// Linux/UHD 630 failures caused by OS/driver upgrade. +8683 LINUX INTEL OPENGL : AtomicCounterBufferTest31.AtomicCounterReadCompute/* = SKIP +8683 LINUX INTEL OPENGL : ClipControlTest.OriginFragCoord/* = SKIP +8683 LINUX INTEL VULKAN : CubeMapTextureTest.SampleCoordinateTransformGrad/* = SKIP +8683 LINUX INTEL OPENGL : EGLMultiContextTest.ReuseUnterminatedDisplay/* = SKIP +8683 LINUX INTEL OPENGL : GLSLTest.FragCoordConsistency/* = SKIP +8683 LINUX INTEL OPENGL : GLSLTest_ES31.StructAndArrayEqualOperator/* = SKIP +8683 LINUX INTEL VULKAN : TransformFeedbackTest.BufferOutOfMemory/* = SKIP +8683 LINUX INTEL OPENGL : WEBGLVideoTextureTest.VerifySamplerVideoWEBGL/* = SKIP +8683 LINUX INTEL OPENGL : WEBGLVideoTextureTest.VerifySamplerVideoWEBGLAsParameter/* = SKIP +8683 LINUX INTEL OPENGL : WEBGLVideoTextureTest.VerifyStateManagerKnowsBindingVideoImage/* = SKIP + // Slow tests, should appear last in this file 5076 : GLSLTest.VerifyMaxVertexUniformVectors* = TIMEOUT 5076 : GLSLTest.VerifyMaxFragmentUniformVectors* = TIMEOUT diff --git a/src/tests/gl_tests/StateChangeTest.cpp b/src/tests/gl_tests/StateChangeTest.cpp index 4222aed967..ed0e19fa00 100644 --- a/src/tests/gl_tests/StateChangeTest.cpp +++ b/src/tests/gl_tests/StateChangeTest.cpp @@ -9609,6 +9609,49 @@ TEST_P(StateChangeTestES3, DepthTestWriteAndFunc) ASSERT_GL_NO_ERROR(); } +// Tests state change for depth test while depth write is enabled +TEST_P(StateChangeTestES3, DepthTestToggleWithDepthWrite) +{ + ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor()); + glUseProgram(program); + + GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform()); + ASSERT_NE(colorLoc, -1); + + const int w = getWindowWidth(); + const int h = getWindowHeight(); + + glClearColor(0, 0, 0, 1); + glClearDepthf(0.5); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Enable depth write, but keep depth test disabled. Internally, depth write may be disabled + // because of the depth test. + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + + // Draw with a different depth, but because depth test is disabled, depth is not actually + // changed. + glUniform4f(colorLoc, 1, 0, 0, 1); + drawQuad(program, essl1_shaders::PositionAttrib(), -0.3f); + + // Enable depth test, but don't change state otherwise. The following draw must change depth. + glEnable(GL_DEPTH_TEST); + + glUniform4f(colorLoc, 0, 1, 0, 1); + drawQuad(program, essl1_shaders::PositionAttrib(), -0.2f); + + // Verify that depth was changed in the last draw call. + EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::green); + + glDepthFunc(GL_GREATER); + glUniform4f(colorLoc, 0, 0, 1, 1); + drawQuad(program, essl1_shaders::PositionAttrib(), -0.1f); + EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::blue); + ASSERT_GL_NO_ERROR(); +} + // Tests state change for stencil test and function TEST_P(StateChangeTestES3, StencilTestAndFunc) { @@ -11007,6 +11050,7 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StateChangeTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND( StateChangeTestES3, ES3_VULKAN().disable(Feature::SupportsIndexTypeUint8), + ES3_VULKAN().disable(Feature::UseDepthWriteEnableDynamicState), ES3_VULKAN() .disable(Feature::SupportsExtendedDynamicState) .disable(Feature::SupportsExtendedDynamicState2), diff --git a/src/tests/gl_tests/VulkanDescriptorSetTest.cpp b/src/tests/gl_tests/VulkanDescriptorSetTest.cpp index 068f4113f6..7ec9b4af43 100644 --- a/src/tests/gl_tests/VulkanDescriptorSetTest.cpp +++ b/src/tests/gl_tests/VulkanDescriptorSetTest.cpp @@ -11,6 +11,7 @@ #include "test_utils/gl_raii.h" #include "libANGLE/Context.h" +#include "libANGLE/Display.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ProgramVk.h" @@ -97,6 +98,117 @@ TEST_P(VulkanDescriptorSetTest, AtomicCounterReadLimitedDescriptorPool) } } +class VulkanDescriptorSetLayoutDescTest : public ANGLETest<> +{ + protected: + VulkanDescriptorSetLayoutDescTest() {} + + void testSetUp() override { ANGLETest::testSetUp(); } + + void testTearDown() override { ANGLETest::testTearDown(); } + + gl::Context *hackContext() const + { + egl::Display *display = static_cast<egl::Display *>(getEGLWindow()->getDisplay()); + gl::ContextID contextID = { + static_cast<GLuint>(reinterpret_cast<uintptr_t>(getEGLWindow()->getContext()))}; + return display->getContext(contextID); + } + + rx::ContextVk *hackANGLE() const + { + // Hack the angle! + return rx::GetImplAs<rx::ContextVk>(hackContext()); + } + + struct DescriptorSetBinding + { + uint32_t bindingIndex; + VkDescriptorType type; + uint32_t bindingCount; + VkShaderStageFlagBits shaderStage; + }; + + const std::array<DescriptorSetBinding, 12> mBindings = {{ + {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT}, + {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT}, + {3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {4, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT}, + {5, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {6, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT}, + {7, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT}, + {9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {10, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_VERTEX_BIT}, + {11, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + }}; + + void updateBindings(const std::vector<uint32_t> &bindingIndices, + rx::vk::DescriptorSetLayoutDesc *desc) + { + for (uint32_t index : bindingIndices) + { + ASSERT(index < mBindings.size()); + const DescriptorSetBinding &binding = mBindings[index]; + desc->update(binding.bindingIndex, binding.type, binding.bindingCount, + binding.shaderStage, nullptr); + } + } + + rx::vk::DescriptorSetLayoutDesc mDescriptorSetLayoutDesc; + rx::DescriptorSetLayoutCache mDescriptorSetLayoutCache; +}; + +// Test basic interaction between DescriptorSetLayoutDesc and DescriptorSetLayoutCache +TEST_P(VulkanDescriptorSetLayoutDescTest, Basic) +{ + const std::vector<uint32_t> bindingsPattern1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + const std::vector<uint32_t> bindingsPattern2 = {0, 1}; + const std::vector<uint32_t> bindingsPattern3 = {0, 1, 5, 9}; + + angle::Result result; + rx::ContextVk *contextVk = hackANGLE(); + rx::vk::AtomicBindingPointer<rx::vk::DescriptorSetLayout> descriptorSetLayout; + + mDescriptorSetLayoutDesc = {}; + updateBindings(bindingsPattern1, &mDescriptorSetLayoutDesc); + result = mDescriptorSetLayoutCache.getDescriptorSetLayout(contextVk, mDescriptorSetLayoutDesc, + &descriptorSetLayout); + EXPECT_EQ(result, angle::Result::Continue); + EXPECT_EQ(mDescriptorSetLayoutCache.getCacheMissCount(), 1u); + + mDescriptorSetLayoutDesc = {}; + updateBindings(bindingsPattern2, &mDescriptorSetLayoutDesc); + result = mDescriptorSetLayoutCache.getDescriptorSetLayout(contextVk, mDescriptorSetLayoutDesc, + &descriptorSetLayout); + EXPECT_EQ(result, angle::Result::Continue); + EXPECT_EQ(mDescriptorSetLayoutCache.getCacheMissCount(), 2u); + + mDescriptorSetLayoutDesc = {}; + updateBindings(bindingsPattern3, &mDescriptorSetLayoutDesc); + size_t reusedDescHash = mDescriptorSetLayoutDesc.hash(); + result = mDescriptorSetLayoutCache.getDescriptorSetLayout(contextVk, mDescriptorSetLayoutDesc, + &descriptorSetLayout); + EXPECT_EQ(result, angle::Result::Continue); + EXPECT_EQ(mDescriptorSetLayoutCache.getCacheMissCount(), 3u); + + rx::vk::DescriptorSetLayoutDesc desc; + updateBindings(bindingsPattern3, &desc); + size_t newDescHash = desc.hash(); + EXPECT_EQ(reusedDescHash, newDescHash); + + result = + mDescriptorSetLayoutCache.getDescriptorSetLayout(contextVk, desc, &descriptorSetLayout); + EXPECT_EQ(result, angle::Result::Continue); + EXPECT_EQ(mDescriptorSetLayoutCache.getCacheHitCount(), 1u); + EXPECT_EQ(mDescriptorSetLayoutCache.getCacheMissCount(), 3u); + + descriptorSetLayout.reset(); + mDescriptorSetLayoutCache.destroy(contextVk->getRenderer()); +} + ANGLE_INSTANTIATE_TEST(VulkanDescriptorSetTest, ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER()); +ANGLE_INSTANTIATE_TEST(VulkanDescriptorSetLayoutDescTest, ES31_VULKAN()); } // namespace diff --git a/src/tests/perf_tests/TracePerfTest.cpp b/src/tests/perf_tests/TracePerfTest.cpp index 7d3dd3ac7a..ccc98b9792 100644 --- a/src/tests/perf_tests/TracePerfTest.cpp +++ b/src/tests/perf_tests/TracePerfTest.cpp @@ -1204,6 +1204,11 @@ TracePerfTest::TracePerfTest(std::unique_ptr<const TracePerfParams> params) { skipTest("TODO: http://anglebug.com/5943 GL_INVALID_ENUM on Windows/Intel"); } + + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } } if (traceNameIs("pokemon_go")) @@ -1335,6 +1340,11 @@ TracePerfTest::TracePerfTest(std::unique_ptr<const TracePerfParams> params) { skipTest("http://anglebug.com/6658 Crashing in Vulkan backend"); } + + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } } if (traceNameIs("township")) @@ -1531,6 +1541,10 @@ TracePerfTest::TracePerfTest(std::unique_ptr<const TracePerfParams> params) if (traceNameIs("minetest")) { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } addExtensionPrerequisite("GL_EXT_texture_format_BGRA8888"); addIntegerPrerequisite(GL_MAX_TEXTURE_UNITS, 4); } @@ -1649,6 +1663,11 @@ TracePerfTest::TracePerfTest(std::unique_ptr<const TracePerfParams> params) if (traceNameIs("street_fighter_iv_ce")) { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + if (mParams->isSwiftshader()) { skipTest("https://anglebug.com/8243 Too slow on Swiftshader (large keyframe)"); @@ -1682,6 +1701,62 @@ TracePerfTest::TracePerfTest(std::unique_ptr<const TracePerfParams> params) addIntegerPrerequisite(GL_MAX_TEXTURE_SIZE, 16383); } + if (traceNameIs("dr_driving")) + { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + } + + if (traceNameIs("plague_inc")) + { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + } + + if (traceNameIs("sonic_the_hedgehog")) + { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + } + + if (traceNameIs("wayward_souls")) + { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + } + + if (traceNameIs("wordscapes")) + { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + } + + if (traceNameIs("zenonia_4")) + { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + } + + if (traceNameIs("zombie_smasher")) + { + if (isIntelLinuxNative) + { + skipTest("https://anglebug.com/8682 fails on newer OS/driver"); + } + } + if (IsGalaxyS22()) { if (traceNameIs("cod_mobile") || traceNameIs("dota_underlords") || diff --git a/third_party/abseil-cpp/CMake/AbseilDll.cmake b/third_party/abseil-cpp/CMake/AbseilDll.cmake index 31b39afe3e..28ba25cd5c 100644 --- a/third_party/abseil-cpp/CMake/AbseilDll.cmake +++ b/third_party/abseil-cpp/CMake/AbseilDll.cmake @@ -65,6 +65,7 @@ set(ABSL_INTERNAL_DLL_FILES "cleanup/internal/cleanup.h" "container/btree_map.h" "container/btree_set.h" + "container/hash_container_defaults.h" "container/fixed_array.h" "container/flat_hash_map.h" "container/flat_hash_set.h" diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index f24402ecdd..35175fe322 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium @@ -4,7 +4,7 @@ URL: https://github.com/abseil/abseil-cpp License: Apache 2.0 License File: LICENSE Version: N/A -Revision: e022c806b07c661932967a2680e32cafdf572895 +Revision: f638e34270be76d15decb08f0e5d48b6f1f1b2c8 Security Critical: yes Shipped: yes diff --git a/third_party/abseil-cpp/absl/base/internal/spinlock.h b/third_party/abseil-cpp/absl/base/internal/spinlock.h index 301c3e3b43..1bb260f46b 100644 --- a/third_party/abseil-cpp/absl/base/internal/spinlock.h +++ b/third_party/abseil-cpp/absl/base/internal/spinlock.h @@ -89,7 +89,8 @@ class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED SpinLock { // acquisition was successful. If the lock was not acquired, false is // returned. If this SpinLock is free at the time of the call, TryLock // will return true with high probability. - inline bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { + ABSL_MUST_USE_RESULT inline bool TryLock() + ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock); bool res = TryLockImpl(); ABSL_TSAN_MUTEX_POST_LOCK( @@ -120,7 +121,7 @@ class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED SpinLock { // Determine if the lock is held. When the lock is held by the invoking // thread, true will always be returned. Intended to be used as // CHECK(lock.IsHeld()). - inline bool IsHeld() const { + ABSL_MUST_USE_RESULT inline bool IsHeld() const { return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0; } diff --git a/third_party/abseil-cpp/absl/container/BUILD.bazel b/third_party/abseil-cpp/absl/container/BUILD.bazel index 2eaece6966..859163f86f 100644 --- a/third_party/abseil-cpp/absl/container/BUILD.bazel +++ b/third_party/abseil-cpp/absl/container/BUILD.bazel @@ -248,7 +248,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":raw_hash_map", "//absl/algorithm:container", "//absl/base:core_headers", @@ -285,7 +285,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":raw_hash_set", "//absl/algorithm:container", "//absl/base:core_headers", @@ -324,7 +324,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":node_slot_policy", ":raw_hash_map", "//absl/algorithm:container", @@ -359,7 +359,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":node_slot_policy", ":raw_hash_set", "//absl/algorithm:container", @@ -433,6 +433,17 @@ cc_library( ], ) +cc_library( + name = "hash_container_defaults", + hdrs = ["hash_container_defaults.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":hash_function_defaults", + "//absl/base:config", + ], +) + cc_test( name = "hash_function_defaults_test", srcs = ["internal/hash_function_defaults_test.cc"], diff --git a/third_party/abseil-cpp/absl/container/BUILD.gn b/third_party/abseil-cpp/absl/container/BUILD.gn index f0ba1252ad..04eb34f948 100644 --- a/third_party/abseil-cpp/absl/container/BUILD.gn +++ b/third_party/abseil-cpp/absl/container/BUILD.gn @@ -98,7 +98,7 @@ absl_source_set("flat_hash_map") { public = [ "flat_hash_map.h" ] deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":raw_hash_map", "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/base:core_headers", @@ -126,7 +126,7 @@ absl_source_set("flat_hash_set") { public = [ "flat_hash_set.h" ] deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":raw_hash_set", "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/base:core_headers", @@ -156,7 +156,7 @@ absl_source_set("node_hash_map") { public = [ "node_hash_map.h" ] deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":node_slot_policy", ":raw_hash_map", "//third_party/abseil-cpp/absl/algorithm:container", @@ -169,7 +169,7 @@ absl_source_set("node_hash_set") { public = [ "node_hash_set.h" ] deps = [ ":container_memory", - ":hash_function_defaults", + ":hash_container_defaults", ":node_slot_policy", ":raw_hash_set", "//third_party/abseil-cpp/absl/algorithm:container", @@ -214,6 +214,15 @@ absl_source_set("hash_function_defaults") { ] } +absl_source_set("hash_container_defaults") { + public = [ "hash_container_defaults.h" ] + visibility = [ "//third_party/abseil-cpp/absl/container:*" ] + deps = [ + ":hash_function_defaults", + "//third_party/abseil-cpp/absl/base:config", + ] +} + absl_test("hash_function_defaults_test") { sources = [ "internal/hash_function_defaults_test.cc" ] deps = [ diff --git a/third_party/abseil-cpp/absl/container/CMakeLists.txt b/third_party/abseil-cpp/absl/container/CMakeLists.txt index 576e83e280..b1f5f9d8a3 100644 --- a/third_party/abseil-cpp/absl/container/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/container/CMakeLists.txt @@ -289,7 +289,7 @@ absl_cc_library( DEPS absl::container_memory absl::core_headers - absl::hash_function_defaults + absl::hash_container_defaults absl::raw_hash_map absl::algorithm_container absl::memory @@ -326,7 +326,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::container_memory - absl::hash_function_defaults + absl::hash_container_defaults absl::raw_hash_set absl::algorithm_container absl::core_headers @@ -368,7 +368,7 @@ absl_cc_library( DEPS absl::container_memory absl::core_headers - absl::hash_function_defaults + absl::hash_container_defaults absl::node_slot_policy absl::raw_hash_map absl::algorithm_container @@ -404,7 +404,7 @@ absl_cc_library( DEPS absl::container_memory absl::core_headers - absl::hash_function_defaults + absl::hash_container_defaults absl::node_slot_policy absl::raw_hash_set absl::algorithm_container @@ -430,6 +430,19 @@ absl_cc_test( GTest::gmock_main ) +absl_cc_library( + NAME + hash_container_defaults + HDRS + "hash_container_defaults.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + absl::hash_function_defaults + PUBLIC +) + # Internal-only target, do not depend on directly. absl_cc_library( NAME diff --git a/third_party/abseil-cpp/absl/container/flat_hash_map.h b/third_party/abseil-cpp/absl/container/flat_hash_map.h index a33c794fad..aa2c5c8c0c 100644 --- a/third_party/abseil-cpp/absl/container/flat_hash_map.h +++ b/third_party/abseil-cpp/absl/container/flat_hash_map.h @@ -31,16 +31,15 @@ #define ABSL_CONTAINER_FLAT_HASH_MAP_H_ #include <cstddef> -#include <new> +#include <memory> #include <type_traits> #include <utility> #include "absl/algorithm/container.h" #include "absl/base/macros.h" +#include "absl/container/hash_container_defaults.h" #include "absl/container/internal/container_memory.h" -#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export -#include "absl/memory/memory.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -119,9 +118,8 @@ struct FlatHashMapPolicy; // if (result != ducks.end()) { // std::cout << "Result: " << result->second << std::endl; // } -template <class K, class V, - class Hash = absl::container_internal::hash_default_hash<K>, - class Eq = absl::container_internal::hash_default_eq<K>, +template <class K, class V, class Hash = DefaultHashContainerHash<K>, + class Eq = DefaultHashContainerEq<K>, class Allocator = std::allocator<std::pair<const K, V>>> class flat_hash_map : public absl::container_internal::raw_hash_map< absl::container_internal::FlatHashMapPolicy<K, V>, diff --git a/third_party/abseil-cpp/absl/container/flat_hash_set.h b/third_party/abseil-cpp/absl/container/flat_hash_set.h index 5f72f9549e..e558b071c3 100644 --- a/third_party/abseil-cpp/absl/container/flat_hash_set.h +++ b/third_party/abseil-cpp/absl/container/flat_hash_set.h @@ -36,8 +36,8 @@ #include "absl/algorithm/container.h" #include "absl/base/macros.h" +#include "absl/container/hash_container_defaults.h" #include "absl/container/internal/container_memory.h" -#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export #include "absl/memory/memory.h" @@ -114,8 +114,8 @@ struct FlatHashSetPolicy; // if (ducks.contains("dewey")) { // std::cout << "We found dewey!" << std::endl; // } -template <class T, class Hash = absl::container_internal::hash_default_hash<T>, - class Eq = absl::container_internal::hash_default_eq<T>, +template <class T, class Hash = DefaultHashContainerHash<T>, + class Eq = DefaultHashContainerEq<T>, class Allocator = std::allocator<T>> class flat_hash_set : public absl::container_internal::raw_hash_set< diff --git a/third_party/abseil-cpp/absl/container/hash_container_defaults.h b/third_party/abseil-cpp/absl/container/hash_container_defaults.h new file mode 100644 index 0000000000..eb944a7c81 --- /dev/null +++ b/third_party/abseil-cpp/absl/container/hash_container_defaults.h @@ -0,0 +1,45 @@ +// Copyright 2024 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_CONTAINER_HASH_CONTAINER_DEFAULTS_H_ +#define ABSL_CONTAINER_HASH_CONTAINER_DEFAULTS_H_ + +#include "absl/base/config.h" +#include "absl/container/internal/hash_function_defaults.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// DefaultHashContainerHash is a convenience alias for the functor that is used +// by default by Abseil hash-based (unordered) containers for hashing when +// `Hash` type argument is not explicitly specified. +// +// This type alias can be used by generic code that wants to provide more +// flexibility for defining underlying containers. +template <typename T> +using DefaultHashContainerHash = absl::container_internal::hash_default_hash<T>; + +// DefaultHashContainerEq is a convenience alias for the functor that is used by +// default by Abseil hash-based (unordered) containers for equality check when +// `Eq` type argument is not explicitly specified. +// +// This type alias can be used by generic code that wants to provide more +// flexibility for defining underlying containers. +template <typename T> +using DefaultHashContainerEq = absl::container_internal::hash_default_eq<T>; + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_CONTAINER_HASH_CONTAINER_DEFAULTS_H_ diff --git a/third_party/abseil-cpp/absl/container/node_hash_map.h b/third_party/abseil-cpp/absl/container/node_hash_map.h index cb41543c93..31beb1daa7 100644 --- a/third_party/abseil-cpp/absl/container/node_hash_map.h +++ b/third_party/abseil-cpp/absl/container/node_hash_map.h @@ -37,14 +37,13 @@ #define ABSL_CONTAINER_NODE_HASH_MAP_H_ #include <cstddef> -#include <tuple> +#include <memory> #include <type_traits> #include <utility> #include "absl/algorithm/container.h" -#include "absl/base/macros.h" +#include "absl/container/hash_container_defaults.h" #include "absl/container/internal/container_memory.h" -#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/node_slot_policy.h" #include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export #include "absl/memory/memory.h" @@ -114,9 +113,8 @@ class NodeHashMapPolicy; // if (result != ducks.end()) { // std::cout << "Result: " << result->second << std::endl; // } -template <class Key, class Value, - class Hash = absl::container_internal::hash_default_hash<Key>, - class Eq = absl::container_internal::hash_default_eq<Key>, +template <class Key, class Value, class Hash = DefaultHashContainerHash<Key>, + class Eq = DefaultHashContainerEq<Key>, class Alloc = std::allocator<std::pair<const Key, Value>>> class node_hash_map : public absl::container_internal::raw_hash_map< diff --git a/third_party/abseil-cpp/absl/container/node_hash_set.h b/third_party/abseil-cpp/absl/container/node_hash_set.h index 8cc4b62407..deeb49ce53 100644 --- a/third_party/abseil-cpp/absl/container/node_hash_set.h +++ b/third_party/abseil-cpp/absl/container/node_hash_set.h @@ -36,12 +36,12 @@ #define ABSL_CONTAINER_NODE_HASH_SET_H_ #include <cstddef> +#include <memory> #include <type_traits> #include "absl/algorithm/container.h" -#include "absl/base/macros.h" +#include "absl/container/hash_container_defaults.h" #include "absl/container/internal/container_memory.h" -#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/node_slot_policy.h" #include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export #include "absl/memory/memory.h" @@ -109,9 +109,8 @@ struct NodeHashSetPolicy; // if (ducks.contains("dewey")) { // std::cout << "We found dewey!" << std::endl; // } -template <class T, class Hash = absl::container_internal::hash_default_hash<T>, - class Eq = absl::container_internal::hash_default_eq<T>, - class Alloc = std::allocator<T>> +template <class T, class Hash = DefaultHashContainerHash<T>, + class Eq = DefaultHashContainerEq<T>, class Alloc = std::allocator<T>> class node_hash_set : public absl::container_internal::raw_hash_set< absl::container_internal::NodeHashSetPolicy<T>, Hash, Eq, Alloc> { diff --git a/third_party/abseil-cpp/absl/functional/any_invocable.h b/third_party/abseil-cpp/absl/functional/any_invocable.h index 68d882532e..176077ae1b 100644 --- a/third_party/abseil-cpp/absl/functional/any_invocable.h +++ b/third_party/abseil-cpp/absl/functional/any_invocable.h @@ -98,9 +98,9 @@ ABSL_NAMESPACE_BEGIN // `AnyInvocable` also properly respects `const` qualifiers, reference // qualifiers, and the `noexcept` specification (only in C++ 17 and beyond) as // part of the user-specified function type (e.g. -// `AnyInvocable<void()&& const noexcept>`). These qualifiers will be applied to -// the `AnyInvocable` object's `operator()`, and the underlying invocable must -// be compatible with those qualifiers. +// `AnyInvocable<void() const && noexcept>`). These qualifiers will be applied +// to the `AnyInvocable` object's `operator()`, and the underlying invocable +// must be compatible with those qualifiers. // // Comparison of const and non-const function types: // diff --git a/third_party/abseil-cpp/absl/strings/BUILD.bazel b/third_party/abseil-cpp/absl/strings/BUILD.bazel index d93a78a962..48793edddb 100644 --- a/third_party/abseil-cpp/absl/strings/BUILD.bazel +++ b/third_party/abseil-cpp/absl/strings/BUILD.bazel @@ -917,6 +917,7 @@ cc_test( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/base:no_destructor", "//absl/container:fixed_array", "//absl/functional:function_ref", "//absl/hash", diff --git a/third_party/abseil-cpp/absl/strings/BUILD.gn b/third_party/abseil-cpp/absl/strings/BUILD.gn index f0ad679d41..9ac0db9b2f 100644 --- a/third_party/abseil-cpp/absl/strings/BUILD.gn +++ b/third_party/abseil-cpp/absl/strings/BUILD.gn @@ -611,6 +611,7 @@ absl_source_set("cordz_test_helpers") { # "//third_party/abseil-cpp/absl/base:config", # "//third_party/abseil-cpp/absl/base:core_headers", # "//third_party/abseil-cpp/absl/base:endian", +# "//third_party/abseil-cpp/absl/base:no_destructor", # "//third_party/abseil-cpp/absl/container:fixed_array", # "//third_party/abseil-cpp/absl/functional:function_ref", # "//third_party/abseil-cpp/absl/hash", diff --git a/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/third_party/abseil-cpp/absl/strings/CMakeLists.txt index 53e8518821..99156cfeea 100644 --- a/third_party/abseil-cpp/absl/strings/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/strings/CMakeLists.txt @@ -1075,6 +1075,7 @@ absl_cc_test( absl::function_ref absl::hash absl::hash_testing + absl::no_destructor absl::log absl::optional absl::random_random diff --git a/third_party/abseil-cpp/absl/strings/cord.cc b/third_party/abseil-cpp/absl/strings/cord.cc index 025904c10e..f0f4f31ac5 100644 --- a/third_party/abseil-cpp/absl/strings/cord.cc +++ b/third_party/abseil-cpp/absl/strings/cord.cc @@ -75,7 +75,7 @@ using ::absl::cord_internal::kMinFlatLength; using ::absl::cord_internal::kInlinedVectorSize; using ::absl::cord_internal::kMaxBytesToCopy; -static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data, +static void DumpNode(absl::Nonnull<CordRep*> nonnull_rep, bool include_data, absl::Nonnull<std::ostream*> os, int indent = 0); static bool VerifyNode(absl::Nonnull<CordRep*> root, absl::Nonnull<CordRep*> start_node); @@ -1457,12 +1457,13 @@ absl::string_view Cord::FlattenSlowPath() { } } -static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data, +static void DumpNode(absl::Nonnull<CordRep*> nonnull_rep, bool include_data, absl::Nonnull<std::ostream*> os, int indent) { + CordRep* rep = nonnull_rep; const int kIndentStep = 1; for (;;) { - *os << std::setw(3) << rep->refcount.Get(); - *os << " " << std::setw(7) << rep->length; + *os << std::setw(3) << (rep == nullptr ? 0 : rep->refcount.Get()); + *os << " " << std::setw(7) << (rep == nullptr ? 0 : rep->length); *os << " ["; if (include_data) *os << static_cast<void*>(rep); *os << "]"; diff --git a/third_party/abseil-cpp/absl/strings/cord_test.cc b/third_party/abseil-cpp/absl/strings/cord_test.cc index 658ad55bcc..ad96aafa5d 100644 --- a/third_party/abseil-cpp/absl/strings/cord_test.cc +++ b/third_party/abseil-cpp/absl/strings/cord_test.cc @@ -38,6 +38,7 @@ #include "absl/base/config.h" #include "absl/base/internal/endian.h" #include "absl/base/macros.h" +#include "absl/base/no_destructor.h" #include "absl/base/options.h" #include "absl/container/fixed_array.h" #include "absl/functional/function_ref.h" @@ -2796,34 +2797,15 @@ class AfterExitCordTester { absl::string_view expected_; }; -// Deliberately prevents the destructor for an absl::Cord from running. The cord -// is accessible via the cord member during the lifetime of the CordLeaker. -// After the CordLeaker is destroyed, pointers to the cord will remain valid -// until the CordLeaker's memory is deallocated. -struct CordLeaker { - union { - absl::Cord cord; - }; - - template <typename Str> - constexpr explicit CordLeaker(const Str& str) : cord(str) {} - - ~CordLeaker() { - // Don't do anything, including running cord's destructor. (cord's - // destructor won't run automatically because cord is hidden inside a - // union.) - } -}; - template <typename Str> -void TestConstinitConstructor(Str) { +void TestAfterExit(Str) { const auto expected = Str::value; // Defined before `cord` to be destroyed after it. static AfterExitCordTester exit_tester; // NOLINT - ABSL_CONST_INIT static CordLeaker cord_leaker(Str{}); // NOLINT + static absl::NoDestructor<absl::Cord> cord_leaker(Str{}); // cord_leaker is static, so this reference will remain valid through the end // of program execution. - static absl::Cord& cord = cord_leaker.cord; + static absl::Cord& cord = *cord_leaker; static bool init_exit_tester = exit_tester.Set(&cord, expected); (void)init_exit_tester; @@ -2875,11 +2857,9 @@ struct LongView { }; -TEST_P(CordTest, ConstinitConstructor) { - TestConstinitConstructor( - absl::strings_internal::MakeStringConstant(ShortView{})); - TestConstinitConstructor( - absl::strings_internal::MakeStringConstant(LongView{})); +TEST_P(CordTest, AfterExit) { + TestAfterExit(absl::strings_internal::MakeStringConstant(ShortView{})); + TestAfterExit(absl::strings_internal::MakeStringConstant(LongView{})); } namespace { diff --git a/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc b/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc index 3e761373f5..17c3607d7c 100644 --- a/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc +++ b/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc @@ -785,8 +785,7 @@ TEST_F(FormatConvertTest, Uint128) { } template <typename Floating> -void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats, - const std::set<Floating> &skip_verify) { +void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) { const NativePrintfTraits &native_traits = VerifyNativeImplementation(); // Reserve the space to ensure we don't allocate memory in the output itself. std::string str_format_result; @@ -834,6 +833,9 @@ void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats, AppendPack(&str_format_result, format, absl::MakeSpan(args)); } + // For values that we know won't match the standard library + // implementation we skip verification, but still run the algorithm to + // catch asserts/sanitizer bugs. #ifdef _MSC_VER // MSVC has a different rounding policy than us so we can't test our // implementation against the native one there. @@ -842,8 +844,7 @@ void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats, // Apple formats NaN differently (+nan) vs. (nan) if (std::isnan(d)) continue; #endif - if (string_printf_result != str_format_result && - skip_verify.find(d) == skip_verify.end()) { + if (string_printf_result != str_format_result) { // We use ASSERT_EQ here because failures are usually correlated and a // bug would print way too many failed expectations causing the test // to time out. @@ -904,14 +905,10 @@ TEST_F(FormatConvertTest, Float) { }); floats.erase(std::unique(floats.begin(), floats.end()), floats.end()); - TestWithMultipleFormatsHelper(floats, {}); + TestWithMultipleFormatsHelper(floats); } TEST_F(FormatConvertTest, Double) { - // For values that we know won't match the standard library implementation we - // skip verification, but still run the algorithm to catch asserts/sanitizer - // bugs. - std::set<double> skip_verify; std::vector<double> doubles = {0.0, -0.0, .99999999999999, @@ -959,7 +956,7 @@ TEST_F(FormatConvertTest, Double) { }); doubles.erase(std::unique(doubles.begin(), doubles.end()), doubles.end()); - TestWithMultipleFormatsHelper(doubles, skip_verify); + TestWithMultipleFormatsHelper(doubles); } TEST_F(FormatConvertTest, DoubleRound) { diff --git a/third_party/abseil-cpp/absl/synchronization/mutex.h b/third_party/abseil-cpp/absl/synchronization/mutex.h index 9505225259..be3f1f56bb 100644 --- a/third_party/abseil-cpp/absl/synchronization/mutex.h +++ b/third_party/abseil-cpp/absl/synchronization/mutex.h @@ -190,7 +190,7 @@ class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED Mutex { // If the mutex can be acquired without blocking, does so exclusively and // returns `true`. Otherwise, returns `false`. Returns `true` with high // probability if the `Mutex` was free. - bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true); + ABSL_MUST_USE_RESULT bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true); // Mutex::AssertHeld() // @@ -255,7 +255,7 @@ class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED Mutex { // If the mutex can be acquired without blocking, acquires this mutex for // shared access and returns `true`. Otherwise, returns `false`. Returns // `true` with high probability if the `Mutex` was free or shared. - bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true); + ABSL_MUST_USE_RESULT bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true); // Mutex::AssertReaderHeld() // @@ -281,7 +281,8 @@ class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED Mutex { void WriterUnlock() ABSL_UNLOCK_FUNCTION() { this->Unlock(); } - bool WriterTryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { + ABSL_MUST_USE_RESULT bool WriterTryLock() + ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { return this->TryLock(); } diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc index d01461222e..b509402783 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if defined(_WIN32) || defined(_WIN64) +#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_WIN32) #define _CRT_SECURE_NO_WARNINGS 1 #endif |