aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore9
-rw-r--r--.gitmodules44
-rw-r--r--.gn2
-rw-r--r--BUILD.gn12
-rw-r--r--DEPS160
-rw-r--r--OWNERS9
m---------build0
-rw-r--r--build_overrides/angle.gni6
-rw-r--r--build_overrides/dawn.gni10
-rw-r--r--build_overrides/glslang.gni2
-rw-r--r--build_overrides/spirv_tools.gni2
-rw-r--r--build_overrides/tint.gni4
-rw-r--r--build_overrides/vulkan_validation_layers.gni9
m---------buildtools0
-rw-r--r--extensions/EGL_ANGLE_device_d3d11.txt89
-rw-r--r--extensions/EGL_ANGLE_device_d3d9.txt89
-rw-r--r--gni/angle.gni11
-rw-r--r--infra/config/generated/luci-milo.cfg8
-rwxr-xr-xinfra/config/main.star1
-rw-r--r--infra/specs/angle.json219
-rw-r--r--infra/specs/angle_mb_config.pyl8
-rw-r--r--infra/specs/mixins.pyl4
-rw-r--r--infra/specs/waterfalls.pyl1
-rw-r--r--scripts/code_generation_hashes/Extension_files.json4
-rw-r--r--scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json8
-rw-r--r--scripts/code_generation_hashes/GL_EGL_WGL_loader.json4
-rw-r--r--scripts/code_generation_hashes/GL_EGL_entry_points.json8
-rw-r--r--scripts/code_generation_hashes/GLenum_value_to_string_map.json2
-rw-r--r--scripts/code_generation_hashes/SPIR-V_helpers.json8
-rw-r--r--scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json4
-rw-r--r--scripts/code_generation_hashes/interpreter_utils.json4
-rw-r--r--scripts/code_generation_hashes/proc_table.json4
-rw-r--r--scripts/egl_angle_ext.xml10
-rwxr-xr-xscripts/export_targets.py2
-rw-r--r--scripts/generate_android_bp.py37
-rwxr-xr-xscripts/generate_entry_points.py9
-rw-r--r--scripts/registry_xml.py2
-rwxr-xr-xscripts/roll_aosp.sh18
-rw-r--r--src/common/PackedEnums.h6
-rw-r--r--src/common/SimpleMutex.h7
-rw-r--r--src/common/SimpleMutex_unittest.cpp6
-rw-r--r--src/common/mathutil.cpp2
-rwxr-xr-xsrc/common/spirv/gen_spirv_builder_and_parser.py12
-rw-r--r--src/common/spirv/spirv_instruction_builder_autogen.cpp6
-rw-r--r--src/common/spirv/spirv_instruction_builder_autogen.h2
-rw-r--r--src/common/spirv/spirv_types.h5
-rw-r--r--src/compiler/translator/hlsl/ResourcesHLSL.h4
-rw-r--r--src/compiler/translator/msl/IdGen.cpp20
-rw-r--r--src/compiler/translator/spirv/BuildSPIRV.cpp2
-rw-r--r--src/compiler/translator/tree_ops/msl/SeparateCompoundExpressions.cpp2
-rw-r--r--src/image_util/loadimage_etc.cpp2
-rw-r--r--src/libANGLE/Buffer.cpp7
-rw-r--r--src/libANGLE/Buffer.h2
-rw-r--r--src/libANGLE/Caps.cpp2
-rw-r--r--src/libANGLE/Caps.h6
-rw-r--r--src/libANGLE/Context.cpp14
-rw-r--r--src/libANGLE/Device.cpp9
-rw-r--r--src/libANGLE/Device.h1
-rw-r--r--src/libANGLE/Display.cpp33
-rw-r--r--src/libANGLE/ProgramExecutable.cpp8
-rw-r--r--src/libANGLE/ProgramExecutable.h4
-rw-r--r--src/libANGLE/ProgramPipeline.cpp34
-rw-r--r--src/libANGLE/ProgramPipeline.h6
-rw-r--r--src/libANGLE/RefCountObject.h13
-rw-r--r--src/libANGLE/ResourceManager.cpp3
-rw-r--r--src/libANGLE/ResourceMap.h155
-rw-r--r--src/libANGLE/ResourceMap_unittest.cpp231
-rw-r--r--src/libANGLE/State.cpp2
-rw-r--r--src/libANGLE/State.h60
-rw-r--r--src/libANGLE/Texture.cpp6
-rw-r--r--src/libANGLE/renderer/DeviceImpl.h1
-rw-r--r--src/libANGLE/renderer/DisplayImpl.cpp5
-rw-r--r--src/libANGLE/renderer/d3d/DeviceD3D.cpp84
-rw-r--r--src/libANGLE/renderer/d3d/DisplayD3D.cpp3
-rw-r--r--src/libANGLE/renderer/d3d/RendererD3D.cpp1
-rw-r--r--src/libANGLE/renderer/d3d/RendererD3D.h1
-rw-r--r--src/libANGLE/renderer/d3d/TextureD3D.cpp2
-rw-r--r--src/libANGLE/renderer/d3d/d3d11/Device11.cpp63
-rw-r--r--src/libANGLE/renderer/d3d/d3d11/Device11.h (renamed from src/libANGLE/renderer/d3d/DeviceD3D.h)25
-rw-r--r--src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp14
-rw-r--r--src/libANGLE/renderer/d3d/d3d9/Device9.cpp41
-rw-r--r--src/libANGLE/renderer/d3d/d3d9/Device9.h36
-rw-r--r--src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp4
-rw-r--r--src/libANGLE/renderer/d3d/d3d_backend.gni6
-rw-r--r--src/libANGLE/renderer/driver_utils.cpp24
-rw-r--r--src/libANGLE/renderer/driver_utils.h5
-rw-r--r--src/libANGLE/renderer/gl/cgl/DeviceCGL.cpp5
-rw-r--r--src/libANGLE/renderer/gl/cgl/DeviceCGL.h1
-rw-r--r--src/libANGLE/renderer/gl/eagl/DeviceEAGL.cpp5
-rw-r--r--src/libANGLE/renderer/gl/eagl/DeviceEAGL.h1
-rw-r--r--src/libANGLE/renderer/gl/egl/DeviceEGL.cpp6
-rw-r--r--src/libANGLE/renderer/gl/egl/DeviceEGL.h1
-rw-r--r--src/libANGLE/renderer/gl/egl/SyncEGL.cpp8
-rw-r--r--src/libANGLE/renderer/metal/DeviceMtl.h1
-rw-r--r--src/libANGLE/renderer/metal/DeviceMtl.mm8
-rw-r--r--src/libANGLE/renderer/metal/TextureMtl.mm15
-rw-r--r--src/libANGLE/renderer/metal/VertexArrayMtl.mm6
-rw-r--r--src/libANGLE/renderer/metal/mtl_resources.mm3
-rw-r--r--src/libANGLE/renderer/null/DeviceNULL.cpp5
-rw-r--r--src/libANGLE/renderer/null/DeviceNULL.h1
-rw-r--r--src/libANGLE/renderer/vulkan/BUILD.gn6
-rw-r--r--src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp2
-rw-r--r--src/libANGLE/renderer/vulkan/CLContextVk.cpp4
-rw-r--r--src/libANGLE/renderer/vulkan/CommandProcessor.cpp139
-rw-r--r--src/libANGLE/renderer/vulkan/CommandProcessor.h83
-rw-r--r--src/libANGLE/renderer/vulkan/ContextVk.cpp38
-rw-r--r--src/libANGLE/renderer/vulkan/ContextVk.h6
-rw-r--r--src/libANGLE/renderer/vulkan/DeviceVk.cpp5
-rw-r--r--src/libANGLE/renderer/vulkan/DeviceVk.h1
-rw-r--r--src/libANGLE/renderer/vulkan/DisplayVk.cpp2
-rw-r--r--src/libANGLE/renderer/vulkan/MemoryObjectVk.cpp2
-rw-r--r--src/libANGLE/renderer/vulkan/RenderbufferVk.cpp5
-rw-r--r--src/libANGLE/renderer/vulkan/SemaphoreVk.cpp19
-rw-r--r--src/libANGLE/renderer/vulkan/ShareGroupVk.cpp2
-rw-r--r--src/libANGLE/renderer/vulkan/ShareGroupVk.h21
-rw-r--r--src/libANGLE/renderer/vulkan/TextureVk.cpp7
-rw-r--r--src/libANGLE/renderer/vulkan/UtilsVk.cpp2
-rw-r--r--src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp2
-rw-r--r--src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py2
-rw-r--r--src/libANGLE/renderer/vulkan/linux/DmaBufImageSiblingVkLinux.cpp2
-rw-r--r--src/libANGLE/renderer/vulkan/vk_helpers.cpp241
-rw-r--r--src/libANGLE/renderer/vulkan/vk_helpers.h48
-rw-r--r--src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp256
-rw-r--r--src/libANGLE/renderer/vulkan/vk_ref_counted_event.h251
-rw-r--r--src/libANGLE/renderer/vulkan/vk_renderer.cpp82
-rw-r--r--src/libANGLE/renderer/vulkan/vk_renderer.h26
-rw-r--r--src/libANGLE/renderer/vulkan/vk_utils.cpp4
-rw-r--r--src/libANGLE/renderer/vulkan/vk_utils.h80
-rw-r--r--src/libANGLE/renderer/wgpu/DeviceWgpu.cpp5
-rw-r--r--src/libANGLE/renderer/wgpu/DeviceWgpu.h1
-rw-r--r--src/libANGLE/validationEGL.cpp8
-rw-r--r--src/libGLESv2/entry_points_gles_2_0_autogen.cpp2
-rw-r--r--src/tests/angle_end2end_tests_expectations.txt4
-rw-r--r--src/tests/deqp_support/deqp.gni12
-rw-r--r--src/tests/deqp_support/deqp_gl46_test_expectations.txt1
-rw-r--r--src/tests/deqp_support/deqp_gles2_test_expectations.txt9
-rw-r--r--src/tests/deqp_support/deqp_gles31_test_expectations.txt17
-rw-r--r--src/tests/deqp_support/deqp_gles3_test_expectations.txt4
-rw-r--r--src/tests/deqp_support/deqp_khr_gles32_test_expectations.txt5
-rw-r--r--src/tests/deqp_support/deqp_khr_gles3_test_expectations.txt15
-rw-r--r--src/tests/egl_tests/EGLDeviceTest.cpp57
-rw-r--r--src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp67
-rw-r--r--src/tests/egl_tests/EGLSyncTest.cpp12
-rw-r--r--src/tests/gl_tests/GLSLTest.cpp66
-rw-r--r--src/tests/gl_tests/MultithreadingTest.cpp248
-rw-r--r--src/tests/gl_tests/RobustResourceInitTest.cpp19
-rw-r--r--src/tests/gl_tests/ShaderAlgorithmTest.cpp2
-rw-r--r--src/tests/gl_tests/StateChangeTest.cpp16
-rw-r--r--src/tests/gl_tests/VertexAttributeTest.cpp37
-rw-r--r--src/tests/gl_tests/WebGLCompatibilityTest.cpp72
-rw-r--r--src/tests/perf_tests/TracePerfTest.cpp10
m---------testing0
m---------third_party/SwiftShader0
m---------third_party/VK-GL-CTS/src0
m---------third_party/abseil-cpp0
m---------third_party/android_deps0
m---------third_party/catapult0
-rw-r--r--third_party/clspv/BUILD.gn4
m---------third_party/dawn0
m---------third_party/depot_tools0
-rw-r--r--third_party/flatbuffers/DIR_METADATA5
-rw-r--r--third_party/flatbuffers/README.chromium4
-rw-r--r--third_party/flatbuffers/generated/tests/alignment_test_generated.h4
-rw-r--r--third_party/flatbuffers/generated/tests/arrays_test_generated.h4
m---------third_party/flatbuffers/src0
-rw-r--r--third_party/glslang/DIR_METADATA4
-rw-r--r--third_party/glslang/LICENSE25
-rw-r--r--third_party/glslang/README.chromium16
m---------third_party/glslang/src0
m---------third_party/libc++/src0
m---------third_party/libc++abi/src0
m---------third_party/libunwind/src0
-rw-r--r--third_party/spirv-cross/DIR_METADATA4
-rw-r--r--third_party/spirv-cross/README.chromium13
m---------third_party/spirv-cross/src0
-rw-r--r--third_party/spirv-headers/DIR_METADATA4
-rw-r--r--third_party/spirv-headers/LICENSE202
-rw-r--r--third_party/spirv-headers/README.chromium15
m---------third_party/spirv-headers/src0
-rw-r--r--third_party/spirv-tools/DIR_METADATA5
-rw-r--r--third_party/spirv-tools/LICENSE202
-rw-r--r--third_party/spirv-tools/README.chromium16
m---------third_party/spirv-tools/src0
m---------third_party/vulkan-deps0
-rw-r--r--third_party/vulkan-headers/DIR_METADATA4
-rw-r--r--third_party/vulkan-headers/LICENSE.txt202
-rw-r--r--third_party/vulkan-headers/README.chromium12
m---------third_party/vulkan-headers/src0
-rw-r--r--third_party/vulkan-loader/README.chromium16
m---------third_party/vulkan-loader/src0
-rw-r--r--third_party/vulkan-tools/README.chromium15
m---------third_party/vulkan-tools/src0
-rw-r--r--third_party/vulkan-utility-libraries/README.chromium15
m---------third_party/vulkan-utility-libraries/src0
-rw-r--r--third_party/vulkan-validation-layers/README.chromium18
m---------third_party/vulkan-validation-layers/src0
m---------third_party/zlib0
m---------tools/android0
m---------tools/clang0
m---------tools/mb0
m---------tools/perf0
-rw-r--r--util/android/third_party/android_native_app_glue.c145
-rw-r--r--util/android/third_party/android_native_app_glue.h58
203 files changed, 3514 insertions, 1401 deletions
diff --git a/.gitignore b/.gitignore
index af83ec392f..3d9ffa76a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@
/third_party/fuchsia-sdk
/third_party/gles1_conform
/third_party/glmark2/src
+/third_party/glslang/src
/third_party/googletest
/third_party/ijar
/third_party/jdk/current
@@ -89,10 +90,18 @@
/third_party/rapidjson/src
/third_party/requests/src
/third_party/six
+/third_party/spirv-cross/src
+/third_party/spirv-headers/src
+/third_party/spirv-tools/src
/third_party/SwiftShader
/third_party/turbine/*.jar
/third_party/VK-GL-CTS/src
/third_party/vulkan-deps
+/third_party/vulkan-headers/src
+/third_party/vulkan-loader/src
+/third_party/vulkan-tools/src
+/third_party/vulkan-utility-libraries/src
+/third_party/vulkan-validation-layers/src
/third_party/vulkan_memory_allocator
/third_party/wayland
/third_party/zlib
diff --git a/.gitmodules b/.gitmodules
index d8ca36b452..f5f80fd062 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -92,7 +92,7 @@
[submodule "third_party/libdrm"]
path = third_party/libdrm
url = https://chromium.googlesource.com/chromiumos/third_party/libdrm
- gclient-condition = checkout_angle_mesa
+ gclient-condition = checkout_angle_mesa or not build_with_chromium
[submodule "third_party/libjpeg_turbo"]
path = third_party/libjpeg_turbo
url = https://chromium.googlesource.com/chromium/deps/libjpeg_turbo
@@ -108,7 +108,7 @@
[submodule "third_party/jinja2"]
path = third_party/jinja2
url = https://chromium.googlesource.com/chromium/src/third_party/jinja2
- gclient-condition = checkout_android and not build_with_chromium
+ gclient-condition = not build_with_chromium
[submodule "third_party/jsoncpp"]
path = third_party/jsoncpp
url = https://chromium.googlesource.com/chromium/src/third_party/jsoncpp
@@ -128,7 +128,7 @@
[submodule "third_party/markupsafe"]
path = third_party/markupsafe
url = https://chromium.googlesource.com/chromium/src/third_party/markupsafe
- gclient-condition = checkout_android and not build_with_chromium
+ gclient-condition = not build_with_chromium
[submodule "third_party/mesa/src"]
path = third_party/mesa/src
url = https://chromium.googlesource.com/external/github.com/Mesa3D/mesa
@@ -160,7 +160,7 @@
[submodule "third_party/perfetto"]
path = third_party/perfetto
url = https://android.googlesource.com/platform/external/perfetto
- gclient-condition = not build_with_chromium and checkout_angle_restricted_traces
+ gclient-condition = not build_with_chromium and checkout_angle_perfetto
[submodule "third_party/protobuf"]
path = third_party/protobuf
url = https://chromium.googlesource.com/chromium/src/third_party/protobuf
@@ -191,6 +191,42 @@
path = third_party/vulkan-deps
url = https://chromium.googlesource.com/vulkan-deps
gclient-condition = not build_with_chromium
+[submodule "third_party/glslang/src"]
+ path = third_party/glslang/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/glslang
+ gclient-condition = not build_with_chromium
+[submodule "third_party/spirv-cross/src"]
+ path = third_party/spirv-cross/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/SPIRV-Cross
+ gclient-condition = not build_with_chromium
+[submodule "third_party/spirv-headers/src"]
+ path = third_party/spirv-headers/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/SPIRV-Headers
+ gclient-condition = not build_with_chromium
+[submodule "third_party/spirv-tools/src"]
+ path = third_party/spirv-tools/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/SPIRV-Tools
+ gclient-condition = not build_with_chromium
+[submodule "third_party/vulkan-headers/src"]
+ path = third_party/vulkan-headers/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/Vulkan-Headers
+ gclient-condition = not build_with_chromium
+[submodule "third_party/vulkan-loader/src"]
+ path = third_party/vulkan-loader/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/Vulkan-Loader
+ gclient-condition = not build_with_chromium
+[submodule "third_party/vulkan-tools/src"]
+ path = third_party/vulkan-tools/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/Vulkan-Tools
+ gclient-condition = not build_with_chromium
+[submodule "third_party/vulkan-utility-libraries/src"]
+ path = third_party/vulkan-utility-libraries/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/Vulkan-Utility-Libraries
+ gclient-condition = not build_with_chromium
+[submodule "third_party/vulkan-validation-layers/src"]
+ path = third_party/vulkan-validation-layers/src
+ url = https://chromium.googlesource.com/external/github.com/KhronosGroup/Vulkan-ValidationLayers
+ gclient-condition = not build_with_chromium
[submodule "third_party/vulkan_memory_allocator"]
path = third_party/vulkan_memory_allocator
url = https://chromium.googlesource.com/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
diff --git a/.gn b/.gn
index bf84f78702..6e96504b40 100644
--- a/.gn
+++ b/.gn
@@ -53,6 +53,8 @@ default_args = {
# Use base level API level 29 support for AHardwareBuffer ANGLE tests.
android32_ndk_api_level = 29
android64_ndk_api_level = 29
+
+ vma_vulkan_headers_dir = "//third_party/vulkan-headers/src"
}
no_check_targets = [ "third_party/dawn/*" ]
diff --git a/BUILD.gn b/BUILD.gn
index 9ba42bd227..e9c3a3e79a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1244,16 +1244,10 @@ config("angle_abseil_config") {
group("angle_abseil") {
if (angle_enable_abseil) {
# When build_with_chromium=true we need to include "//third_party/abseil-cpp:absl" while
- # we can be more specific when building standalone ANGLE.
- if (build_with_chromium) {
+ # we can be more specific when building standalone non-component ANGLE.
+ # Also build the combined target when building Dawn to avoid multiply defined globals.
+ if (build_with_chromium || angle_enable_wgpu || is_component_build) {
public_deps = [ "$angle_abseil_cpp_dir:absl" ]
- } else if (angle_enable_wgpu) {
- # Use Dawn's abseil build files when Dawn will also be built. Multiple build targets
- # with the same files causes link issues in component builds.
- public_deps = [
- "$angle_dawn_dir/third_party/gn/abseil-cpp:flat_hash_map",
- "$angle_dawn_dir/third_party/gn/abseil-cpp:flat_hash_set",
- ]
} else {
public_deps = [
"$angle_abseil_cpp_dir/absl/container:flat_hash_map",
diff --git a/DEPS b/DEPS
index 88015befa6..8a0bb50c48 100644
--- a/DEPS
+++ b/DEPS
@@ -43,13 +43,13 @@ vars = {
'checkout_angle_mesa': False,
# Version of Chromium our Chromium-based DEPS are mirrored from.
- 'chromium_revision': '4fea14b56dd7d46a28e566671c06cdd0a92fc4d1',
+ 'chromium_revision': '1daa08898eedcd1371baaa095c129cf56bbff3da',
# We never want to checkout chromium,
# but need a dummy DEPS entry for the autoroller
'dummy_checkout_chromium': False,
# Current revision of VK-GL-CTS (a.k.a dEQP).
- 'vk_gl_cts_revision': '9d7b4c3d553331e316321942e2eb8413e4081c79',
+ 'vk_gl_cts_revision': 'fd5cc7b1e07578e8e807696034ab894b134f4280',
# Current revision of googletest.
# Note: this dep cannot be auto-rolled b/c of nesting.
@@ -88,16 +88,16 @@ 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': '47d3198a953f28d06b46bb6f9293b4e0b384d155',
+ 'catapult_revision': 'ec40c25bd83f043ebc76fb368414016b0515675b',
# the commit queue can handle CLs rolling Fuchsia sdk
# and whatever else without interference from each other.
- 'fuchsia_version': 'version:20.20240507.3.1',
+ 'fuchsia_version': 'version:20.20240522.3.1',
# 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:91ca2f5af39c4feb1c748c353f4d616e1c2332e7',
+ 'luci_go': 'git_revision:4967d21f2b92546ac3747086cdcbb046b6db52fb',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_build-tools_version
@@ -130,10 +130,10 @@ vars = {
# reclient CIPD package
'reclient_package': 'infra/rbe/client/',
# reclient CIPD package version
- 'reclient_version': 're_client_version:0.141.1.29a9d3c-gomaip',
+ 'reclient_version': 're_client_version:0.143.0.518e369-gomaip',
# siso CIPD package version.
- 'siso_version': 'git_revision:4524544994f4eac131378143f498ee4d0b7d1f36',
+ 'siso_version': 'git_revision:df7a992166415f66f6958744f149f724df138879',
# 'magic' text to tell depot_tools that git submodules should be accepted but
# but parity with DEPS file is expected.
@@ -141,7 +141,7 @@ vars = {
# Make Dawn skip its standalone dependencies
'dawn_standalone': False,
- 'dawn_revision': '5406e9dfbe0ba766e5a7571e1ad7c2dc48ad57e7',
+ 'dawn_revision': 'd32858a3045a89e8c5ff919107ee76c8b103afdf',
# All of the restricted traces (large).
'checkout_angle_restricted_traces': 'checkout_angle_internal',
@@ -415,12 +415,12 @@ vars = {
deps = {
'build': {
- 'url': Var('chromium_git') + '/chromium/src/build.git@7796c50af5b192c01d7c92f930de2093a8507097',
+ 'url': Var('chromium_git') + '/chromium/src/build.git@59a9be4050c182588808e01f79d6d743e9351034',
'condition': 'not build_with_chromium',
},
'buildtools': {
- 'url': Var('chromium_git') + '/chromium/src/buildtools.git@9703d9137fff0cb447779de1bfebbe18ea312f89',
+ 'url': Var('chromium_git') + '/chromium/src/buildtools.git@efa920ce144e4dc1c1841e73179cd7e23b9f0d5e',
'condition': 'not build_with_chromium',
},
@@ -433,7 +433,7 @@ deps = {
'packages': [
{
'package': 'gn/gn/linux-${{arch}}',
- 'version': 'git_revision:f284b6b47039a2d7edfcbfc51f52664f82b5a789',
+ 'version': 'git_revision:df98b86690c83b81aedc909ded18857296406159',
}
],
'dep_type': 'cipd',
@@ -444,7 +444,7 @@ deps = {
'packages': [
{
'package': 'gn/gn/mac-${{arch}}',
- 'version': 'git_revision:f284b6b47039a2d7edfcbfc51f52664f82b5a789',
+ 'version': 'git_revision:df98b86690c83b81aedc909ded18857296406159',
}
],
'dep_type': 'cipd',
@@ -466,7 +466,7 @@ deps = {
'packages': [
{
'package': 'gn/gn/windows-amd64',
- 'version': 'git_revision:f284b6b47039a2d7edfcbfc51f52664f82b5a789',
+ 'version': 'git_revision:df98b86690c83b81aedc909ded18857296406159',
}
],
'dep_type': 'cipd',
@@ -474,12 +474,12 @@ deps = {
},
'testing': {
- 'url': '{chromium_git}/chromium/src/testing@a2a6e48c98e5e5869e822b542e935514d843c436',
+ 'url': '{chromium_git}/chromium/src/testing@940cfd4db1dfb7712cb94d68f19e476f6ed6e3ad',
'condition': 'not build_with_chromium',
},
'third_party/abseil-cpp': {
- 'url': Var('chromium_git') + '/chromium/src/third_party/abseil-cpp@31bdf8fec41f04dfe86976734cbad22ded4ca1f7',
+ 'url': Var('chromium_git') + '/chromium/src/third_party/abseil-cpp@b027bd3c0b3ce035c8da06a78e7ab8db2d5c4444',
'condition': 'not build_with_chromium',
},
@@ -525,7 +525,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_build_tools/lint',
- 'version': 'Y5wuGPB-HfFtEVQC_0XI6n88Covm4HFDxnG0uTdV2LcC',
+ 'version': '802fuDf2tCI5HIcMNx1jWJbsTrLt2DS5z8BuFE_Sx7cC',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -536,7 +536,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_build_tools/manifest_merger',
- 'version': 'tz8dYQ_yBEZJRVhtzyyCjOlbOfujkHRWcYZy7419o_cC',
+ 'version': 'EBQZXvDztclHzavY9ulEJA3r4mn0PmbIMeKYKnzhEoEC',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -544,7 +544,7 @@ deps = {
},
'third_party/android_deps': {
- 'url': Var('chromium_git') + '/chromium/src/third_party/android_deps@36a6c64282adbe58f343d9c0cbdf45d0e6402db3',
+ 'url': Var('chromium_git') + '/chromium/src/third_party/android_deps@2888a739e9b8b8514807a5a0d8b26f91a7e4e91d',
'condition': 'checkout_android and not build_with_chromium',
},
@@ -656,7 +656,7 @@ deps = {
},
'third_party/depot_tools': {
- 'url': Var('chromium_git') + '/chromium/tools/depot_tools.git@df437783c243fef294e6af2e44de383e751a3764',
+ 'url': Var('chromium_git') + '/chromium/tools/depot_tools.git@09c232e7c0d5670695d1f8f70d05ed1a215e438c',
'condition': 'not build_with_chromium',
},
@@ -673,7 +673,7 @@ deps = {
},
'third_party/flatbuffers/src': {
- 'url': Var('chromium_git') + '/external/github.com/google/flatbuffers.git@bcb9ef187628fe07514e57756d05e6a6296f7dc5',
+ 'url': Var('chromium_git') + '/external/github.com/google/flatbuffers.git@150644d7f4d030a0629c564fd90dc3becab77636',
'condition': 'checkout_android and not build_with_chromium',
},
@@ -713,7 +713,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/kotlin_stdlib',
- 'version': '05hzFgOi0AqRK3RxbSvGj2TWTFUNeLcwkJwVzwgLttUC',
+ 'version': '_4e0lDaCjMgaNeq2v2olJs_15Ax3PxGfCU9fMt0FTKcC',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -775,17 +775,17 @@ deps = {
},
'third_party/libc++/src': {
- 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libcxx.git@e3b94d0e5b86883fd77696bf10dc33ba250ba99b',
+ 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libcxx.git@852bc6746f45add53fec19f3a29280e69e358d44',
'condition': 'not build_with_chromium',
},
'third_party/libc++abi/src': {
- 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libcxxabi.git@d17298ab09b44bbc95e5e59c0f285145d0e5f8a7',
+ 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libcxxabi.git@ba370858669b1e905db5ded82c8887095b61dc14',
'condition': 'not build_with_chromium',
},
'third_party/libunwind/src': {
- 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libunwind.git@419b03c0b8f20d6da9ddcb0d661a94a97cdd7dad',
+ 'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libunwind.git@e0a4f3561e7f7ce10573917b60c7027e3b599e65',
'condition': 'not build_with_chromium',
},
@@ -872,7 +872,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/r8',
- 'version': 'ntlyos9oLHW_q1AeZovqFuTYzog9dKd2lITTowptHuYC',
+ 'version': '2VsAp2dMXnrxyG6_BD0El4gDAxTXPqrw8xCV0MNmxcUC',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -919,7 +919,7 @@ deps = {
},
'third_party/SwiftShader': {
- 'url': Var('swiftshader_git') + '/SwiftShader@da334852e70510d259bfa8cbaa7c5412966b2f41',
+ 'url': Var('swiftshader_git') + '/SwiftShader@90519141a709a92db90640b52176aaf82942e937',
'condition': 'not build_with_chromium',
},
@@ -927,7 +927,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/turbine',
- 'version': 'fYpnoJAvh8-OaNB9k81XWGrwiODb_uTipTBEUeIFM98C',
+ 'version': 'JA8o86DtHkYnsW4v8F9pdcvi7uqN1WB-L1XFLggZdtAC',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -939,7 +939,52 @@ deps = {
},
'third_party/vulkan-deps': {
- 'url': Var('chromium_git') + '/vulkan-deps@643408ea2a0685352d831a97601997c9ea246f6f',
+ 'url': Var('chromium_git') + '/vulkan-deps@feb3ce48e50956465d171e37c548bb8e44a30efa',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/glslang/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/glslang@7c3c50ea94354d06dc8c280de8b8a5d5aacbbb19',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/spirv-cross/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Cross@b8fcf307f1f347089e3c46eb4451d27f32ebc8d3',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/spirv-headers/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@49a1fceb9b1d087f3c25ad5ec077bb0e46231297',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/spirv-tools/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Tools@77c40bece1b8b441eee432fc9d74efbf985f777f',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/vulkan-headers/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Headers@5677bafb820e476441e9e1f745371b72133407d3',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/vulkan-loader/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Loader@d3d530c90dd6549bcfc7cfaedd3ff85fe8ff04a2',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/vulkan-tools/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Tools@d67a9d3a394e11c1c4c0f480124f5b7925cb1b4d',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/vulkan-utility-libraries/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Utility-Libraries@f6c54531066c6d28ef403b50ff9cff3ea195d28a',
+ 'condition': 'not build_with_chromium',
+ },
+
+ 'third_party/vulkan-validation-layers/src': {
+ 'url': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@b25dea41d4a441268745ed9a83f82757170ec459',
'condition': 'not build_with_chromium',
},
@@ -954,17 +999,17 @@ deps = {
},
'third_party/zlib': {
- 'url': Var('chromium_git') + '/chromium/src/third_party/zlib@7d77fb7fd66d8a5640618ad32c71fdeb7d3e02df',
+ 'url': Var('chromium_git') + '/chromium/src/third_party/zlib@209717dd69cd62f24cbacc4758261ae2dd78cfac',
'condition': 'not build_with_chromium',
},
'tools/android': {
- 'url': Var('chromium_git') + '/chromium/src/tools/android@cc51a5ea8611565ff48db1a11c08e90d03484bd2',
+ 'url': Var('chromium_git') + '/chromium/src/tools/android@34192533e15dd37bd3c91910247fb925d1e15327',
'condition': 'checkout_android and not build_with_chromium',
},
'tools/clang': {
- 'url': Var('chromium_git') + '/chromium/src/tools/clang.git@964cf5c799c2284d52a88b1a516481852e7a216f',
+ 'url': Var('chromium_git') + '/chromium/src/tools/clang.git@9772a0a3490ed8f5977babbb01182944b44d3ea8',
'condition': 'not build_with_chromium',
},
@@ -995,7 +1040,7 @@ deps = {
},
'tools/mb': {
- 'url': Var('chromium_git') + '/chromium/src/tools/mb@54a120d570f317c69bb155481629e2121df75546',
+ 'url': Var('chromium_git') + '/chromium/src/tools/mb@973c25352084d231639ecd6f110e8343e203defb',
'condition': 'not build_with_chromium',
},
@@ -1010,7 +1055,7 @@ deps = {
},
'tools/perf': {
- 'url': Var('chromium_git') + '/chromium/src/tools/perf@7ef4ff5ba36be22f641d0f08f34402f85db18492',
+ 'url': Var('chromium_git') + '/chromium/src/tools/perf@ce2f1c1daa5716c697105213772e13be838ee441',
'condition': 'not build_with_chromium',
},
@@ -1028,7 +1073,7 @@ deps = {
'packages': [
{
'package': 'skia/tools/goldctl/linux-amd64',
- 'version': 'rnVa2tBzy_bWBzhMbfGN9LWVREg2oX7FIWTizcil9nAC',
+ 'version': 'WMIZj5iCtXaIDiOhz7iiswLMOl8EWWP5gfRyHAEZUSAC',
},
],
'dep_type': 'cipd',
@@ -1039,7 +1084,7 @@ deps = {
'packages': [
{
'package': 'skia/tools/goldctl/windows-amd64',
- 'version': 'qWfDi1N2HXBm5wLJgsy6fImu51jqJ6JafFDWjWJPuMQC',
+ 'version': 'zHUBIGOiczuqjD1DhUqsPCLIcVp7c-7bnuOzAncAsy0C',
},
],
'dep_type': 'cipd',
@@ -1050,7 +1095,7 @@ deps = {
'packages': [
{
'package': 'skia/tools/goldctl/mac-amd64',
- 'version': 'Y1vx6zBEl8AgYA0BE99RK71LoJPAJMdFcFZUiiH4ItIC',
+ 'version': '88_YxpnUWyvy_qTnp6FH2cvFsJ3eKeNLLph6CbyXHmoC',
},
],
'dep_type': 'cipd',
@@ -1061,7 +1106,7 @@ deps = {
'packages': [
{
'package': 'skia/tools/goldctl/mac-arm64',
- 'version': '1QeDGa3HwvjmY-wV4NK81PTGZGJ_uSZ0FSC0dHAosIsC',
+ 'version': 'TtqdFmghiNp8fsnpcuBhyC8e9PjVxKAXDBQhNoTReaUC',
},
],
'dep_type': 'cipd',
@@ -4904,7 +4949,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on',
- 'version': 'version:2@1.76.cr1',
+ 'version': 'version:2@1.77.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5168,7 +5213,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_ow2_asm_asm',
- 'version': 'version:2@9.6.cr1',
+ 'version': 'version:2@9.7.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5179,7 +5224,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_ow2_asm_asm_analysis',
- 'version': 'version:2@9.6.cr1',
+ 'version': 'version:2@9.7.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5190,7 +5235,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_ow2_asm_asm_commons',
- 'version': 'version:2@9.6.cr1',
+ 'version': 'version:2@9.7.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5201,7 +5246,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_ow2_asm_asm_tree',
- 'version': 'version:2@9.6.cr1',
+ 'version': 'version:2@9.7.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5212,7 +5257,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_ow2_asm_asm_util',
- 'version': 'version:2@9.6.cr1',
+ 'version': 'version:2@9.7.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5234,7 +5279,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_annotations',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5245,7 +5290,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_junit',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5256,7 +5301,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_nativeruntime',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5267,7 +5312,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat',
- 'version': 'version:2@1.0.2.cr1',
+ 'version': 'version:2@1.0.9.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5278,7 +5323,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_pluginapi',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5289,7 +5334,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5300,7 +5345,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_resources',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5311,7 +5356,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_robolectric',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5322,7 +5367,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_sandbox',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5333,7 +5378,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_shadowapi',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5344,7 +5389,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_shadows_framework',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5355,7 +5400,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_shadows_versioning',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5366,7 +5411,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_utils',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5377,7 +5422,7 @@ deps = {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/org_robolectric_utils_reflector',
- 'version': 'version:2@4.11.1.cr1',
+ 'version': 'version:2@4.12.1.cr1',
},
],
'condition': 'checkout_android and not build_with_chromium',
@@ -5654,7 +5699,6 @@ hooks = [
recursedeps = [
'third_party/googletest',
'third_party/jsoncpp',
- 'third_party/vulkan-deps',
'third_party/dawn',
]
diff --git a/OWNERS b/OWNERS
index bde1c2b20c..12123c136c 100644
--- a/OWNERS
+++ b/OWNERS
@@ -54,6 +54,7 @@ per-file third_party/EGL-Registry/src=*
per-file third_party/flatbuffers/src=*
per-file third_party/gles1_conform=*
per-file third_party/glmark2/src=*
+per-file third_party/glslang/src=*
per-file third_party/googletest=*
per-file third_party/ijar=*
per-file third_party/libdrm=*
@@ -77,9 +78,17 @@ per-file third_party/Python-Markdown=*
per-file third_party/rapidjson/src=*
per-file third_party/requests/src=*
per-file third_party/six=*
+per-file third_party/spirv-cross/src=*
+per-file third_party/spirv-headers/src=*
+per-file third_party/spirv-tools/src=*
per-file third_party/SwiftShader=*
per-file third_party/VK-GL-CTS/src=*
per-file third_party/vulkan-deps=*
+per-file third_party/vulkan-headers/src=*
+per-file third_party/vulkan-loader/src=*
+per-file third_party/vulkan-tools/src=*
+per-file third_party/vulkan-utility-libraries/src=*
+per-file third_party/vulkan-validation-layers/src=*
per-file third_party/vulkan_memory_allocator=*
per-file third_party/wayland=*
per-file third_party/zlib=*
diff --git a/build b/build
-Subproject 7796c50af5b192c01d7c92f930de2093a850709
+Subproject 59a9be4050c182588808e01f79d6d743e935103
diff --git a/build_overrides/angle.gni b/build_overrides/angle.gni
index 48f3993b5d..dcd98eb8f9 100644
--- a/build_overrides/angle.gni
+++ b/build_overrides/angle.gni
@@ -10,13 +10,13 @@ angle_has_build = true
# Overrides for ANGLE's dependencies
angle_abseil_cpp_dir = "//third_party/abseil-cpp"
-angle_glslang_dir = "//third_party/vulkan-deps/glslang/src"
+angle_glslang_dir = "//third_party/glslang/src"
angle_googletest_dir = "//third_party/googletest/src"
angle_jsoncpp_dir = "//third_party/jsoncpp"
angle_libjpeg_turbo_dir = "//third_party/libjpeg_turbo"
angle_libpng_dir = "//third_party/libpng"
-angle_spirv_headers_dir = "//third_party/vulkan-deps/spirv-headers/src"
-angle_spirv_tools_dir = "//third_party/vulkan-deps/spirv-tools/src"
+angle_spirv_headers_dir = "//third_party/spirv-headers/src"
+angle_spirv_tools_dir = "//third_party/spirv-tools/src"
angle_vulkan_memory_allocator_dir = "//third_party/vulkan_memory_allocator"
angle_clspv_dir = "//third_party/clspv"
angle_llvm_dir = "//third_party/llvm/src"
diff --git a/build_overrides/dawn.gni b/build_overrides/dawn.gni
index c1b38f7be7..85bb1ae014 100644
--- a/build_overrides/dawn.gni
+++ b/build_overrides/dawn.gni
@@ -1,4 +1,5 @@
build_with_chromium = false
+build_with_angle = true
dawn_build_dxc = false
dawn_angle_dir = "//"
@@ -6,11 +7,12 @@ dawn_glfw_dir = "//third_party/dawn/third_party/glfw"
dawn_googletest_dir = "//third_party/googletest/src"
dawn_jinja2_dir = "//third_party/jinja2"
dawn_jsoncpp_dir = "//third_party/jsoncpp"
-dawn_spirv_tools_dir = "//third_party/vulkan-deps/spirv-tools/src"
+dawn_spirv_tools_dir = "//third_party/spirv-tools/src"
dawn_swiftshader_dir = "//third_party/SwiftShader"
-dawn_vulkan_loader_dir = "//third_party/vulkan-deps/vulkan-loader/src"
-dawn_vulkan_validation_layers_dir =
- "//third_party/vulkan-deps/vulkan-validation-layers/src"
+dawn_vulkan_headers_dir = "//third_party/vulkan-headers/src"
+dawn_vulkan_loader_dir = "//third_party/vulkan-loader/src"
+dawn_vulkan_utility_libraries_dir = "//third_party/vulkan-utility-libraries/src"
+dawn_vulkan_validation_layers_dir = "//third_party/vulkan-validation-layers/src"
dawn_dxc_dir = "//third_party/dawn/third_party/dxc"
dawn_dxheaders_dir = "//third_party/dawn/third_party/dxheaders"
dawn_opengl_registry_dir = "//third_party/OpenGL-Registry/src"
diff --git a/build_overrides/glslang.gni b/build_overrides/glslang.gni
index c32adf60b3..534d55d911 100644
--- a/build_overrides/glslang.gni
+++ b/build_overrides/glslang.gni
@@ -3,4 +3,4 @@
# found in the LICENSE file.
# Paths to glslang dependencies in ANGLE
-glslang_spirv_tools_dir = "//third_party/vulkan-deps/spirv-tools/src"
+glslang_spirv_tools_dir = "//third_party/spirv-tools/src"
diff --git a/build_overrides/spirv_tools.gni b/build_overrides/spirv_tools.gni
index 3c9b43ad97..adfa08b6d8 100644
--- a/build_overrides/spirv_tools.gni
+++ b/build_overrides/spirv_tools.gni
@@ -7,4 +7,4 @@ spirv_tools_standalone = false
# Paths to SPIRV-Tools dependencies in ANGLE
spirv_tools_googletest_dir = "//third_party/googletest/src"
-spirv_tools_spirv_headers_dir = "//third_party/vulkan-deps/spirv-headers/src"
+spirv_tools_spirv_headers_dir = "//third_party/spirv-headers/src"
diff --git a/build_overrides/tint.gni b/build_overrides/tint.gni
index ee43d60929..4e41a6aa72 100644
--- a/build_overrides/tint.gni
+++ b/build_overrides/tint.gni
@@ -4,9 +4,9 @@ tint_has_build = false
tint_build_unittests = false
tint_root_dir = "//third_party/dawn"
-tint_spirv_tools_dir = "//third_party/vulkan-deps/spirv-tools/src"
+tint_spirv_tools_dir = "//third_party/spirv-tools/src"
tint_googletest_dir = "//third_party/googletest/src"
-tint_spirv_headers_dir = "//third_party/vulkan-deps/spirv-headers/src"
+tint_spirv_headers_dir = "//third_party/spirv-headers/src"
tint_build_spv_reader = false
tint_build_spv_writer = true
diff --git a/build_overrides/vulkan_validation_layers.gni b/build_overrides/vulkan_validation_layers.gni
index c57af506d3..d47b6c7a7f 100644
--- a/build_overrides/vulkan_validation_layers.gni
+++ b/build_overrides/vulkan_validation_layers.gni
@@ -4,8 +4,7 @@
import("//build_overrides/vulkan_common.gni")
-vulkan_utility_libraries_dir =
- "//third_party/vulkan-deps/vulkan-utility-libraries/src"
-vvl_spirv_tools_dir = "//third_party/vulkan-deps/spirv-tools/src"
-vvl_spirv_headers_dir = "//third_party/vulkan-deps/spirv-headers/src"
-vvl_glslang_dir = "//third_party/vulkan-deps/glslang/src"
+vulkan_utility_libraries_dir = "//third_party/vulkan-utility-libraries/src"
+vvl_spirv_tools_dir = "//third_party/spirv-tools/src"
+vvl_spirv_headers_dir = "//third_party/spirv-headers/src"
+vvl_glslang_dir = "//third_party/glslang/src"
diff --git a/buildtools b/buildtools
-Subproject 9703d9137fff0cb447779de1bfebbe18ea312f8
+Subproject efa920ce144e4dc1c1841e73179cd7e23b9f0d5
diff --git a/extensions/EGL_ANGLE_device_d3d11.txt b/extensions/EGL_ANGLE_device_d3d11.txt
new file mode 100644
index 0000000000..a90b95c80f
--- /dev/null
+++ b/extensions/EGL_ANGLE_device_d3d11.txt
@@ -0,0 +1,89 @@
+Name
+
+ ANGLE_device_d3d11
+
+Name Strings
+
+ EGL_ANGLE_device_d3d11
+
+Contributors
+
+ Geoff Lang (geofflang 'at' google.com)
+ Contributors of EGL_ANGLE_device_d3d
+
+Contact
+
+ Geoff Lang (geofflang 'at' google.com)
+
+Status
+
+ Draft
+
+Version
+
+ Version 1, May 21, 2024
+
+Number
+
+ EGL Extension #XXX
+
+Extension Type
+
+ EGL device extension
+
+Dependencies
+
+ This extension is written against the language of EGL 1.5 as
+ modified by EGL_EXT_device_query.
+
+ EGL_EXT_device_query is required.
+
+Overview
+
+ ANGLE has the ability to run GPU commands on a native D3D11 device.
+ This extension defines a mapping from an EGL device to a D3D11
+ device, after it's queried from an EGL display.
+
+IP Status
+
+ No known claims.
+
+New Types
+
+ None.
+
+New Procedures and Functions
+
+ None.
+
+New Tokens
+
+ Accepted as a queried <attribute> in eglQueryDeviceAttribEXT:
+
+ EGL_D3D11_DEVICE_ANGLE 0x33A1
+
+Add a new section 2.1.3 (D3D11 Devices) after 2.1.2 (Devices)
+
+ Somewhat analogous to an EGL device, a D3D11 device establishes a
+ namespace for D3D operations. In the D3D APIs, such devices are
+ represented by pointers. For more details, see the D3D11
+ documentation.
+
+Changes to section 3.2 (Devices)
+
+ Replace the paragraph immediately following the prototype for
+ eglQueryDeviceAttribEXT:
+
+ <attribute> may EGL_D3D11_DEVICE_ANGLE. On success, EGL_TRUE is
+ returned, and a valid D3D11 device pointer corresponding to the EGL
+ device is returned in <value>. This handle is compatible with D3D11
+ API functions.
+
+Issues
+
+ None
+
+Revision History
+
+ Version 1, May 21, 2024 (Geoff Lang)
+ - Initial Draft, based off of EGL_ANGLE_device_d3d
diff --git a/extensions/EGL_ANGLE_device_d3d9.txt b/extensions/EGL_ANGLE_device_d3d9.txt
new file mode 100644
index 0000000000..07137260c6
--- /dev/null
+++ b/extensions/EGL_ANGLE_device_d3d9.txt
@@ -0,0 +1,89 @@
+Name
+
+ ANGLE_device_d3d9
+
+Name Strings
+
+ EGL_ANGLE_device_d3d9
+
+Contributors
+
+ Geoff Lang (geofflang 'at' google.com)
+ Contributors of EGL_ANGLE_device_d3d
+
+Contact
+
+ Geoff Lang (geofflang 'at' google.com)
+
+Status
+
+ Draft
+
+Version
+
+ Version 1, May 21, 2024
+
+Number
+
+ EGL Extension #XXX
+
+Extension Type
+
+ EGL device extension
+
+Dependencies
+
+ This extension is written against the language of EGL 1.5 as
+ modified by EGL_EXT_device_query.
+
+ EGL_EXT_device_query is required.
+
+Overview
+
+ ANGLE has the ability to run GPU commands on a native D3D9 device.
+ This extension defines a mapping from an EGL device to a D3D9
+ device, after it's queried from an EGL display.
+
+IP Status
+
+ No known claims.
+
+New Types
+
+ None.
+
+New Procedures and Functions
+
+ None.
+
+New Tokens
+
+ Accepted as a queried <attribute> in eglQueryDeviceAttribEXT:
+
+ EGL_D3D9_DEVICE_ANGLE 0x33A0
+
+Add a new section 2.1.3 (D3D9 Devices) after 2.1.2 (Devices)
+
+ Somewhat analogous to an EGL device, a D3D9 device establishes a
+ namespace for D3D operations. In the D3D APIs, such devices are
+ represented by pointers. For more details, see the D3D9
+ documentation.
+
+Changes to section 3.2 (Devices)
+
+ Replace the paragraph immediately following the prototype for
+ eglQueryDeviceAttribEXT:
+
+ <attribute> may EGL_D3D9_DEVICE_ANGLE. On success, EGL_TRUE is
+ returned, and a valid D3D9 device pointer corresponding to the EGL
+ device is returned in <value>. This handle is compatible with D3D9
+ API functions.
+
+Issues
+
+ None
+
+Revision History
+
+ Version 1, May 21, 2024 (Geoff Lang)
+ - Initial Draft, based off of EGL_ANGLE_device_d3d
diff --git a/gni/angle.gni b/gni/angle.gni
index 2feede6743..a9ddfa3a02 100644
--- a/gni/angle.gni
+++ b/gni/angle.gni
@@ -293,14 +293,11 @@ declare_args() {
# Directory where to find wayland source files
angle_wayland_dir = "$angle_root/third_party/wayland"
- angle_vulkan_headers_dir =
- "$angle_root/third_party/vulkan-deps/vulkan-headers/src"
- angle_vulkan_loader_dir =
- "$angle_root/third_party/vulkan-deps/vulkan-loader/src"
- angle_vulkan_tools_dir =
- "$angle_root/third_party/vulkan-deps/vulkan-tools/src"
+ angle_vulkan_headers_dir = "$angle_root/third_party/vulkan-headers/src"
+ angle_vulkan_loader_dir = "$angle_root/third_party/vulkan-loader/src"
+ angle_vulkan_tools_dir = "$angle_root/third_party/vulkan-tools/src"
angle_vulkan_validation_layers_dir =
- "$angle_root/third_party/vulkan-deps/vulkan-validation-layers/src"
+ "$angle_root/third_party/vulkan-validation-layers/src"
angle_build_vulkan_system_info = angle_has_build && !angle_is_winuwp
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg
index f1983aa985..a0cdc90829 100644
--- a/infra/config/generated/luci-milo.cfg
+++ b/infra/config/generated/luci-milo.cfg
@@ -71,11 +71,6 @@ consoles {
short_name: "dbg"
}
builders {
- name: "buildbucket/luci.angle.ci/mac-exp-test"
- category: "test|mac|x64"
- short_name: "exp"
- }
- builders {
name: "buildbucket/luci.angle.ci/mac-test"
category: "test|mac|x64"
short_name: "rel"
@@ -186,6 +181,9 @@ consoles {
name: "buildbucket/luci.angle.ci/linux-exp-tsan-test"
}
builders {
+ name: "buildbucket/luci.angle.ci/mac-exp-test"
+ }
+ builders {
name: "buildbucket/luci.angle.ci/win-exp-test"
}
builder_view_only: true
diff --git a/infra/config/main.star b/infra/config/main.star
index 1533f831f6..cfbaeb8572 100755
--- a/infra/config/main.star
+++ b/infra/config/main.star
@@ -323,7 +323,6 @@ def angle_builder(name, cpu):
"android-arm64-exp-test",
"android-arm64-exp-s22-test",
"linux-exp-test",
- "mac-exp-test",
]
if (not is_exp) or (name in active_experimental_builders):
diff --git a/infra/specs/angle.json b/infra/specs/angle.json
index d599aee141..ac35e33f58 100644
--- a/infra/specs/angle.json
+++ b/infra/specs/angle.json
@@ -5641,7 +5641,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -5665,7 +5665,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -5690,7 +5690,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -5715,7 +5715,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -5740,7 +5740,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -5766,7 +5766,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -5792,7 +5792,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -5814,209 +5814,7 @@
"display_attached": "1",
"gpu": "1002:67ef",
"hidpi": "1",
- "os": "Mac-13.5",
- "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
- }
- ]
- },
- "mac-exp-amd": {
- "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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
- "pool": "chromium.tests.gpu"
- },
- "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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
- "pool": "chromium.tests.gpu"
- },
- "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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
- "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": [
- "--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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
- "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": [
- "--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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
- "pool": "chromium.tests.gpu"
- },
- "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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
- "pool": "chromium.tests.gpu"
- },
- "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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
- "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
- },
- {
- "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": "1002:67ef",
- "hidpi": "1",
- "os": "Mac-14.3.1|Mac-14.4.1",
+ "os": "Mac-14.4.1",
"pool": "chromium.tests.gpu"
},
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -6027,6 +5825,7 @@
}
]
},
+ "mac-exp-amd": {},
"mac-exp-intel": {},
"mac-exp-nvidia": {},
"mac-intel": {
diff --git a/infra/specs/angle_mb_config.pyl b/infra/specs/angle_mb_config.pyl
index c211e7ee34..c2bbe79f0e 100644
--- a/infra/specs/angle_mb_config.pyl
+++ b/infra/specs/angle_mb_config.pyl
@@ -60,10 +60,10 @@
'configs': {
'angle_asan_bot': ['angle', 'opencl', 'reclient', 'asan', 'release', 'desktop'],
'angle_asan_lsan_ubsan_bot': ['angle', 'opencl', 'openclcts', 'reclient', 'asan', 'lsan', 'ubsan', 'release', 'desktop'],
- 'angle_non_clang_debug_bot': ['angle', 'opencl', 'non_clang', 'debug', 'desktop'],
- 'angle_non_clang_release_bot': ['angle', 'opencl', 'non_clang', 'release', 'desktop'],
- 'angle_non_clang_x86_debug_bot': ['angle', 'opencl', 'non_clang', 'x86', 'debug'],
- 'angle_non_clang_x86_release_bot': ['angle', 'opencl', 'non_clang', 'x86', 'release'],
+ 'angle_non_clang_debug_bot': ['angle', 'non_clang', 'debug', 'desktop'],
+ 'angle_non_clang_release_bot': ['angle', 'non_clang', 'release', 'desktop'],
+ 'angle_non_clang_x86_debug_bot': ['angle', 'non_clang', 'x86', 'debug', 'cxx17'],
+ 'angle_non_clang_x86_release_bot': ['angle', 'non_clang', 'x86', 'release'],
'angle_reclient_android_arm64_debug_bot': ['angle', 'opencl', 'openclcts', 'reclient', 'android', 'arm64', 'debug'],
'angle_reclient_android_arm64_release_bot': ['angle', 'capture', 'opencl', 'openclcts', 'reclient', 'android', 'arm64', 'release'],
'angle_reclient_android_arm_debug_bot': ['angle', 'opencl', 'openclcts', 'reclient', 'android', 'arm', 'debug', 'cxx17'],
diff --git a/infra/specs/mixins.pyl b/infra/specs/mixins.pyl
index 949a6270cf..e1bead1e5a 100644
--- a/infra/specs/mixins.pyl
+++ b/infra/specs/mixins.pyl
@@ -63,13 +63,13 @@
'display_attached': '1',
'gpu': '1002:67ef',
'hidpi': '1',
- 'os': 'Mac-14.3.1|Mac-14.4.1',
+ 'os': 'Mac-14.4.1',
'pool': 'chromium.tests.gpu'}}},
'mac_retina_amd_gpu_stable': { 'swarming': { 'dimensions': { 'cpu': 'x86-64',
'display_attached': '1',
'gpu': '1002:67ef',
'hidpi': '1',
- 'os': 'Mac-13.5',
+ 'os': 'Mac-14.4.1',
'pool': 'chromium.tests.gpu'}}},
'mac_retina_nvidia_gpu_experimental': { 'swarming': { 'dimensions': { 'cpu': 'x86-64',
'display_attached': '1',
diff --git a/infra/specs/waterfalls.pyl b/infra/specs/waterfalls.pyl
index d3ba3786ec..a9c072ecf8 100644
--- a/infra/specs/waterfalls.pyl
+++ b/infra/specs/waterfalls.pyl
@@ -230,7 +230,6 @@
'mac_retina_amd_gpu_experimental',
],
'test_suites': {
- 'gtest_tests': 'mac_amd_and_intel_gtests',
},
},
'mac-exp-intel': {
diff --git a/scripts/code_generation_hashes/Extension_files.json b/scripts/code_generation_hashes/Extension_files.json
index 6df352232c..dd6a1fa484 100644
--- a/scripts/code_generation_hashes/Extension_files.json
+++ b/scripts/code_generation_hashes/Extension_files.json
@@ -2,7 +2,7 @@
"doc/ExtensionSupport.md":
"a139fa98744132d92c5d66356efc373d",
"scripts/egl_angle_ext.xml":
- "697a927b35f5f48c6a1be5cf56e9f103",
+ "bdd2dcfaa4b6d82e12b6004f1435946d",
"scripts/extension_data/intel_630_linux.json":
"3b86832de6a7095f4617e273cba6d45e",
"scripts/extension_data/intel_630_win10.json":
@@ -22,7 +22,7 @@
"scripts/gl_angle_ext.xml":
"197e07a917d5bba6dfa2840fb1b58e7e",
"scripts/registry_xml.py":
- "eb23ab1ec2c7c8d78aefbfe0aa86fc4a",
+ "0d9085b06bc29cf8fdfb2a04a24a44c2",
"src/libANGLE/gen_extensions.py":
"6ea1cb1733c4df98b527bbf2752e118b",
"src/libANGLE/gles_extensions_autogen.cpp":
diff --git a/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json b/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json
index 8287da966b..c7b88bb0e7 100644
--- a/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json
+++ b/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json
@@ -26,11 +26,11 @@
"third_party/VK-GL-CTS/src/external/openglcts/modules/CMakeLists.txt":
"51bab42277ace2f99407b1b88715a92f",
"third_party/VK-GL-CTS/src/external/openglcts/modules/common/CMakeLists.txt":
- "7662b4a17b08f07b4b2e2a57edceb209",
+ "38908cad976953ed99c59b6b1ba61a87",
"third_party/VK-GL-CTS/src/external/openglcts/modules/common/subgroups/CMakeLists.txt":
"bf71ce2d9756ccee7833a789737e6481",
"third_party/VK-GL-CTS/src/external/openglcts/modules/gl/CMakeLists.txt":
- "0f90224dc01d52e436014cf5f0b14490",
+ "143dffb11c57e173f8f73966466c4de9",
"third_party/VK-GL-CTS/src/external/openglcts/modules/gles2/CMakeLists.txt":
"5ac63dce60849bf12e3ab2dde99424ab",
"third_party/VK-GL-CTS/src/external/openglcts/modules/gles3/CMakeLists.txt":
@@ -70,7 +70,7 @@
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/device_group/CMakeLists.txt":
"451a6c35fd38aec3212d02f14f201cf9",
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/draw/CMakeLists.txt":
- "b38e8a3627004e3556ea88df76bdb088",
+ "11c790826f72087412af6e0b19ab30b3",
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/dynamic_state/CMakeLists.txt":
"3db8818671533ace06b9b7710aeda461",
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/fragment_ops/CMakeLists.txt":
@@ -128,7 +128,7 @@
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/sparse_resources/CMakeLists.txt":
"0d64de8230844f6dfd44306993105f31",
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt":
- "672bde36c1263be73ba59503021410d9",
+ "45857ee5183883971f8d53949f8d06b8",
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/ssbo/CMakeLists.txt":
"509295d2d41e74dc371ec29b221ee854",
"third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/subgroups/CMakeLists.txt":
diff --git a/scripts/code_generation_hashes/GL_EGL_WGL_loader.json b/scripts/code_generation_hashes/GL_EGL_WGL_loader.json
index d98a7ff66e..1ffbd3d64e 100644
--- a/scripts/code_generation_hashes/GL_EGL_WGL_loader.json
+++ b/scripts/code_generation_hashes/GL_EGL_WGL_loader.json
@@ -1,12 +1,12 @@
{
"scripts/egl_angle_ext.xml":
- "697a927b35f5f48c6a1be5cf56e9f103",
+ "bdd2dcfaa4b6d82e12b6004f1435946d",
"scripts/generate_loader.py":
"93c78a8d11323fa311fed5118fbcf083",
"scripts/gl_angle_ext.xml":
"197e07a917d5bba6dfa2840fb1b58e7e",
"scripts/registry_xml.py":
- "eb23ab1ec2c7c8d78aefbfe0aa86fc4a",
+ "0d9085b06bc29cf8fdfb2a04a24a44c2",
"src/libEGL/egl_loader_autogen.cpp":
"9ed54b9c0801cbe9b81746e79baa09bd",
"src/libEGL/egl_loader_autogen.h":
diff --git a/scripts/code_generation_hashes/GL_EGL_entry_points.json b/scripts/code_generation_hashes/GL_EGL_entry_points.json
index e4eca7e117..58dcbccfbc 100644
--- a/scripts/code_generation_hashes/GL_EGL_entry_points.json
+++ b/scripts/code_generation_hashes/GL_EGL_entry_points.json
@@ -1,16 +1,16 @@
{
"scripts/egl_angle_ext.xml":
- "697a927b35f5f48c6a1be5cf56e9f103",
+ "bdd2dcfaa4b6d82e12b6004f1435946d",
"scripts/entry_point_packed_egl_enums.json":
"a72ae855c6b403912103b519139951a1",
"scripts/entry_point_packed_gl_enums.json":
"57a3a729fd25032bc336f4b6a55bc238",
"scripts/generate_entry_points.py":
- "7e554c0ecbbe527501e083b9e0f720b7",
+ "bbb6454f5e67df1f24ed71aa86d26c63",
"scripts/gl_angle_ext.xml":
"197e07a917d5bba6dfa2840fb1b58e7e",
"scripts/registry_xml.py":
- "eb23ab1ec2c7c8d78aefbfe0aa86fc4a",
+ "0d9085b06bc29cf8fdfb2a04a24a44c2",
"src/common/entry_points_enum_autogen.cpp":
"96fad45d19b9fe517fff0ca858a92eff",
"src/common/entry_points_enum_autogen.h":
@@ -158,7 +158,7 @@
"src/libGLESv2/entry_points_gles_1_0_autogen.h":
"1d3aef77845a416497070985a8e9cb31",
"src/libGLESv2/entry_points_gles_2_0_autogen.cpp":
- "19c044201387796e546be26bb554ac48",
+ "a1a5a13754a2720df59375292039abc3",
"src/libGLESv2/entry_points_gles_2_0_autogen.h":
"691c60c2dfed9beca68aa1f32aa2c71b",
"src/libGLESv2/entry_points_gles_3_0_autogen.cpp":
diff --git a/scripts/code_generation_hashes/GLenum_value_to_string_map.json b/scripts/code_generation_hashes/GLenum_value_to_string_map.json
index 5512923268..85e351f3dc 100644
--- a/scripts/code_generation_hashes/GLenum_value_to_string_map.json
+++ b/scripts/code_generation_hashes/GLenum_value_to_string_map.json
@@ -4,7 +4,7 @@
"scripts/gl_angle_ext.xml":
"197e07a917d5bba6dfa2840fb1b58e7e",
"scripts/registry_xml.py":
- "eb23ab1ec2c7c8d78aefbfe0aa86fc4a",
+ "0d9085b06bc29cf8fdfb2a04a24a44c2",
"src/common/gl_enum_utils_autogen.cpp":
"745c4be051eb3d9c93c2116180afb3ca",
"src/common/gl_enum_utils_autogen.h":
diff --git a/scripts/code_generation_hashes/SPIR-V_helpers.json b/scripts/code_generation_hashes/SPIR-V_helpers.json
index 944cf1a2cb..29897bad21 100644
--- a/scripts/code_generation_hashes/SPIR-V_helpers.json
+++ b/scripts/code_generation_hashes/SPIR-V_helpers.json
@@ -1,14 +1,14 @@
{
"src/common/spirv/gen_spirv_builder_and_parser.py":
- "868a697edbc38c95e36be54cf5c71435",
+ "771d70f2fe4c89f325cd22efd0ba9be7",
"src/common/spirv/spirv_instruction_builder_autogen.cpp":
- "c149de371bcd571bd31cc8eb1e517910",
+ "682111aced9eab0828dcb361d6f27b60",
"src/common/spirv/spirv_instruction_builder_autogen.h":
- "56b1309d8afabb2b64d7e16f0c4a4898",
+ "7451dcdf46772d43a6509e4a15d07d80",
"src/common/spirv/spirv_instruction_parser_autogen.cpp":
"388f17f462daa8e091238b4d1fd42ef5",
"src/common/spirv/spirv_instruction_parser_autogen.h":
"58282734b793c994dbe52c3aa988e40e",
- "third_party/vulkan-deps/spirv-headers/src/include/spirv/1.0/spirv.core.grammar.json":
+ "third_party/spirv-headers/src/include/spirv/1.0/spirv.core.grammar.json":
"a8c4239344b2fc10bfc4ace7ddee1867"
}
diff --git a/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json b/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json
index f61e921dff..5811352d5d 100644
--- a/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json
+++ b/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json
@@ -2,13 +2,13 @@
"src/libANGLE/renderer/angle_format.py":
"8269a72cc5629fb2544975b6c36c2bd4",
"src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py":
- "ffb3d44c853669c2c260b96b3808fcf3",
+ "a9fd6f3ff2b584aff382364489146c76",
"src/libANGLE/renderer/vulkan/vk_format_map.json":
"096290d605cbed91ccef9a81bab31984",
"src/libANGLE/renderer/vulkan/vk_mandatory_format_support_data.json":
"fa2bd54c1bb0ab2cf1d386061a4bc5c5",
"src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp":
"96ac9e08704b7a086f7c8db5d213de2b",
- "third_party/vulkan-deps/vulkan-headers/src/registry/vk.xml":
+ "third_party/vulkan-headers/src/registry/vk.xml":
"c63dc0947e72e4b6ee50b5c86c728903"
}
diff --git a/scripts/code_generation_hashes/interpreter_utils.json b/scripts/code_generation_hashes/interpreter_utils.json
index e6ab7a7b7c..1aef4af6e1 100644
--- a/scripts/code_generation_hashes/interpreter_utils.json
+++ b/scripts/code_generation_hashes/interpreter_utils.json
@@ -1,12 +1,12 @@
{
"scripts/egl_angle_ext.xml":
- "697a927b35f5f48c6a1be5cf56e9f103",
+ "bdd2dcfaa4b6d82e12b6004f1435946d",
"scripts/gen_interpreter_utils.py":
"10ba16ee78604763fc883525dd275de8",
"scripts/gl_angle_ext.xml":
"197e07a917d5bba6dfa2840fb1b58e7e",
"scripts/registry_xml.py":
- "eb23ab1ec2c7c8d78aefbfe0aa86fc4a",
+ "0d9085b06bc29cf8fdfb2a04a24a44c2",
"third_party/EGL-Registry/src/api/egl.xml":
"2056d54ea07156f1988ca1366bdee21a",
"third_party/OpenCL-Docs/src/xml/cl.xml":
diff --git a/scripts/code_generation_hashes/proc_table.json b/scripts/code_generation_hashes/proc_table.json
index ee818513f3..49f20ffd85 100644
--- a/scripts/code_generation_hashes/proc_table.json
+++ b/scripts/code_generation_hashes/proc_table.json
@@ -1,12 +1,12 @@
{
"scripts/egl_angle_ext.xml":
- "697a927b35f5f48c6a1be5cf56e9f103",
+ "bdd2dcfaa4b6d82e12b6004f1435946d",
"scripts/gen_proc_table.py":
"073351265b085943f816498cecaa281c",
"scripts/gl_angle_ext.xml":
"197e07a917d5bba6dfa2840fb1b58e7e",
"scripts/registry_xml.py":
- "eb23ab1ec2c7c8d78aefbfe0aa86fc4a",
+ "0d9085b06bc29cf8fdfb2a04a24a44c2",
"src/libGLESv2/proc_table_cl_autogen.cpp":
"ed003b0f041aaaa35b67d3fe07e61f91",
"src/libGLESv2/proc_table_egl_autogen.cpp":
diff --git a/scripts/egl_angle_ext.xml b/scripts/egl_angle_ext.xml
index e323cb717a..4431493a2a 100644
--- a/scripts/egl_angle_ext.xml
+++ b/scripts/egl_angle_ext.xml
@@ -302,6 +302,16 @@
<enum name="EGL_CGL_PIXEL_FORMAT_ANGLE"/>
</require>
</extension>
+ <extension name="EGL_ANGLE_device_d3d9" supported="egl">
+ <require>
+ <enum name="EGL_D3D9_DEVICE_ANGLE"/>
+ </require>
+ </extension>
+ <extension name="EGL_ANGLE_device_d3d1" supported="egl">
+ <require>
+ <enum name="EGL_D3D11_DEVICE_ANGLE"/>
+ </require>
+ </extension>
<extension name="EGL_ANGLE_device_eagl" supported="egl">
<require>
<enum name="EGL_EAGL_CONTEXT_ANGLE"/>
diff --git a/scripts/export_targets.py b/scripts/export_targets.py
index 5a06940715..bd2f5e2e6c 100755
--- a/scripts/export_targets.py
+++ b/scripts/export_targets.py
@@ -194,8 +194,8 @@ IGNORED_INCLUDES = {
b'dirent_on_windows.h',
b'dlopen_fuchsia.h',
b'kernel/image.h',
+ b'libANGLE/renderer/d3d/d3d11/Device11.h',
b'libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h',
- b'libANGLE/renderer/d3d/DeviceD3D.h',
b'libANGLE/renderer/d3d/DisplayD3D.h',
b'libANGLE/renderer/d3d/RenderTargetD3D.h',
b'libANGLE/renderer/gl/cgl/DisplayCGL.h',
diff --git a/scripts/generate_android_bp.py b/scripts/generate_android_bp.py
index bd17c15178..16d2ae844e 100644
--- a/scripts/generate_android_bp.py
+++ b/scripts/generate_android_bp.py
@@ -200,14 +200,22 @@ target_blockist = [
third_party_target_allowlist = [
'//third_party/abseil-cpp',
- '//third_party/vulkan-deps',
+ '//third_party/glslang/src',
+ '//third_party/spirv-cross/src',
+ '//third_party/spirv-headers/src',
+ '//third_party/spirv-tools/src',
+ '//third_party/vulkan-headers/src',
+ '//third_party/vulkan-loader/src',
+ '//third_party/vulkan-tools/src',
+ '//third_party/vulkan-utility-libraries/src',
+ '//third_party/vulkan-validation-layers/src',
'//third_party/vulkan_memory_allocator',
]
include_blocklist = [
'//buildtools/third_party/libc++/',
'//third_party/libc++/src/',
- '//out/Android/gen/third_party/vulkan-deps/glslang/src/include/',
+ '//out/Android/gen/third_party/glslang/src/include/',
'//third_party/zlib/',
'//third_party/zlib/google/',
]
@@ -391,10 +399,8 @@ def gn_action_args_to_blueprint_args(blueprint_inputs, blueprint_outputs, args):
# path. b/150457277
remap_folders = [
# Specific special-cases first, since the other will strip the prefixes.
- ('gen/third_party/vulkan-deps/glslang/src/include/glslang/build_info.h',
- 'glslang/build_info.h'),
- ('third_party/vulkan-deps/glslang/src',
- 'external/angle/third_party/vulkan-deps/glslang/src'),
+ ('gen/third_party/glslang/src/include/glslang/build_info.h', 'glslang/build_info.h'),
+ ('third_party/glslang/src', 'external/angle/third_party/glslang/src'),
('../../', ''),
('gen/', ''),
]
@@ -696,16 +702,15 @@ def main():
'third_party/proguard/LICENSE',
'third_party/r8/LICENSE',
'third_party/turbine/LICENSE',
- 'third_party/vulkan-deps/glslang/LICENSE',
- 'third_party/vulkan-deps/glslang/src/LICENSE.txt',
- 'third_party/vulkan-deps/LICENSE',
- 'third_party/vulkan-deps/spirv-headers/LICENSE',
- 'third_party/vulkan-deps/spirv-headers/src/LICENSE',
- 'third_party/vulkan-deps/spirv-tools/LICENSE',
- 'third_party/vulkan-deps/spirv-tools/src/LICENSE',
- 'third_party/vulkan-deps/spirv-tools/src/utils/vscode/src/lsp/LICENSE',
- 'third_party/vulkan-deps/vulkan-headers/LICENSE.txt',
- 'third_party/vulkan-deps/vulkan-headers/src/LICENSE.md',
+ 'third_party/glslang/LICENSE',
+ 'third_party/glslang/src/LICENSE.txt',
+ 'third_party/spirv-headers/LICENSE',
+ 'third_party/spirv-headers/src/LICENSE',
+ 'third_party/spirv-tools/LICENSE',
+ 'third_party/spirv-tools/src/LICENSE',
+ 'third_party/spirv-tools/src/utils/vscode/src/lsp/LICENSE',
+ 'third_party/vulkan-headers/LICENSE.txt',
+ 'third_party/vulkan-headers/src/LICENSE.md',
'third_party/vulkan_memory_allocator/LICENSE.txt',
'tools/flex-bison/third_party/m4sugar/LICENSE',
'tools/flex-bison/third_party/skeletons/LICENSE',
diff --git a/scripts/generate_entry_points.py b/scripts/generate_entry_points.py
index 0bf5224fa2..35dca1a1cb 100755
--- a/scripts/generate_entry_points.py
+++ b/scripts/generate_entry_points.py
@@ -3095,6 +3095,15 @@ def get_context_lock(api, cmd_name):
if api == apis.GLES and cmd_name.startswith("glEGLImage"):
return "SCOPED_EGL_IMAGE_SHARE_CONTEXT_LOCK(context, imagePacked);"
+ # The following commands do not need to hold the share group lock. Both
+ # validation and their implementation in the context are limited to
+ # context-local state.
+ #
+ # - glBindBuffer: This function looks up the ID in the buffer manager,
+ # access to which is thread-safe for buffers.
+ if cmd_name in ['glBindBuffer']:
+ return ""
+
return "SCOPED_SHARE_CONTEXT_LOCK(context);"
diff --git a/scripts/registry_xml.py b/scripts/registry_xml.py
index ed55ba4ec9..b6e096aab8 100644
--- a/scripts/registry_xml.py
+++ b/scripts/registry_xml.py
@@ -322,6 +322,8 @@ supported_egl_extensions = [
"EGL_ANGLE_d3d_share_handle_client_buffer",
"EGL_ANGLE_device_creation",
"EGL_ANGLE_device_d3d",
+ "EGL_ANGLE_device_d3d11",
+ "EGL_ANGLE_device_d3d9",
"EGL_ANGLE_display_semaphore_share_group",
"EGL_ANGLE_display_texture_share_group",
"EGL_ANGLE_external_context_and_surface",
diff --git a/scripts/roll_aosp.sh b/scripts/roll_aosp.sh
index 8170f3eaf5..32c8bb4be9 100755
--- a/scripts/roll_aosp.sh
+++ b/scripts/roll_aosp.sh
@@ -115,10 +115,10 @@ export PATH=`pwd`/${DEPOT_TOOLS_DIR}:$PATH
third_party_deps=(
"build"
"third_party/abseil-cpp"
- "third_party/vulkan-deps/glslang/src"
- "third_party/vulkan-deps/spirv-headers/src"
- "third_party/vulkan-deps/spirv-tools/src"
- "third_party/vulkan-deps/vulkan-headers/src"
+ "third_party/glslang/src"
+ "third_party/spirv-headers/src"
+ "third_party/spirv-tools/src"
+ "third_party/vulkan-headers/src"
"third_party/vulkan_memory_allocator"
)
@@ -127,9 +127,7 @@ root_add_deps=(
"third_party"
)
-# Only add the parts of NDK and vulkan-deps that are required by ANGLE. The entire dep is too large.
delete_only_deps=(
- "third_party/vulkan-deps"
"third_party/zlib" # Replaced by Android's zlib; delete for gclient to work https://crbug.com/skia/14155#c3
)
@@ -192,10 +190,10 @@ extra_removal_files=(
# Remove Android.mk files to prevent automated CLs:
# "[LSC] Add LOCAL_LICENSE_KINDS to external/angle"
"Android.mk"
- "third_party/vulkan-deps/glslang/src/Android.mk"
- "third_party/vulkan-deps/glslang/src/ndk_test/Android.mk"
- "third_party/vulkan-deps/spirv-tools/src/Android.mk"
- "third_party/vulkan-deps/spirv-tools/src/android_test/Android.mk"
+ "third_party/glslang/src/Android.mk"
+ "third_party/glslang/src/ndk_test/Android.mk"
+ "third_party/spirv-tools/src/Android.mk"
+ "third_party/spirv-tools/src/android_test/Android.mk"
"third_party/siso" # Not needed
)
diff --git a/src/common/PackedEnums.h b/src/common/PackedEnums.h
index 006367b2f7..4a7f34778f 100644
--- a/src/common/PackedEnums.h
+++ b/src/common/PackedEnums.h
@@ -784,12 +784,6 @@ typename std::enable_if<IsResourceIDType<T>::value, bool>::type operator<(const
template <typename ResourceIDType>
GLuint GetIDValue(ResourceIDType id);
-template <>
-inline GLuint GetIDValue(GLuint id)
-{
- return id;
-}
-
template <typename ResourceIDType>
inline GLuint GetIDValue(ResourceIDType id)
{
diff --git a/src/common/SimpleMutex.h b/src/common/SimpleMutex.h
index 5d3c30cb93..84ffa1a1da 100644
--- a/src/common/SimpleMutex.h
+++ b/src/common/SimpleMutex.h
@@ -132,6 +132,13 @@ using SimpleMutex = priv::MutexOnFutex;
using SimpleMutex = priv::MutexOnStd;
#endif
+// A no-op mutex to replace SimpleMutex where a lock is not needed.
+struct NoOpMutex
+{
+ void lock() {}
+ void unlock() {}
+ bool try_lock() { return true; }
+};
} // namespace angle
#endif // COMMON_SIMPLEMUTEX_H_
diff --git a/src/common/SimpleMutex_unittest.cpp b/src/common/SimpleMutex_unittest.cpp
index 72db80a06b..ec8a52d1ac 100644
--- a/src/common/SimpleMutex_unittest.cpp
+++ b/src/common/SimpleMutex_unittest.cpp
@@ -15,12 +15,6 @@ namespace angle
{
namespace
{
-struct NoOpMutex
-{
- void lock() {}
- void unlock() {}
-};
-
template <typename TestMutex>
bool runBasicMutexTest()
{
diff --git a/src/common/mathutil.cpp b/src/common/mathutil.cpp
index 5cbc6a920a..630348923b 100644
--- a/src/common/mathutil.cpp
+++ b/src/common/mathutil.cpp
@@ -50,7 +50,7 @@ unsigned int convertRGBFloatsTo999E5(float red, float green, float blue)
const float green_c = std::max<float>(0, std::min(g_sharedexp_max, green));
const float blue_c = std::max<float>(0, std::min(g_sharedexp_max, blue));
- const float max_c = std::max<float>(std::max<float>(red_c, green_c), blue_c);
+ const float max_c = std::max<float>({red_c, green_c, blue_c});
const float exp_p =
std::max<float>(-g_sharedexp_bias - 1, floor(log(max_c))) + 1 + g_sharedexp_bias;
const int max_s = static_cast<int>(
diff --git a/src/common/spirv/gen_spirv_builder_and_parser.py b/src/common/spirv/gen_spirv_builder_and_parser.py
index c7e1f401b3..01335a026f 100755
--- a/src/common/spirv/gen_spirv_builder_and_parser.py
+++ b/src/common/spirv/gen_spirv_builder_and_parser.py
@@ -13,10 +13,10 @@ import os
import sys
# ANGLE uses SPIR-V 1.0 currently, so there's no reason to generate code for newer instructions.
-SPIRV_GRAMMAR_FILE = '../../../third_party/vulkan-deps/spirv-headers/src/include/spirv/1.0/spirv.core.grammar.json'
+SPIRV_GRAMMAR_FILE = '../../../third_party/spirv-headers/src/include/spirv/1.0/spirv.core.grammar.json'
# Cherry pick some extra extensions from here that aren't in SPIR-V 1.0.
-SPIRV_CHERRY_PICKED_EXTENSIONS_FILE = '../../../third_party/vulkan-deps/spirv-headers/src/include/spirv/unified1/spirv.core.grammar.json'
+SPIRV_CHERRY_PICKED_EXTENSIONS_FILE = '../../../third_party/spirv-headers/src/include/spirv/unified1/spirv.core.grammar.json'
# The script has two sets of outputs, a header and source file for SPIR-V code generation, and a
# header and source file for SPIR-V parsing.
@@ -106,12 +106,12 @@ uint32_t MakeLengthOp(size_t length, spv::Op op)
}
} // anonymous namespace
-void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t idCount)
+void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t version, uint32_t idCount)
{
// Header:
//
// - Magic number
- // - Version (1.0)
+ // - Version (1.X)
// - ANGLE's Generator number:
// * 24 for tool id (higher 16 bits)
// * 1 for tool version (lower 16 bits))
@@ -123,7 +123,7 @@ void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t idCount)
ASSERT(blob->empty());
blob->push_back(spv::MagicNumber);
- blob->push_back(0x00010000);
+ blob->push_back(version);
blob->push_back(kANGLEGeneratorId << 16 | kANGLEGeneratorVersion);
blob->push_back(idCount);
blob->push_back(0x00000000);
@@ -131,7 +131,7 @@ void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t idCount)
"""
BUILDER_HELPER_FUNCTION_PROTOTYPE = """
- void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t idCount);
+ void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t version, uint32_t idCount);
"""
PARSER_FIXED_FUNCTIONS_PROTOTYPES = """void GetInstructionOpAndLength(const uint32_t *_instruction,
diff --git a/src/common/spirv/spirv_instruction_builder_autogen.cpp b/src/common/spirv/spirv_instruction_builder_autogen.cpp
index 6e6ad6f510..c63aed55c3 100644
--- a/src/common/spirv/spirv_instruction_builder_autogen.cpp
+++ b/src/common/spirv/spirv_instruction_builder_autogen.cpp
@@ -38,12 +38,12 @@ uint32_t MakeLengthOp(size_t length, spv::Op op)
}
} // anonymous namespace
-void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t idCount)
+void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t version, uint32_t idCount)
{
// Header:
//
// - Magic number
- // - Version (1.0)
+ // - Version (1.X)
// - ANGLE's Generator number:
// * 24 for tool id (higher 16 bits)
// * 1 for tool version (lower 16 bits))
@@ -55,7 +55,7 @@ void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t idCount)
ASSERT(blob->empty());
blob->push_back(spv::MagicNumber);
- blob->push_back(0x00010000);
+ blob->push_back(version);
blob->push_back(kANGLEGeneratorId << 16 | kANGLEGeneratorVersion);
blob->push_back(idCount);
blob->push_back(0x00000000);
diff --git a/src/common/spirv/spirv_instruction_builder_autogen.h b/src/common/spirv/spirv_instruction_builder_autogen.h
index 1caf5cd204..7ecfd0a1ce 100644
--- a/src/common/spirv/spirv_instruction_builder_autogen.h
+++ b/src/common/spirv/spirv_instruction_builder_autogen.h
@@ -20,7 +20,7 @@ namespace angle
namespace spirv
{
-void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t idCount);
+void WriteSpirvHeader(std::vector<uint32_t> *blob, uint32_t version, uint32_t idCount);
void WriteNop(Blob *blob);
void WriteUndef(Blob *blob, IdResultType idResultType, IdResult idResult);
void WriteSourceContinued(Blob *blob, LiteralString continuedSource);
diff --git a/src/common/spirv/spirv_types.h b/src/common/spirv/spirv_types.h
index c97e4db477..b27befdbaa 100644
--- a/src/common/spirv/spirv_types.h
+++ b/src/common/spirv/spirv_types.h
@@ -125,6 +125,11 @@ enum HeaderIndex
kHeaderIndexInstructions = 5,
};
+// SPIR-V version
+constexpr uint32_t kVersion_1_0 = 0x00010000;
+constexpr uint32_t kVersion_1_3 = 0x00010300;
+constexpr uint32_t kVersion_1_4 = 0x00010400;
+
// Returns whether SPIR-V is valid. Useful for ASSERTs. Automatically generates a warning if
// SPIR-V is not valid.
bool Validate(const Blob &blob);
diff --git a/src/compiler/translator/hlsl/ResourcesHLSL.h b/src/compiler/translator/hlsl/ResourcesHLSL.h
index d5842a3d57..9541c9d923 100644
--- a/src/compiler/translator/hlsl/ResourcesHLSL.h
+++ b/src/compiler/translator/hlsl/ResourcesHLSL.h
@@ -147,8 +147,8 @@ class ResourcesHLSL : angle::NonCopyable
std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, bool> mUniformBlockUseStructuredBufferMap;
- unsigned int mReadonlyImage2DRegisterIndex;
- unsigned int mImage2DRegisterIndex;
+ unsigned int mReadonlyImage2DRegisterIndex = 0;
+ unsigned int mImage2DRegisterIndex = 0;
};
} // namespace sh
diff --git a/src/compiler/translator/msl/IdGen.cpp b/src/compiler/translator/msl/IdGen.cpp
index b74e71bdd9..88435df198 100644
--- a/src/compiler/translator/msl/IdGen.cpp
+++ b/src/compiler/translator/msl/IdGen.cpp
@@ -31,10 +31,6 @@ Name IdGen::createNewName(size_t count,
mNewNameBuffer += '_';
mNewNameBuffer += idBuffer;
- // Note:
- // Double underscores are only allowed in C++ (and thus Metal) vendor identifiers, so here we
- // take care not to introduce any.
-
for (size_t i = 0; i < count; ++i)
{
const ImmutableString baseName = toImmutable(baseNames[i]);
@@ -43,19 +39,15 @@ Name IdGen::createNewName(size_t count,
const char *base = baseName.data();
if (baseName.beginsWith(kAngleInternalPrefix))
{
+ // skip 'ANGLE' or 'ANGLE_' prefix
base += sizeof(kAngleInternalPrefix) - 1;
- }
- if (*base == '_')
- {
- ++base;
- }
- ASSERT(*base != '_');
-
- if (mNewNameBuffer.back() != '_')
- {
- mNewNameBuffer += '_';
+ if (*base == '_')
+ {
+ ++base;
+ }
}
+ mNewNameBuffer += '_';
mNewNameBuffer += base;
}
}
diff --git a/src/compiler/translator/spirv/BuildSPIRV.cpp b/src/compiler/translator/spirv/BuildSPIRV.cpp
index 8edf4bb11b..b79b99b291 100644
--- a/src/compiler/translator/spirv/BuildSPIRV.cpp
+++ b/src/compiler/translator/spirv/BuildSPIRV.cpp
@@ -2321,7 +2321,7 @@ spirv::Blob SPIRVBuilder::getSpirv()
mSpirvFunctions.size());
// Generate the SPIR-V header.
- spirv::WriteSpirvHeader(&result, mNextAvailableId);
+ spirv::WriteSpirvHeader(&result, spirv::kVersion_1_0, mNextAvailableId);
// Generate metadata in the following order:
//
diff --git a/src/compiler/translator/tree_ops/msl/SeparateCompoundExpressions.cpp b/src/compiler/translator/tree_ops/msl/SeparateCompoundExpressions.cpp
index a3dc0567a6..49eaec47c3 100644
--- a/src/compiler/translator/tree_ops/msl/SeparateCompoundExpressions.cpp
+++ b/src/compiler/translator/tree_ops/msl/SeparateCompoundExpressions.cpp
@@ -635,7 +635,7 @@ class Separator : public TIntermRebuild
PostResult visitConstantUnionPost(TIntermConstantUnion &node) override
{
const TType &type = node.getType();
- if (!type.isScalar())
+ if (!type.isScalar() && !type.isVector() && !type.isMatrix())
{
pushBinding(node, node);
}
diff --git a/src/image_util/loadimage_etc.cpp b/src/image_util/loadimage_etc.cpp
index 16737501ba..b517899296 100644
--- a/src/image_util/loadimage_etc.cpp
+++ b/src/image_util/loadimage_etc.cpp
@@ -1141,7 +1141,7 @@ struct ETC2Block
// From the eigenvalue and eigenvector, choose the axis to project
// colors on. When projecting colors we want to do integer computations
// for speed, so we normalize the eigenvector to the [0, 512] range.
- float magn = std::max(std::max(std::abs(vfr), std::abs(vfg)), std::abs(vfb));
+ float magn = std::max({std::abs(vfr), std::abs(vfg), std::abs(vfb)});
magn = kQuantizeRange / magn;
vr = static_cast<int>(vfr * magn);
vg = static_cast<int>(vfg * magn);
diff --git a/src/libANGLE/Buffer.cpp b/src/libANGLE/Buffer.cpp
index 876b1921c4..43452e79cb 100644
--- a/src/libANGLE/Buffer.cpp
+++ b/src/libANGLE/Buffer.cpp
@@ -67,6 +67,13 @@ void Buffer::onDestroy(const Context *context)
void Buffer::onBind(const Context *context, BufferBinding target)
{
+ // Note: this function is called from glBindBuffer, which does not hold the share group lock.
+ // However, it only affects webgl contexts, where browsers already guarantees thread safety.
+ if (!context->isWebGL())
+ {
+ return;
+ }
+
if (mState.mWebGLType == WebGLBufferType::Undefined)
{
if (target == BufferBinding::ElementArray)
diff --git a/src/libANGLE/Buffer.h b/src/libANGLE/Buffer.h
index 61c7fb3a75..507f6c333a 100644
--- a/src/libANGLE/Buffer.h
+++ b/src/libANGLE/Buffer.h
@@ -93,7 +93,7 @@ ANGLE_INLINE bool operator==(const ContentsObserver &lhs, const ContentsObserver
return lhs.bufferIndex == rhs.bufferIndex && lhs.observer == rhs.observer;
}
-class Buffer final : public RefCountObject<BufferID>,
+class Buffer final : public ThreadSafeRefCountObject<BufferID>,
public LabeledObject,
public angle::ObserverInterface,
public angle::Subject
diff --git a/src/libANGLE/Caps.cpp b/src/libANGLE/Caps.cpp
index 659be9a991..5e04cc8de5 100644
--- a/src/libANGLE/Caps.cpp
+++ b/src/libANGLE/Caps.cpp
@@ -1361,6 +1361,8 @@ std::vector<std::string> DeviceExtensions::getStrings() const
// clang-format off
// | Extension name | Supported flag | Output vector |
InsertExtensionString("EGL_ANGLE_device_d3d", deviceD3D, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_d3d9", deviceD3D9, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_d3d11", deviceD3D11, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_cgl", deviceCGL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_eagl", deviceEAGL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_metal", deviceMetal, &extensionStrings);
diff --git a/src/libANGLE/Caps.h b/src/libANGLE/Caps.h
index 5cfe3a88bd..c8b1722e51 100644
--- a/src/libANGLE/Caps.h
+++ b/src/libANGLE/Caps.h
@@ -700,6 +700,12 @@ struct DeviceExtensions
// EGL_ANGLE_device_d3d
bool deviceD3D = false;
+ // EGL_ANGLE_device_d3d9
+ bool deviceD3D9 = false;
+
+ // EGL_ANGLE_device_d3d11
+ bool deviceD3D11 = false;
+
// EGL_ANGLE_device_cgl
bool deviceCGL = false;
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 5eda734ca6..77f4bd999e 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -664,7 +664,21 @@ Context::Context(egl::Display *display,
egl::Error Context::initialize()
{
if (!mImplementation)
+ {
return egl::Error(EGL_NOT_INITIALIZED, "native context creation failed");
+ }
+
+ // If the final context version created (with backwards compatibility possibly added in),
+ // generate an error if it's higher than the maximum supported version for the display. This
+ // validation is always done even with EGL validation disabled because it's not possible to
+ // detect ahead of time if an ES 3.1 context is supported (no ES_31_BIT) or if
+ // KHR_no_config_context is used.
+ if (getClientType() == EGL_OPENGL_ES_API &&
+ getClientVersion() > getDisplay()->getMaxSupportedESVersion())
+ {
+ return egl::Error(EGL_BAD_ATTRIBUTE, "Requested version is not supported");
+ }
+
return egl::NoError();
}
diff --git a/src/libANGLE/Device.cpp b/src/libANGLE/Device.cpp
index 5acb3b56f3..ab509174be 100644
--- a/src/libANGLE/Device.cpp
+++ b/src/libANGLE/Device.cpp
@@ -20,7 +20,7 @@
#include "libANGLE/renderer/DeviceImpl.h"
#if defined(ANGLE_ENABLE_D3D11)
-# include "libANGLE/renderer/d3d/DeviceD3D.h"
+# include "libANGLE/renderer/d3d/d3d11/Device11.h"
#endif
namespace egl
@@ -54,7 +54,7 @@ egl::Error Device::CreateDevice(EGLint deviceType, void *nativeDevice, Device **
#if defined(ANGLE_ENABLE_D3D11)
if (deviceType == EGL_D3D11_DEVICE_ANGLE)
{
- newDeviceImpl.reset(new rx::DeviceD3D(deviceType, nativeDevice));
+ newDeviceImpl.reset(new rx::Device11(nativeDevice));
}
#endif
@@ -110,11 +110,6 @@ Error Device::getAttribute(EGLint attribute, EGLAttrib *value)
return error;
}
-EGLint Device::getType() const
-{
- return mImplementation.get()->getType();
-}
-
void Device::initDeviceExtensions()
{
mImplementation->generateExtensions(&mDeviceExtensions);
diff --git a/src/libANGLE/Device.h b/src/libANGLE/Device.h
index 51799ce867..f50667f521 100644
--- a/src/libANGLE/Device.h
+++ b/src/libANGLE/Device.h
@@ -34,7 +34,6 @@ class Device final : public LabeledObject, angle::NonCopyable
Error getAttribute(EGLint attribute, EGLAttrib *value);
Display *getOwningDisplay() const { return mOwningDisplay; }
- EGLint getType() const;
const DeviceExtensions &getExtensions() const;
const std::string &getExtensionString() const;
diff --git a/src/libANGLE/Display.cpp b/src/libANGLE/Display.cpp
index 9ebd571e84..1ce16e6180 100644
--- a/src/libANGLE/Display.cpp
+++ b/src/libANGLE/Display.cpp
@@ -244,28 +244,25 @@ rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &
{
rx::DisplayImpl *impl = nullptr;
- switch (eglDevice->getType())
- {
#if defined(ANGLE_ENABLE_D3D11)
- case EGL_D3D11_DEVICE_ANGLE:
- impl = new rx::DisplayD3D(state);
- break;
+ if (eglDevice->getExtensions().deviceD3D11)
+ {
+ impl = new rx::DisplayD3D(state);
+ }
#endif
+
#if defined(ANGLE_ENABLE_D3D9)
- case EGL_D3D9_DEVICE_ANGLE:
- // Currently the only way to get EGLDeviceEXT representing a D3D9 device
- // is to retrieve one from an already-existing EGLDisplay.
- // When eglGetPlatformDisplayEXT is called with a D3D9 EGLDeviceEXT,
- // the already-existing display should be returned.
- // Therefore this codepath to create a new display from the device
- // should never be hit.
- UNREACHABLE();
- break;
-#endif
- default:
- UNREACHABLE();
- break;
+ if (eglDevice->getExtensions().deviceD3D9)
+ {
+ // Currently the only way to get EGLDeviceEXT representing a D3D9 device
+ // is to retrieve one from an already-existing EGLDisplay.
+ // When eglGetPlatformDisplayEXT is called with a D3D9 EGLDeviceEXT,
+ // the already-existing display should be returned.
+ // Therefore this codepath to create a new display from the device
+ // should never be hit.
+ UNREACHABLE();
}
+#endif
ASSERT(impl != nullptr);
return impl;
diff --git a/src/libANGLE/ProgramExecutable.cpp b/src/libANGLE/ProgramExecutable.cpp
index 6c6ce121d1..d7a06c2960 100644
--- a/src/libANGLE/ProgramExecutable.cpp
+++ b/src/libANGLE/ProgramExecutable.cpp
@@ -745,6 +745,14 @@ void ProgramExecutable::destroy(const Context *context)
{
ASSERT(mImplementation != nullptr);
+ for (SharedProgramExecutable &executable : mPPOProgramExecutables)
+ {
+ if (executable)
+ {
+ UninstallExecutable(context, &executable);
+ }
+ }
+
mImplementation->destroy(context);
SafeDelete(mImplementation);
}
diff --git a/src/libANGLE/ProgramExecutable.h b/src/libANGLE/ProgramExecutable.h
index d7a9252610..519b115f3d 100644
--- a/src/libANGLE/ProgramExecutable.h
+++ b/src/libANGLE/ProgramExecutable.h
@@ -993,6 +993,10 @@ class ProgramExecutable final : public angle::Subject
// been modified.
UniformBufferBindingArray<ProgramUniformBlockMask> mUniformBufferBindingToUniformBlocks;
+ // PPO only: installed executables from the programs. Note that these may be different from the
+ // programs' current executables, because they may have been unsuccessfully relinked.
+ ShaderMap<SharedProgramExecutable> mPPOProgramExecutables;
+
// Cache for sampler validation
mutable Optional<bool> mCachedValidateSamplersResult;
diff --git a/src/libANGLE/ProgramPipeline.cpp b/src/libANGLE/ProgramPipeline.cpp
index 6d1e312f74..9d7cd66a6c 100644
--- a/src/libANGLE/ProgramPipeline.cpp
+++ b/src/libANGLE/ProgramPipeline.cpp
@@ -66,10 +66,11 @@ void ProgramPipelineState::useProgramStage(const Context *context,
{
mPrograms[shaderType] = shaderProgram;
// Install the program executable, if not already
- if (shaderProgram->getSharedExecutable().get() != mProgramExecutables[shaderType].get())
+ if (shaderProgram->getSharedExecutable().get() !=
+ mExecutable->mPPOProgramExecutables[shaderType].get())
{
InstallExecutable(context, shaderProgram->getSharedExecutable(),
- &mProgramExecutables[shaderType]);
+ &mExecutable->mPPOProgramExecutables[shaderType]);
}
shaderProgram->addRef();
}
@@ -79,11 +80,11 @@ void ProgramPipelineState::useProgramStage(const Context *context,
// given stage, it is as if the pipeline object has no programmable stage configured for the
// indicated shader stage.
mPrograms[shaderType] = nullptr;
- UninstallExecutable(context, &mProgramExecutables[shaderType]);
+ UninstallExecutable(context, &mExecutable->mPPOProgramExecutables[shaderType]);
}
programObserverBinding->bind(mPrograms[shaderType]);
- programExecutableObserverBinding->bind(mProgramExecutables[shaderType].get());
+ programExecutableObserverBinding->bind(mExecutable->mPPOProgramExecutables[shaderType].get());
}
void ProgramPipelineState::useProgramStages(
@@ -175,14 +176,6 @@ void ProgramPipeline::onDestroy(const Context *context)
getImplementation()->destroy(context);
UninstallExecutable(context, &mState.mExecutable);
- for (SharedProgramExecutable &executable : mState.mProgramExecutables)
- {
- if (executable)
- {
- mState.mProgramExecutablesToDiscard.emplace_back(std::move(executable));
- }
- }
-
mState.destroyDiscardedExecutables(context);
}
@@ -505,10 +498,11 @@ angle::Result ProgramPipeline::link(const Context *context)
mState.destroyDiscardedExecutables(context);
// Make a new executable to hold the result of the link.
- InstallExecutable(
- context,
- std::make_shared<ProgramExecutable>(context->getImplementation(), &mState.mInfoLog),
- &mState.mExecutable);
+ SharedProgramExecutable newExecutable =
+ std::make_shared<ProgramExecutable>(context->getImplementation(), &mState.mInfoLog);
+ newExecutable->mPPOProgramExecutables = std::move(mState.mExecutable->mPPOProgramExecutables);
+
+ InstallExecutable(context, newExecutable, &mState.mExecutable);
onStateChange(angle::SubjectMessage::ProgramUnlinked);
updateLinkedShaderStages();
@@ -597,7 +591,7 @@ angle::Result ProgramPipeline::link(const Context *context)
}
// Merge uniforms.
- mState.mExecutable->copyUniformsFromProgramMap(mState.mProgramExecutables);
+ mState.mExecutable->copyUniformsFromProgramMap(mState.mExecutable->mPPOProgramExecutables);
if (mState.mExecutable->hasLinkedShaderStage(ShaderType::Vertex))
{
@@ -785,12 +779,12 @@ void ProgramPipeline::onSubjectStateChange(angle::SubjectIndex index, angle::Sub
{
ShaderType shaderType = static_cast<ShaderType>(index);
ASSERT(mState.mPrograms[shaderType] != nullptr);
- ASSERT(mState.mProgramExecutables[shaderType]);
+ ASSERT(mState.mExecutable->mPPOProgramExecutables[shaderType]);
mState.mIsLinked = false;
mState.mProgramExecutablesToDiscard.emplace_back(
- std::move(mState.mProgramExecutables[shaderType]));
- mState.mProgramExecutables[shaderType] =
+ std::move(mState.mExecutable->mPPOProgramExecutables[shaderType]));
+ mState.mExecutable->mPPOProgramExecutables[shaderType] =
mState.mPrograms[shaderType]->getSharedExecutable();
break;
diff --git a/src/libANGLE/ProgramPipeline.h b/src/libANGLE/ProgramPipeline.h
index 2425e587ef..35d07552c8 100644
--- a/src/libANGLE/ProgramPipeline.h
+++ b/src/libANGLE/ProgramPipeline.h
@@ -64,7 +64,7 @@ class ProgramPipelineState final : angle::NonCopyable
const Program *getShaderProgram(ShaderType shaderType) const { return mPrograms[shaderType]; }
const SharedProgramExecutable &getShaderProgramExecutable(ShaderType shaderType) const
{
- return mProgramExecutables[shaderType];
+ return mExecutable->mPPOProgramExecutables[shaderType];
}
bool usesShaderProgram(ShaderProgramID program) const;
@@ -90,10 +90,6 @@ class ProgramPipelineState final : angle::NonCopyable
// The shader programs for each stage.
ShaderMap<Program *> mPrograms;
- // Installed executables from the programs. Note that these may be different from the programs'
- // current executables, because they may have been unsuccessfully relinked.
- ShaderMap<SharedProgramExecutable> mProgramExecutables;
-
// Mapping from program's UBOs into the program executable's UBOs.
ShaderMap<ProgramUniformBlockArray<GLuint>> mUniformBlockMap;
diff --git a/src/libANGLE/RefCountObject.h b/src/libANGLE/RefCountObject.h
index d01677f58f..b01efcb336 100644
--- a/src/libANGLE/RefCountObject.h
+++ b/src/libANGLE/RefCountObject.h
@@ -68,12 +68,12 @@ class ThreadSafeRefCountObject : angle::NonCopyable
virtual void onDestroy(const ContextType *context) {}
- void addRef() const { ++mRefCount; }
+ void addRef() const { mRefCount.fetch_add(1, std::memory_order_relaxed); }
ANGLE_INLINE void release(const ContextType *context)
{
ASSERT(mRefCount > 0);
- if (mRefCount.fetch_sub(1) == 1)
+ if (mRefCount.fetch_sub(1, std::memory_order_acq_rel) == 1)
{
onDestroy(context);
delete this;
@@ -206,10 +206,11 @@ class Context;
template <class ObjectType>
class BindingPointer;
-using RefCountObjectNoID = angle::RefCountObject<Context, angle::Result>;
+using RefCountObjectNoID = angle::RefCountObject<Context, angle::Result>;
+using ThreadSafeRefCountObjectNoID = angle::ThreadSafeRefCountObject<Context, angle::Result>;
-template <typename IDType>
-class RefCountObject : public gl::RefCountObjectNoID
+template <typename IDType, typename RC = RefCountObjectNoID>
+class RefCountObject : public RC
{
public:
explicit RefCountObject(rx::UniqueSerial serial, IDType id) : mSerial(serial), mId(id) {}
@@ -225,6 +226,8 @@ class RefCountObject : public gl::RefCountObjectNoID
rx::UniqueSerial mSerial;
IDType mId;
};
+template <typename IDType>
+using ThreadSafeRefCountObject = RefCountObject<IDType, ThreadSafeRefCountObjectNoID>;
template <class ObjectType>
class BindingPointer : public angle::BindingPointer<ObjectType, Context>
diff --git a/src/libANGLE/ResourceManager.cpp b/src/libANGLE/ResourceManager.cpp
index bf0c93d59e..60a1be10f6 100644
--- a/src/libANGLE/ResourceManager.cpp
+++ b/src/libANGLE/ResourceManager.cpp
@@ -61,7 +61,8 @@ void ResourceManagerBase::release(const Context *context)
template <typename ResourceType, typename ImplT, typename IDType>
TypedResourceManager<ResourceType, ImplT, IDType>::~TypedResourceManager()
{
- ASSERT(UnsafeResourceMapIter(mObjectMap).empty());
+ using UnsafeResourceMapIterTyped = UnsafeResourceMapIter<ResourceType, IDType>;
+ ASSERT(UnsafeResourceMapIterTyped(mObjectMap).empty());
}
template <typename ResourceType, typename ImplT, typename IDType>
diff --git a/src/libANGLE/ResourceMap.h b/src/libANGLE/ResourceMap.h
index 92d6b6251d..5604cd49c9 100644
--- a/src/libANGLE/ResourceMap.h
+++ b/src/libANGLE/ResourceMap.h
@@ -11,10 +11,99 @@
#ifndef LIBANGLE_RESOURCE_MAP_H_
#define LIBANGLE_RESOURCE_MAP_H_
+#include <mutex>
+#include <type_traits>
+
+#include "common/SimpleMutex.h"
#include "libANGLE/angletypes.h"
namespace gl
{
+// The resource map needs to be internally synchronized for maps that are placed in the share group
+// (as opposed to being private to the context) and that are accessed without holding the share
+// group lock.
+#if defined(ANGLE_ENABLE_SHARE_CONTEXT_LOCK)
+using ResourceMapMutex = angle::SimpleMutex;
+#else
+using ResourceMapMutex = angle::NoOpMutex;
+#endif
+
+template <bool NeedsLock = true>
+struct SelectResourceMapMutex
+{
+ using type = ResourceMapMutex;
+};
+
+template <>
+struct SelectResourceMapMutex<false>
+{
+ using type = angle::NoOpMutex;
+};
+
+// Analysis of ANGLE's traces as well as Chrome usage reveals the following:
+//
+// - Buffers: Typical applications use no more than 4000 ids. Very few use over 6000.
+// - Textures: Typical applications use no more than 1200 ids. Very few use over 2000.
+// - Samplers: Typical applications use no more than 50 ids. Very few use over 100.
+// - Shaders and Programs: Typical applications use no more than 500. Very few use over 700.
+// - Sync objects: Typical applications use no more than 500. Very few use over 1500.
+//
+// For all the other shared types, the maximum used id is small (under 100). For
+// context-private parts (such as vertex arrays and queries), the id count can be in the
+// thousands.
+//
+// The initial size of the flat resource map is based on the above, rounded up to a multiple of
+// 1536. Resource maps that need a lock (kNeedsLock == true) have the maximum flat size identical
+// to initial flat size to avoid reallocation. For others, the maps start small and can grow.
+template <typename IDType>
+struct ResourceMapParams
+{
+ static constexpr size_t kInitialFlatResourcesSize = 192;
+
+ // The following are private to the context and don't need a lock:
+ //
+ // - Vertex Array Objects
+ // - Framebuffer Objects
+ // - Transform Feedback Objects
+ // - Query Objects
+ //
+ // The rest of the maps need a lock. However, only a select few are currently locked as API
+ // relevant to the rest of the types are protected by the share group lock. As the share group
+ // lock is removed from more types, the resource map lock needs to be enabled for them.
+ static constexpr bool kNeedsLock = false;
+};
+template <>
+struct ResourceMapParams<BufferID>
+{
+ static constexpr size_t kInitialFlatResourcesSize = 6144;
+ static constexpr bool kNeedsLock = true;
+};
+template <>
+struct ResourceMapParams<TextureID>
+{
+ static constexpr size_t kInitialFlatResourcesSize = 1536;
+ static constexpr bool kNeedsLock = false;
+};
+template <>
+struct ResourceMapParams<ShaderProgramID>
+{
+ static constexpr size_t kInitialFlatResourcesSize = 1536;
+ static constexpr bool kNeedsLock = false;
+};
+template <>
+struct ResourceMapParams<SyncID>
+{
+ static constexpr size_t kInitialFlatResourcesSize = 1536;
+ static constexpr bool kNeedsLock = false;
+};
+// For the purpose of unit testing, |int| is considered private (not needing lock), and
+// |unsigned int| is considered shared (needing lock).
+template <>
+struct ResourceMapParams<unsigned int>
+{
+ static constexpr size_t kInitialFlatResourcesSize = 192;
+ static constexpr bool kNeedsLock = true;
+};
template <typename ResourceType, typename IDType>
class ResourceMap final : angle::NonCopyable
@@ -26,11 +115,18 @@ class ResourceMap final : angle::NonCopyable
ANGLE_INLINE ResourceType *query(IDType id) const
{
GLuint handle = GetIDValue(id);
+ // No need for a lock when accessing the flat map. Either the flat map is static, or
+ // locking is not needed.
+ static_assert(!kNeedsLock || kInitialFlatResourcesSize == kFlatResourcesLimit);
+
if (handle < mFlatResourcesSize)
{
ResourceType *value = mFlatResources[handle];
return (value == InvalidPointer() ? nullptr : value);
}
+
+ std::lock_guard<Mutex> lock(mMutex);
+
auto it = mHashedResources.find(handle);
return (it == mHashedResources.end() ? nullptr : it->second);
}
@@ -92,20 +188,43 @@ class ResourceMap final : angle::NonCopyable
static ResourceType *InvalidPointer();
static constexpr intptr_t kInvalidPointer = static_cast<intptr_t>(-1);
- // Start with 32 maximum elements in the map, which can grow.
- static constexpr size_t kInitialFlatResourcesSize = 0x20;
+ static constexpr bool kNeedsLock = ResourceMapParams<IDType>::kNeedsLock;
+ using Mutex = typename SelectResourceMapMutex<kNeedsLock>::type;
- // Experimental testing suggests that 16k is a reasonable upper limit.
- static constexpr size_t kFlatResourcesLimit = 0x4000;
+ static constexpr size_t kInitialFlatResourcesSize =
+ ResourceMapParams<IDType>::kInitialFlatResourcesSize;
- // Size of one map element.
- static constexpr size_t kElementSize = sizeof(ResourceType *);
+ // Experimental testing suggests that ~10k is a reasonable upper limit.
+ static constexpr size_t kFlatResourcesLimit = kNeedsLock ? kInitialFlatResourcesSize : 0x3000;
+ // Due to the way assign() is implemented, kFlatResourcesLimit / kInitialFlatResourcesSize must
+ // be a power of 2.
+ static_assert(kFlatResourcesLimit % kInitialFlatResourcesSize == 0);
+ static_assert(((kFlatResourcesLimit / kInitialFlatResourcesSize) &
+ (kFlatResourcesLimit / kInitialFlatResourcesSize - 1)) == 0);
size_t mFlatResourcesSize;
ResourceType **mFlatResources;
// A map of GL objects indexed by object ID.
HashMap mHashedResources;
+
+ // mFlatResources is allocated at object creation time, with a default size of
+ // |kInitialFlatResourcesSize|. This is thread safe, because the allocation is done by the
+ // first context in the share group. The flat map is allowed to grow up to
+ // |kFlatResourcesLimit|, but only for maps that don't need a lock (kNeedsLock == false).
+ //
+ // For maps that don't need a lock, this mutex is a no-op. For those that do, the mutex is
+ // taken when allocating / deleting objects, as well as when accessing |mHashedResources|.
+ // Otherwise, access to the flat map (which never gets reallocated due to
+ // |kInitialFlatResourcesSize == kFlatResourcesLimit|) is lockless. This latter is possible
+ // because the application is not allowed to gen/delete and bind the same ID in different
+ // threads at the same time.
+ //
+ // Note that because HandleAllocator is not yet thread-safe, glGen* and glDelete* functions
+ // cannot be free of the share group mutex yet. To remove the share group mutex from those
+ // functions, likely the HandleAllocator class should be merged with this class, and the
+ // necessary insert/erase operations done under this same lock.
+ mutable Mutex mMutex;
};
// A helper to retrieve the resource map iterators while being explicit that this is not thread
@@ -137,13 +256,13 @@ ResourceMap<ResourceType, IDType>::ResourceMap()
: mFlatResourcesSize(kInitialFlatResourcesSize),
mFlatResources(new ResourceType *[kInitialFlatResourcesSize])
{
- memset(mFlatResources, kInvalidPointer, mFlatResourcesSize * kElementSize);
+ memset(mFlatResources, kInvalidPointer, mFlatResourcesSize * sizeof(mFlatResources[0]));
}
template <typename ResourceType, typename IDType>
ResourceMap<ResourceType, IDType>::~ResourceMap()
{
- ASSERT(UnsafeResourceMapIter(*this).empty());
+ ASSERT(begin() == end());
delete[] mFlatResources;
}
@@ -153,9 +272,10 @@ ANGLE_INLINE bool ResourceMap<ResourceType, IDType>::contains(IDType id) const
GLuint handle = GetIDValue(id);
if (handle < mFlatResourcesSize)
{
- return (mFlatResources[handle] != InvalidPointer());
+ return mFlatResources[handle] != InvalidPointer();
}
- return (mHashedResources.find(handle) != mHashedResources.end());
+ std::lock_guard<Mutex> lock(mMutex);
+ return mHashedResources.find(handle) != mHashedResources.end();
}
template <typename ResourceType, typename IDType>
@@ -174,6 +294,8 @@ bool ResourceMap<ResourceType, IDType>::erase(IDType id, ResourceType **resource
}
else
{
+ std::lock_guard<Mutex> lock(mMutex);
+
auto it = mHashedResources.find(handle);
if (it == mHashedResources.end())
{
@@ -193,6 +315,9 @@ void ResourceMap<ResourceType, IDType>::assign(IDType id, ResourceType *resource
{
if (handle >= mFlatResourcesSize)
{
+ // No need for a lock as the flat map never grows when locking is needed.
+ static_assert(!kNeedsLock || kInitialFlatResourcesSize == kFlatResourcesLimit);
+
// Use power-of-two.
size_t newSize = mFlatResourcesSize;
while (newSize <= handle)
@@ -204,8 +329,8 @@ void ResourceMap<ResourceType, IDType>::assign(IDType id, ResourceType *resource
mFlatResources = new ResourceType *[newSize];
memset(&mFlatResources[mFlatResourcesSize], kInvalidPointer,
- (newSize - mFlatResourcesSize) * kElementSize);
- memcpy(mFlatResources, oldResources, mFlatResourcesSize * kElementSize);
+ (newSize - mFlatResourcesSize) * sizeof(mFlatResources[0]));
+ memcpy(mFlatResources, oldResources, mFlatResourcesSize * sizeof(mFlatResources[0]));
mFlatResourcesSize = newSize;
delete[] oldResources;
}
@@ -214,6 +339,7 @@ void ResourceMap<ResourceType, IDType>::assign(IDType id, ResourceType *resource
}
else
{
+ std::lock_guard<Mutex> lock(mMutex);
mHashedResources[handle] = resource;
}
}
@@ -254,7 +380,8 @@ bool UnsafeResourceMapIter<ResourceType, IDType>::empty() const
template <typename ResourceType, typename IDType>
void ResourceMap<ResourceType, IDType>::clear()
{
- memset(mFlatResources, kInvalidPointer, kInitialFlatResourcesSize * kElementSize);
+ // No need for a lock as this is only called on destruction.
+ memset(mFlatResources, kInvalidPointer, kInitialFlatResourcesSize * sizeof(mFlatResources[0]));
mFlatResourcesSize = kInitialFlatResourcesSize;
mHashedResources.clear();
}
@@ -262,6 +389,8 @@ void ResourceMap<ResourceType, IDType>::clear()
template <typename ResourceType, typename IDType>
GLuint ResourceMap<ResourceType, IDType>::nextResource(size_t flatIndex, bool skipNulls) const
{
+ // This function is only used by the iterators, access to which is marked by
+ // UnsafeResourceMapIter. Locking is the responsibility of the caller.
for (size_t index = flatIndex; index < mFlatResourcesSize; index++)
{
if ((mFlatResources[index] != nullptr || !skipNulls) &&
diff --git a/src/libANGLE/ResourceMap_unittest.cpp b/src/libANGLE/ResourceMap_unittest.cpp
index 01d2d706ba..26411fd260 100644
--- a/src/libANGLE/ResourceMap_unittest.cpp
+++ b/src/libANGLE/ResourceMap_unittest.cpp
@@ -8,18 +8,37 @@
//
#include <gtest/gtest.h>
+#include <map>
#include "libANGLE/ResourceMap.h"
using namespace gl;
+namespace gl
+{
+template <>
+inline GLuint GetIDValue(int id)
+{
+ return id;
+}
+template <>
+inline GLuint GetIDValue(unsigned int id)
+{
+ return id;
+}
+} // namespace gl
+
namespace
{
-// Tests assigning slots in the map and then deleting elements.
-TEST(ResourceMapTest, AssignAndErase)
+// The resourceMap class uses a lock for "unsigned int" types to support this unit test.
+using LocklessType = int;
+using LockedType = unsigned int;
+
+template <typename T>
+void AssignAndErase()
{
- constexpr size_t kSize = 64;
- ResourceMap<size_t, GLuint> resourceMap;
+ constexpr size_t kSize = 300;
+ ResourceMap<size_t, T> resourceMap;
std::vector<size_t> objects(kSize, 1);
for (size_t index = 0; index < kSize; ++index)
{
@@ -36,11 +55,22 @@ TEST(ResourceMapTest, AssignAndErase)
ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
}
-// Tests assigning slots in the map and then using clear() to free it.
-TEST(ResourceMapTest, AssignAndClear)
+// Tests assigning slots in the map and then deleting elements.
+TEST(ResourceMapTest, AssignAndEraseLockless)
{
- constexpr size_t kSize = 64;
- ResourceMap<size_t, GLuint> resourceMap;
+ AssignAndErase<LocklessType>();
+}
+// Tests assigning slots in the map and then deleting elements.
+TEST(ResourceMapTest, AssignAndEraseLocked)
+{
+ AssignAndErase<LockedType>();
+}
+
+template <typename T>
+void AssignAndClear()
+{
+ constexpr size_t kSize = 280;
+ ResourceMap<size_t, T> resourceMap;
std::vector<size_t> objects(kSize, 1);
for (size_t index = 0; index < kSize; ++index)
{
@@ -51,12 +81,23 @@ TEST(ResourceMapTest, AssignAndClear)
ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
}
-// Tests growing a map more than double the size.
-TEST(ResourceMapTest, BigGrowth)
+// Tests assigning slots in the map and then using clear() to free it.
+TEST(ResourceMapTest, AssignAndClearLockless)
+{
+ AssignAndClear<LocklessType>();
+}
+// Tests assigning slots in the map and then using clear() to free it.
+TEST(ResourceMapTest, AssignAndClearLocked)
+{
+ AssignAndClear<LockedType>();
+}
+
+template <typename T>
+void BigGrowth()
{
constexpr size_t kSize = 8;
- ResourceMap<size_t, GLuint> resourceMap;
+ ResourceMap<size_t, T> resourceMap;
std::vector<size_t> objects;
for (size_t index = 0; index < kSize; ++index)
@@ -83,12 +124,26 @@ TEST(ResourceMapTest, BigGrowth)
ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
}
-// Tests querying unassigned or erased values.
-TEST(ResourceMapTest, QueryUnassigned)
+// Tests growing a map more than double the size.
+TEST(ResourceMapTest, BigGrowthLockless)
{
- constexpr size_t kSize = 8;
+ BigGrowth<LocklessType>();
+}
+// Tests growing a map more than double the size.
+TEST(ResourceMapTest, BigGrowthLocked)
+{
+ BigGrowth<LockedType>();
+}
+
+template <typename T>
+void QueryUnassigned()
+{
+ constexpr size_t kSize = 8;
+ constexpr T kZero = 0;
+ constexpr T kIdInFlatRange = 10;
+ constexpr T kIdOutOfFlatRange = 500;
- ResourceMap<size_t, GLuint> resourceMap;
+ ResourceMap<size_t, T> resourceMap;
std::vector<size_t> objects;
for (size_t index = 0; index < kSize; ++index)
@@ -96,10 +151,10 @@ TEST(ResourceMapTest, QueryUnassigned)
objects.push_back(index);
}
- ASSERT_FALSE(resourceMap.contains(0));
- ASSERT_EQ(nullptr, resourceMap.query(0));
- ASSERT_FALSE(resourceMap.contains(100));
- ASSERT_EQ(nullptr, resourceMap.query(100));
+ ASSERT_FALSE(resourceMap.contains(kZero));
+ ASSERT_EQ(nullptr, resourceMap.query(kZero));
+ ASSERT_FALSE(resourceMap.contains(kIdOutOfFlatRange));
+ ASSERT_EQ(nullptr, resourceMap.query(kIdOutOfFlatRange));
for (size_t &object : objects)
{
@@ -114,10 +169,10 @@ TEST(ResourceMapTest, QueryUnassigned)
ASSERT_EQ(&object, resourceMap.query(object));
}
- ASSERT_FALSE(resourceMap.contains(10));
- ASSERT_EQ(nullptr, resourceMap.query(10));
- ASSERT_FALSE(resourceMap.contains(100));
- ASSERT_EQ(nullptr, resourceMap.query(100));
+ ASSERT_FALSE(resourceMap.contains(kIdInFlatRange));
+ ASSERT_EQ(nullptr, resourceMap.query(kIdInFlatRange));
+ ASSERT_FALSE(resourceMap.contains(kIdOutOfFlatRange));
+ ASSERT_EQ(nullptr, resourceMap.query(kIdOutOfFlatRange));
for (size_t object : objects)
{
@@ -128,9 +183,131 @@ TEST(ResourceMapTest, QueryUnassigned)
ASSERT_TRUE(UnsafeResourceMapIter(resourceMap).empty());
- ASSERT_FALSE(resourceMap.contains(0));
- ASSERT_EQ(nullptr, resourceMap.query(0));
- ASSERT_FALSE(resourceMap.contains(100));
- ASSERT_EQ(nullptr, resourceMap.query(100));
+ ASSERT_FALSE(resourceMap.contains(kZero));
+ ASSERT_EQ(nullptr, resourceMap.query(kZero));
+ ASSERT_FALSE(resourceMap.contains(kIdOutOfFlatRange));
+ ASSERT_EQ(nullptr, resourceMap.query(kIdOutOfFlatRange));
+}
+
+// Tests querying unassigned or erased values.
+TEST(ResourceMapTest, QueryUnassignedLockless)
+{
+ QueryUnassigned<LocklessType>();
+}
+// Tests querying unassigned or erased values.
+TEST(ResourceMapTest, QueryUnassignedLocked)
+{
+ QueryUnassigned<LockedType>();
+}
+
+void ConcurrentAccess(size_t iterations, size_t idCycleSize)
+{
+ if (std::is_same_v<ResourceMapMutex, angle::NoOpMutex>)
+ {
+ GTEST_SKIP() << "Test skipped: Locking is disabled in build.";
+ }
+
+ constexpr size_t kThreadCount = 13;
+
+ ResourceMap<size_t, LockedType> resourceMap;
+
+ std::array<std::thread, kThreadCount> threads;
+ std::array<std::map<LockedType, size_t>, kThreadCount> insertedIds;
+
+ for (size_t i = 0; i < kThreadCount; ++i)
+ {
+ threads[i] = std::thread([&, i]() {
+ // Each thread manipulates a different set of ids. The resource map guarantees that the
+ // data structure itself is thread-safe, not accesses to the same id.
+ for (size_t j = 0; j < iterations; ++j)
+ {
+ const LockedType id = (j % (idCycleSize / kThreadCount)) * kThreadCount + i;
+
+ ASSERT_LE(id, 0xFFFFu);
+ ASSERT_LE(j, 0xFFFFu);
+ const size_t value = id | j << 16;
+
+ size_t *valuePtr = reinterpret_cast<size_t *>(value);
+
+ const size_t *queryResult = resourceMap.query(id);
+ const bool containsResult = resourceMap.contains(id);
+
+ const bool expectContains = insertedIds[i].count(id) > 0;
+ if (expectContains)
+ {
+ EXPECT_TRUE(containsResult);
+ const LockedType queryResultInt =
+ static_cast<LockedType>(reinterpret_cast<size_t>(queryResult) & 0xFFFF);
+ const size_t queryResultIteration = reinterpret_cast<size_t>(queryResult) >> 16;
+ EXPECT_EQ(queryResultInt, id);
+ EXPECT_LT(queryResultIteration, j);
+
+ size_t *erasedValue = nullptr;
+ const bool erased = resourceMap.erase(id, &erasedValue);
+
+ EXPECT_TRUE(erased);
+ EXPECT_EQ(erasedValue, queryResult);
+
+ insertedIds[i].erase(id);
+ }
+ else
+ {
+ EXPECT_FALSE(containsResult);
+ EXPECT_EQ(queryResult, nullptr);
+
+ resourceMap.assign(id, valuePtr);
+ EXPECT_TRUE(resourceMap.contains(id));
+
+ ASSERT_TRUE(insertedIds[i].count(id) == 0);
+ insertedIds[i][id] = value;
+ }
+ }
+ });
+ }
+
+ for (size_t i = 0; i < kThreadCount; ++i)
+ {
+ threads[i].join();
+ }
+
+ // Verify that every value that is expected to be there is actually there
+ std::map<size_t, size_t> allIds;
+ size_t allIdsPrevSize = 0;
+
+ for (size_t i = 0; i < kThreadCount; ++i)
+ {
+ // Merge all the sets together. The sets are disjoint, which is verified by the ASSERT_EQ.
+ allIds.insert(insertedIds[i].begin(), insertedIds[i].end());
+ ASSERT_EQ(allIds.size(), allIdsPrevSize + insertedIds[i].size());
+ allIdsPrevSize = allIds.size();
+
+ // Make sure every id that is expected to be there is actually there.
+ for (auto &idValue : insertedIds[i])
+ {
+ EXPECT_TRUE(resourceMap.contains(idValue.first));
+ EXPECT_EQ(resourceMap.query(idValue.first), reinterpret_cast<size_t *>(idValue.second));
+ }
+ }
+
+ // Verify that every value that is NOT expected to be there isn't actually there
+ for (auto &idValue : UnsafeResourceMapIter(resourceMap))
+ {
+ EXPECT_TRUE(allIds.count(idValue.first) == 1);
+ EXPECT_EQ(idValue.second, reinterpret_cast<size_t *>(allIds[idValue.first]));
+ }
+
+ resourceMap.clear();
+}
+
+// Tests that concurrent access to thread-safe resource maps works for small ids that are mostly in
+// the flat map range.
+TEST(ResourceMapTest, ConcurrentAccessSmallIds)
+{
+ ConcurrentAccess(50'000, 128);
+}
+// Tests that concurrent access to thread-safe resource maps works for a wider range of ids.
+TEST(ResourceMapTest, ConcurrentAccessLargeIds)
+{
+ ConcurrentAccess(10'000, 20'000);
}
} // anonymous namespace
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 24169c0663..1f3de17a0d 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -3966,4 +3966,6 @@ void State::initializeForCapture(const Context *context)
initialize(mutableContext);
}
+constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[state::DIRTY_OBJECT_MAX];
+
} // namespace gl
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index fa61701b30..b2aa674906 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -1448,40 +1448,13 @@ class State : angle::NonCopyable
using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
- static constexpr std::array<DirtyObjectHandler, state::DIRTY_OBJECT_MAX> kDirtyObjectHandlers =
- []() {
- // Work around C++'s lack of array element support in designated initializers
- std::array<DirtyObjectHandler, state::DIRTY_OBJECT_MAX> handlers{};
-
- handlers[state::DIRTY_OBJECT_ACTIVE_TEXTURES] = &State::syncActiveTextures;
- handlers[state::DIRTY_OBJECT_TEXTURES_INIT] = &State::syncTexturesInit;
- handlers[state::DIRTY_OBJECT_IMAGES_INIT] = &State::syncImagesInit;
- handlers[state::DIRTY_OBJECT_READ_ATTACHMENTS] = &State::syncReadAttachments;
- handlers[state::DIRTY_OBJECT_DRAW_ATTACHMENTS] = &State::syncDrawAttachments;
- handlers[state::DIRTY_OBJECT_READ_FRAMEBUFFER] = &State::syncReadFramebuffer;
- handlers[state::DIRTY_OBJECT_DRAW_FRAMEBUFFER] = &State::syncDrawFramebuffer;
- handlers[state::DIRTY_OBJECT_VERTEX_ARRAY] = &State::syncVertexArray;
- handlers[state::DIRTY_OBJECT_TEXTURES] = &State::syncTextures;
- handlers[state::DIRTY_OBJECT_IMAGES] = &State::syncImages;
- handlers[state::DIRTY_OBJECT_SAMPLERS] = &State::syncSamplers;
- handlers[state::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT] =
- &State::syncProgramPipelineObject;
-
- return handlers;
- }();
-
- static_assert(
- []() {
- for (auto handler : kDirtyObjectHandlers)
- {
- if (handler == nullptr)
- {
- return false;
- }
- }
- return true;
- }(),
- "kDirtyObjectHandlers missing a handler");
+ static constexpr DirtyObjectHandler kDirtyObjectHandlers[state::DIRTY_OBJECT_MAX] = {
+ &State::syncActiveTextures, &State::syncTexturesInit,
+ &State::syncImagesInit, &State::syncReadAttachments,
+ &State::syncDrawAttachments, &State::syncReadFramebuffer,
+ &State::syncDrawFramebuffer, &State::syncVertexArray,
+ &State::syncTextures, &State::syncImages,
+ &State::syncSamplers, &State::syncProgramPipelineObject};
// Robust init must happen before Framebuffer init for the Vulkan back-end.
static_assert(state::DIRTY_OBJECT_ACTIVE_TEXTURES < state::DIRTY_OBJECT_TEXTURES_INIT,
@@ -1495,6 +1468,25 @@ class State : angle::NonCopyable
static_assert(state::DIRTY_OBJECT_READ_ATTACHMENTS < state::DIRTY_OBJECT_READ_FRAMEBUFFER,
"init order");
+ static_assert(state::DIRTY_OBJECT_ACTIVE_TEXTURES == 0,
+ "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
+ static_assert(state::DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
+ static_assert(state::DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
+ static_assert(state::DIRTY_OBJECT_READ_ATTACHMENTS == 3,
+ "check DIRTY_OBJECT_READ_ATTACHMENTS index");
+ static_assert(state::DIRTY_OBJECT_DRAW_ATTACHMENTS == 4,
+ "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
+ static_assert(state::DIRTY_OBJECT_READ_FRAMEBUFFER == 5,
+ "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
+ static_assert(state::DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6,
+ "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
+ static_assert(state::DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index");
+ static_assert(state::DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index");
+ static_assert(state::DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index");
+ static_assert(state::DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index");
+ static_assert(state::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT == 11,
+ "check DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT index");
+
// Dispatch table for buffer update functions.
static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
diff --git a/src/libANGLE/Texture.cpp b/src/libANGLE/Texture.cpp
index fa27583f72..00647cbaac 100644
--- a/src/libANGLE/Texture.cpp
+++ b/src/libANGLE/Texture.cpp
@@ -185,8 +185,8 @@ GLuint TextureState::getMipmapMaxLevel() const
GLuint expectedMipLevels = 0;
if (mType == TextureType::_3D)
{
- const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height),
- baseImageDesc.size.depth);
+ const int maxDim = std::max(
+ {baseImageDesc.size.width, baseImageDesc.size.height, baseImageDesc.size.depth});
expectedMipLevels = static_cast<GLuint>(log2(maxDim));
}
else
@@ -594,7 +594,7 @@ GLuint TextureState::getEnabledLevelCount() const
{
GLuint levelCount = 0;
const GLuint baseLevel = getEffectiveBaseLevel();
- const GLuint maxLevel = std::min(getEffectiveMaxLevel(), getMipmapMaxLevel());
+ const GLuint maxLevel = getMipmapMaxLevel();
// The mip chain will have either one or more sequential levels, or max levels,
// but not a sparse one.
diff --git a/src/libANGLE/renderer/DeviceImpl.h b/src/libANGLE/renderer/DeviceImpl.h
index 53d0edf72b..02eaff0ee7 100644
--- a/src/libANGLE/renderer/DeviceImpl.h
+++ b/src/libANGLE/renderer/DeviceImpl.h
@@ -33,7 +33,6 @@ class DeviceImpl : angle::NonCopyable
virtual egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) = 0;
- virtual EGLint getType() = 0;
virtual void generateExtensions(egl::DeviceExtensions *outExtensions) const = 0;
virtual const std::string getDeviceString(EGLint name);
};
diff --git a/src/libANGLE/renderer/DisplayImpl.cpp b/src/libANGLE/renderer/DisplayImpl.cpp
index e3258cb4be..cb12c501bc 100644
--- a/src/libANGLE/renderer/DisplayImpl.cpp
+++ b/src/libANGLE/renderer/DisplayImpl.cpp
@@ -27,11 +27,6 @@ class MockDevice : public DeviceImpl
UNREACHABLE();
return egl::EglBadAttribute();
}
- EGLint getType() override
- {
- UNREACHABLE();
- return EGL_NONE;
- }
void generateExtensions(egl::DeviceExtensions *outExtensions) const override
{
*outExtensions = egl::DeviceExtensions();
diff --git a/src/libANGLE/renderer/d3d/DeviceD3D.cpp b/src/libANGLE/renderer/d3d/DeviceD3D.cpp
deleted file mode 100644
index 79dfb094e3..0000000000
--- a/src/libANGLE/renderer/d3d/DeviceD3D.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// Copyright 2015 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.
-//
-
-// DeviceD3D.cpp: D3D implementation of egl::Device
-
-#include "libANGLE/renderer/d3d/DeviceD3D.h"
-
-#include "libANGLE/Device.h"
-#include "libANGLE/Display.h"
-
-#include <EGL/eglext.h>
-
-namespace rx
-{
-
-DeviceD3D::DeviceD3D(GLint deviceType, void *nativeDevice)
- : mDevice(nativeDevice), mDeviceType(deviceType), mIsInitialized(false)
-{}
-
-DeviceD3D::~DeviceD3D()
-{
-#if defined(ANGLE_ENABLE_D3D11)
- if (mIsInitialized && mDeviceType == EGL_D3D11_DEVICE_ANGLE)
- {
- // DeviceD3D holds a ref to an externally-sourced D3D11 device. We must release it.
- ID3D11Device *device = static_cast<ID3D11Device *>(mDevice);
- device->Release();
- }
-#endif
-}
-
-egl::Error DeviceD3D::getAttribute(const egl::Display *display, EGLint attribute, void **outValue)
-{
- ASSERT(mIsInitialized);
- ANGLE_UNUSED_VARIABLE(display);
- // Validated at higher levels.
- ASSERT(getType() == attribute);
- *outValue = mDevice;
- return egl::NoError();
-}
-
-egl::Error DeviceD3D::initialize()
-{
- ASSERT(!mIsInitialized);
-
-#if defined(ANGLE_ENABLE_D3D11)
- if (mDeviceType == EGL_D3D11_DEVICE_ANGLE)
- {
- // Validate the device
- IUnknown *iunknown = static_cast<IUnknown *>(mDevice);
-
- ID3D11Device *d3dDevice = nullptr;
- HRESULT hr =
- iunknown->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast<void **>(&d3dDevice));
- if (FAILED(hr))
- {
- return egl::EglBadAttribute() << "Invalid D3D device passed into EGLDeviceEXT";
- }
-
- // The QI to ID3D11Device adds a ref to the D3D11 device.
- // Deliberately don't release the ref here, so that the DeviceD3D holds a ref to the
- // D3D11 device.
- }
-#endif
-
- mIsInitialized = true;
-
- return egl::NoError();
-}
-
-EGLint DeviceD3D::getType()
-{
- return mDeviceType;
-}
-
-void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const
-{
- outExtensions->deviceD3D = true;
-}
-
-} // namespace rx
diff --git a/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/src/libANGLE/renderer/d3d/DisplayD3D.cpp
index 1a2c729631..dad28b9b96 100644
--- a/src/libANGLE/renderer/d3d/DisplayD3D.cpp
+++ b/src/libANGLE/renderer/d3d/DisplayD3D.cpp
@@ -16,7 +16,6 @@
#include "libANGLE/Surface.h"
#include "libANGLE/Thread.h"
#include "libANGLE/histogram_macros.h"
-#include "libANGLE/renderer/d3d/DeviceD3D.h"
#include "libANGLE/renderer/d3d/EGLImageD3D.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/SurfaceD3D.h"
@@ -113,7 +112,7 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer)
else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
{
#if defined(ANGLE_ENABLE_D3D11)
- if (display->getDevice()->getType() == EGL_D3D11_DEVICE_ANGLE)
+ if (display->getDevice()->getExtensions().deviceD3D11)
{
rendererCreationFunctions.push_back(CreateRenderer11);
}
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/libANGLE/renderer/d3d/RendererD3D.cpp
index d5b77d2003..49cbbba06d 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -23,7 +23,6 @@
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/TextureImpl.h"
#include "libANGLE/renderer/d3d/BufferD3D.h"
-#include "libANGLE/renderer/d3d/DeviceD3D.h"
#include "libANGLE/renderer/d3d/DisplayD3D.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "libANGLE/renderer/d3d/ProgramExecutableD3D.h"
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
index 19e8afdc94..11e9e599ac 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -45,7 +45,6 @@ namespace rx
class ContextImpl;
struct D3DUniform;
struct D3DVarying;
-class DeviceD3D;
class EGLImageD3D;
class FramebufferImpl;
class ImageD3D;
diff --git a/src/libANGLE/renderer/d3d/TextureD3D.cpp b/src/libANGLE/renderer/d3d/TextureD3D.cpp
index 141cbe6a82..8d3313e1d3 100644
--- a/src/libANGLE/renderer/d3d/TextureD3D.cpp
+++ b/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -413,7 +413,7 @@ GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) c
mRenderer->getNativeExtensions().textureNpotOES)
{
// Maximum number of levels
- return gl::log2(std::max(std::max(width, height), depth)) + 1;
+ return gl::log2(std::max({width, height, depth})) + 1;
}
else
{
diff --git a/src/libANGLE/renderer/d3d/d3d11/Device11.cpp b/src/libANGLE/renderer/d3d/d3d11/Device11.cpp
new file mode 100644
index 0000000000..350fa3ce89
--- /dev/null
+++ b/src/libANGLE/renderer/d3d/d3d11/Device11.cpp
@@ -0,0 +1,63 @@
+//
+// 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.
+//
+
+// Device11.cpp: D3D11 implementation of egl::Device
+
+#include "libANGLE/renderer/d3d/d3d11/Device11.h"
+
+#include "libANGLE/Device.h"
+#include "libANGLE/Display.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+
+Device11::Device11(void *nativeDevice)
+{
+ // Validate the device
+ IUnknown *iunknown = static_cast<IUnknown *>(nativeDevice);
+
+ // The QI to ID3D11Device adds a ref to the D3D11 device.
+ // Deliberately don't release the ref here, so that the Device11 holds a ref to the
+ // D3D11 device.
+ iunknown->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast<void **>(&mDevice));
+}
+
+Device11::~Device11()
+{
+ if (mDevice)
+ {
+ // Device11 holds a ref to an externally-sourced D3D11 device. We must release it.
+ mDevice->Release();
+ mDevice = nullptr;
+ }
+}
+
+egl::Error Device11::getAttribute(const egl::Display *display, EGLint attribute, void **outValue)
+{
+ ASSERT(attribute == EGL_D3D11_DEVICE_ANGLE);
+ *outValue = mDevice;
+ return egl::NoError();
+}
+
+egl::Error Device11::initialize()
+{
+ if (!mDevice)
+ {
+ return egl::EglBadAttribute() << "Invalid D3D device passed into EGLDeviceEXT";
+ }
+
+ return egl::NoError();
+}
+
+void Device11::generateExtensions(egl::DeviceExtensions *outExtensions) const
+{
+ outExtensions->deviceD3D = true;
+ outExtensions->deviceD3D11 = true;
+}
+
+} // namespace rx
diff --git a/src/libANGLE/renderer/d3d/DeviceD3D.h b/src/libANGLE/renderer/d3d/d3d11/Device11.h
index c169eb7de5..81690a4d67 100644
--- a/src/libANGLE/renderer/d3d/DeviceD3D.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Device11.h
@@ -1,39 +1,38 @@
//
-// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// 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.
//
-// DeviceD3D.h: D3D implementation of egl::Device
+// Device11.h: D3D11 implementation of egl::Device
-#ifndef LIBANGLE_RENDERER_D3D_DEVICED3D_H_
-#define LIBANGLE_RENDERER_D3D_DEVICED3D_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_DEVICE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_DEVICE11_H_
#include "libANGLE/Device.h"
#include "libANGLE/renderer/DeviceImpl.h"
-#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
namespace rx
{
-class DeviceD3D : public DeviceImpl
+class Device11 : public DeviceImpl
{
public:
- DeviceD3D(EGLint deviceType, void *nativeDevice);
- ~DeviceD3D() override;
+ Device11(void *nativeDevice);
+ ~Device11() override;
egl::Error initialize() override;
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
+ ID3D11Device* getDevice() const { return mDevice; }
+
private:
- void *mDevice;
- EGLint mDeviceType;
- bool mIsInitialized;
+ ID3D11Device *mDevice = nullptr;
};
} // namespace rx
-#endif // LIBANGLE_RENDERER_D3D_DEVICED3D_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_DEVICE11_H_
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 6d9cfe1092..fe015f6c69 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -27,7 +27,6 @@
#include "libANGLE/formatutils.h"
#include "libANGLE/histogram_macros.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h"
-#include "libANGLE/renderer/d3d/DeviceD3D.h"
#include "libANGLE/renderer/d3d/DisplayD3D.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h"
@@ -40,6 +39,7 @@
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Device11.h"
#include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h"
#include "libANGLE/renderer/d3d/d3d11/Fence11.h"
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
@@ -701,14 +701,10 @@ egl::Error Renderer11::initializeDXGIAdapter()
{
ASSERT(mRequestedDriverType == D3D_DRIVER_TYPE_UNKNOWN);
- DeviceD3D *deviceD3D = GetImplAs<DeviceD3D>(mDisplay->getDevice());
- ASSERT(deviceD3D != nullptr);
+ Device11 *device11 = GetImplAs<Device11>(mDisplay->getDevice());
+ ASSERT(device11 != nullptr);
- // We should use the inputted D3D11 device instead
- void *device = nullptr;
- ANGLE_TRY(deviceD3D->getAttribute(mDisplay, EGL_D3D11_DEVICE_ANGLE, &device));
-
- ID3D11Device *d3dDevice = static_cast<ID3D11Device *>(device);
+ ID3D11Device *d3dDevice = device11->getDevice();
if (FAILED(d3dDevice->GetDeviceRemovedReason()))
{
return egl::EglNotInitialized() << "Inputted D3D11 device has been lost.";
@@ -4227,7 +4223,7 @@ void Renderer11::initializeFrontendFeatures(angle::FrontendFeatures *features) c
DeviceImpl *Renderer11::createEGLDevice()
{
- return new DeviceD3D(EGL_D3D11_DEVICE_ANGLE, mDevice.Get());
+ return new Device11(mDevice.Get());
}
ContextImpl *Renderer11::createContext(const gl::State &state, gl::ErrorSet *errorSet)
diff --git a/src/libANGLE/renderer/d3d/d3d9/Device9.cpp b/src/libANGLE/renderer/d3d/d3d9/Device9.cpp
new file mode 100644
index 0000000000..15a10f446d
--- /dev/null
+++ b/src/libANGLE/renderer/d3d/d3d9/Device9.cpp
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+// Device9.cpp: D3D9 implementation of egl::Device
+
+#include "libANGLE/renderer/d3d/d3d9/Device9.h"
+
+#include "libANGLE/Device.h"
+#include "libANGLE/Display.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+
+Device9::Device9(IDirect3DDevice9 *device) : mDevice(device) {}
+
+Device9::~Device9() {}
+
+egl::Error Device9::getAttribute(const egl::Display *display, EGLint attribute, void **outValue)
+{
+ ASSERT(attribute == EGL_D3D9_DEVICE_ANGLE);
+ *outValue = mDevice;
+ return egl::NoError();
+}
+
+egl::Error Device9::initialize()
+{
+ return egl::NoError();
+}
+
+void Device9::generateExtensions(egl::DeviceExtensions *outExtensions) const
+{
+ outExtensions->deviceD3D = true;
+ outExtensions->deviceD3D9 = true;
+}
+
+} // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d9/Device9.h b/src/libANGLE/renderer/d3d/d3d9/Device9.h
new file mode 100644
index 0000000000..8d4db450ec
--- /dev/null
+++ b/src/libANGLE/renderer/d3d/d3d9/Device9.h
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+// Device9.h: D3D9 implementation of egl::Device
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_DEVICE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_DEVICE9_H_
+
+#include "libANGLE/Device.h"
+#include "libANGLE/renderer/DeviceImpl.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+
+namespace rx
+{
+class Device9 : public DeviceImpl
+{
+ public:
+ Device9(IDirect3DDevice9 *device);
+ ~Device9() override;
+
+ egl::Error initialize() override;
+ egl::Error getAttribute(const egl::Display *display,
+ EGLint attribute,
+ void **outValue) override;
+ void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
+
+ private:
+ IDirect3DDevice9 *mDevice;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_DEVICE9_H_
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index cddd8d11e5..329ae54d2a 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -26,7 +26,6 @@
#include "libANGLE/features.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h"
-#include "libANGLE/renderer/d3d/DeviceD3D.h"
#include "libANGLE/renderer/d3d/DisplayD3D.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h"
@@ -39,6 +38,7 @@
#include "libANGLE/renderer/d3d/d3d9/Blit9.h"
#include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+#include "libANGLE/renderer/d3d/d3d9/Device9.h"
#include "libANGLE/renderer/d3d/d3d9/Fence9.h"
#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
#include "libANGLE/renderer/d3d/d3d9/Image9.h"
@@ -3121,7 +3121,7 @@ void Renderer9::initializeFrontendFeatures(angle::FrontendFeatures *features) co
DeviceImpl *Renderer9::createEGLDevice()
{
- return new DeviceD3D(EGL_D3D9_DEVICE_ANGLE, mDevice);
+ return new Device9(mDevice);
}
Renderer9::CurSamplerState::CurSamplerState()
diff --git a/src/libANGLE/renderer/d3d/d3d_backend.gni b/src/libANGLE/renderer/d3d/d3d_backend.gni
index d262afa2ef..d17b266540 100644
--- a/src/libANGLE/renderer/d3d/d3d_backend.gni
+++ b/src/libANGLE/renderer/d3d/d3d_backend.gni
@@ -10,8 +10,6 @@ d3d_shared_sources = [
"CompilerD3D.cpp",
"CompilerD3D.h",
"ContextD3D.h",
- "DeviceD3D.cpp",
- "DeviceD3D.h",
"DisplayD3D.cpp",
"DisplayD3D.h",
"DynamicHLSL.cpp",
@@ -73,6 +71,8 @@ if (angle_enable_d3d9) {
"d3d9/Context9.h",
"d3d9/DebugAnnotator9.cpp",
"d3d9/DebugAnnotator9.h",
+ "d3d9/Device9.cpp",
+ "d3d9/Device9.h",
"d3d9/Fence9.cpp",
"d3d9/Fence9.h",
"d3d9/Framebuffer9.cpp",
@@ -132,6 +132,8 @@ if (angle_enable_d3d11) {
"d3d11/Context11.h",
"d3d11/DebugAnnotator11.cpp",
"d3d11/DebugAnnotator11.h",
+ "d3d11/Device11.cpp",
+ "d3d11/Device11.h",
"d3d11/ExternalImageSiblingImpl11.cpp",
"d3d11/ExternalImageSiblingImpl11.h",
"d3d11/Fence11.cpp",
diff --git a/src/libANGLE/renderer/driver_utils.cpp b/src/libANGLE/renderer/driver_utils.cpp
index fed3940a00..641e5f7818 100644
--- a/src/libANGLE/renderer/driver_utils.cpp
+++ b/src/libANGLE/renderer/driver_utils.cpp
@@ -138,6 +138,16 @@ const uint16_t IntelGen12[] = {
// DG1
0x4905, 0x4906, 0x4907, 0x4908, 0x4909};
+// The following is used to parse generic Vulkan driver versions.
+angle::VersionTriple ParseGenericVulkanDriverVersion(uint32_t driverVersion)
+{
+ // Generic Vulkan driver versions are built using the following format:
+ // (Major << 22) | (Minor << 12) | (Patch)
+ constexpr uint32_t kMinorVersionMask = angle::BitMask<uint32_t>(10);
+ constexpr uint32_t kPatchVersionMask = angle::BitMask<uint32_t>(12);
+ return angle::VersionTriple(driverVersion >> 22, (driverVersion >> 12) & kMinorVersionMask,
+ driverVersion & kPatchVersionMask);
+}
} // anonymous namespace
IntelDriverVersion::IntelDriverVersion(uint32_t buildNumber) : mBuildNumber(buildNumber) {}
@@ -305,14 +315,14 @@ IntelDriverVersion ParseIntelWindowsDriverVersion(uint32_t driverVersion)
#endif
}
-ARMDriverVersion ParseARMDriverVersion(uint32_t driverVersion)
+ARMDriverVersion ParseARMVulkanDriverVersion(uint32_t driverVersion)
{
- // ARM driver versions are built with the following macro:
- // ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch)))
- constexpr uint32_t kMinorVersionMask = angle::BitMask<uint32_t>(10);
- constexpr uint32_t kPatchMask = angle::BitMask<uint32_t>(12);
- return ARMDriverVersion(driverVersion >> 22, (driverVersion >> 12) & kMinorVersionMask,
- driverVersion & kPatchMask);
+ return ParseGenericVulkanDriverVersion(driverVersion);
+}
+
+QualcommDriverVersion ParseQualcommVulkanDriverVersion(uint32_t driverVersion)
+{
+ return ParseGenericVulkanDriverVersion(driverVersion);
}
int GetAndroidSDKVersion()
diff --git a/src/libANGLE/renderer/driver_utils.h b/src/libANGLE/renderer/driver_utils.h
index f3247c78fb..b98f80c7c5 100644
--- a/src/libANGLE/renderer/driver_utils.h
+++ b/src/libANGLE/renderer/driver_utils.h
@@ -199,7 +199,10 @@ bool Is11thGenIntel(uint32_t DeviceId);
bool Is12thGenIntel(uint32_t DeviceId);
using ARMDriverVersion = angle::VersionTriple;
-ARMDriverVersion ParseARMDriverVersion(uint32_t driverVersion);
+ARMDriverVersion ParseARMVulkanDriverVersion(uint32_t driverVersion);
+
+using QualcommDriverVersion = angle::VersionTriple;
+QualcommDriverVersion ParseQualcommVulkanDriverVersion(uint32_t driverVersion);
// Platform helpers
using angle::IsAndroid;
diff --git a/src/libANGLE/renderer/gl/cgl/DeviceCGL.cpp b/src/libANGLE/renderer/gl/cgl/DeviceCGL.cpp
index 3890d94f3f..dac2e77103 100644
--- a/src/libANGLE/renderer/gl/cgl/DeviceCGL.cpp
+++ b/src/libANGLE/renderer/gl/cgl/DeviceCGL.cpp
@@ -42,11 +42,6 @@ egl::Error DeviceCGL::getAttribute(const egl::Display *display, EGLint attribute
return egl::NoError();
}
-EGLint DeviceCGL::getType()
-{
- return 0;
-}
-
void DeviceCGL::generateExtensions(egl::DeviceExtensions *outExtensions) const
{
outExtensions->deviceCGL = true;
diff --git a/src/libANGLE/renderer/gl/cgl/DeviceCGL.h b/src/libANGLE/renderer/gl/cgl/DeviceCGL.h
index 3f7e1c0835..e62a6c3761 100644
--- a/src/libANGLE/renderer/gl/cgl/DeviceCGL.h
+++ b/src/libANGLE/renderer/gl/cgl/DeviceCGL.h
@@ -24,7 +24,6 @@ class DeviceCGL : public DeviceImpl
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
};
diff --git a/src/libANGLE/renderer/gl/eagl/DeviceEAGL.cpp b/src/libANGLE/renderer/gl/eagl/DeviceEAGL.cpp
index 9aa5094985..a7786f93da 100644
--- a/src/libANGLE/renderer/gl/eagl/DeviceEAGL.cpp
+++ b/src/libANGLE/renderer/gl/eagl/DeviceEAGL.cpp
@@ -40,11 +40,6 @@ egl::Error DeviceEAGL::getAttribute(const egl::Display *display, EGLint attribut
return egl::NoError();
}
-EGLint DeviceEAGL::getType()
-{
- return 0;
-}
-
void DeviceEAGL::generateExtensions(egl::DeviceExtensions *outExtensions) const
{
outExtensions->deviceEAGL = true;
diff --git a/src/libANGLE/renderer/gl/eagl/DeviceEAGL.h b/src/libANGLE/renderer/gl/eagl/DeviceEAGL.h
index 1b4a2db566..f9de40fdc2 100644
--- a/src/libANGLE/renderer/gl/eagl/DeviceEAGL.h
+++ b/src/libANGLE/renderer/gl/eagl/DeviceEAGL.h
@@ -24,7 +24,6 @@ class DeviceEAGL : public DeviceImpl
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
};
diff --git a/src/libANGLE/renderer/gl/egl/DeviceEGL.cpp b/src/libANGLE/renderer/gl/egl/DeviceEGL.cpp
index f3ee4404a0..bc2c4946bd 100644
--- a/src/libANGLE/renderer/gl/egl/DeviceEGL.cpp
+++ b/src/libANGLE/renderer/gl/egl/DeviceEGL.cpp
@@ -46,12 +46,6 @@ egl::Error DeviceEGL::getAttribute(const egl::Display *display, EGLint attribute
return egl::EglBadAttribute();
}
-EGLint DeviceEGL::getType()
-{
- UNREACHABLE();
- return EGL_NONE;
-}
-
void DeviceEGL::generateExtensions(egl::DeviceExtensions *outExtensions) const
{
if (hasExtension("EGL_EXT_device_drm"))
diff --git a/src/libANGLE/renderer/gl/egl/DeviceEGL.h b/src/libANGLE/renderer/gl/egl/DeviceEGL.h
index 10a1cf68fb..6bf0b5622e 100644
--- a/src/libANGLE/renderer/gl/egl/DeviceEGL.h
+++ b/src/libANGLE/renderer/gl/egl/DeviceEGL.h
@@ -27,7 +27,6 @@ class DeviceEGL : public DeviceImpl
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
const std::string getDeviceString(EGLint name) override;
diff --git a/src/libANGLE/renderer/gl/egl/SyncEGL.cpp b/src/libANGLE/renderer/gl/egl/SyncEGL.cpp
index 93e3151eaf..2ccc9fe523 100644
--- a/src/libANGLE/renderer/gl/egl/SyncEGL.cpp
+++ b/src/libANGLE/renderer/gl/egl/SyncEGL.cpp
@@ -28,7 +28,13 @@ void SyncEGL::onDestroy(const egl::Display *display)
{
egl::Display::GetCurrentThreadUnlockedTailCall()->add(
[egl = mEGL, sync = mSync](void *resultOut) {
- *static_cast<EGLBoolean *>(resultOut) = egl->destroySyncKHR(sync);
+ EGLBoolean result = egl->destroySyncKHR(sync);
+ if (resultOut)
+ {
+ // It's possible for resultOut to be null if this sync is being destructed as
+ // part of display destruction.
+ *static_cast<EGLBoolean *>(resultOut) = result;
+ }
});
mSync = EGL_NO_SYNC_KHR;
}
diff --git a/src/libANGLE/renderer/metal/DeviceMtl.h b/src/libANGLE/renderer/metal/DeviceMtl.h
index ff8bc42e86..2fc9885e4c 100644
--- a/src/libANGLE/renderer/metal/DeviceMtl.h
+++ b/src/libANGLE/renderer/metal/DeviceMtl.h
@@ -26,7 +26,6 @@ class DeviceMtl : public DeviceImpl
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
};
diff --git a/src/libANGLE/renderer/metal/DeviceMtl.mm b/src/libANGLE/renderer/metal/DeviceMtl.mm
index d29b6aefc9..9706e721fa 100644
--- a/src/libANGLE/renderer/metal/DeviceMtl.mm
+++ b/src/libANGLE/renderer/metal/DeviceMtl.mm
@@ -24,6 +24,7 @@ egl::Error DeviceMtl::initialize()
{
return egl::NoError();
}
+
egl::Error DeviceMtl::getAttribute(const egl::Display *display, EGLint attribute, void **outValue)
{
DisplayMtl *displayImpl = mtl::GetImpl(display);
@@ -39,13 +40,10 @@ egl::Error DeviceMtl::getAttribute(const egl::Display *display, EGLint attribute
return egl::NoError();
}
-EGLint DeviceMtl::getType()
-{
- return 0;
-}
+
void DeviceMtl::generateExtensions(egl::DeviceExtensions *outExtensions) const
{
outExtensions->deviceMetal = true;
}
-}
+} // namespace rx
diff --git a/src/libANGLE/renderer/metal/TextureMtl.mm b/src/libANGLE/renderer/metal/TextureMtl.mm
index a0bef18639..1febc2a037 100644
--- a/src/libANGLE/renderer/metal/TextureMtl.mm
+++ b/src/libANGLE/renderer/metal/TextureMtl.mm
@@ -1324,7 +1324,9 @@ angle::Result TextureMtl::setEGLImageTarget(const gl::Context *context,
angle::Format::InternalFormatToID(image->getFormat().info->sizedInternalFormat);
mFormat = contextMtl->getPixelFormat(angleFormatId);
- mSlices = mNativeTexture->cubeFacesOrArrayLength();
+ mSlices = mNativeTexture->cubeFacesOrArrayLength();
+ mCurrentBaseLevel = 0;
+ mCurrentMaxLevel = mNativeTexture->mipmapLevels() - 1;
ANGLE_TRY(ensureSamplerStateCreated(context));
@@ -1484,10 +1486,13 @@ angle::Result TextureMtl::bindTexImage(const gl::Context *context, egl::Surface
{
releaseTexture(true);
- mBoundSurface = surface;
- auto pBuffer = GetImplAs<OffscreenSurfaceMtl>(surface);
- mNativeTexture = pBuffer->getColorTexture();
- mFormat = pBuffer->getColorFormat();
+ mBoundSurface = surface;
+ auto pBuffer = GetImplAs<OffscreenSurfaceMtl>(surface);
+ mNativeTexture = pBuffer->getColorTexture();
+ mFormat = pBuffer->getColorFormat();
+ mSlices = mNativeTexture->cubeFacesOrArrayLength();
+ mCurrentBaseLevel = 0;
+ mCurrentMaxLevel = mNativeTexture->mipmapLevels() - 1;
ANGLE_TRY(ensureSamplerStateCreated(context));
// Tell context to rebind textures
diff --git a/src/libANGLE/renderer/metal/VertexArrayMtl.mm b/src/libANGLE/renderer/metal/VertexArrayMtl.mm
index b0726b984f..d3e33bf040 100644
--- a/src/libANGLE/renderer/metal/VertexArrayMtl.mm
+++ b/src/libANGLE/renderer/metal/VertexArrayMtl.mm
@@ -405,7 +405,9 @@ angle::Result VertexArrayMtl::setupDraw(const gl::Context *glContext,
const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
bool attribEnabled = attrib.enabled;
- if (attribEnabled && !mCurrentArrayBuffers[v] && !mCurrentArrayInlineDataPointers[v])
+ if (attribEnabled &&
+ !(mCurrentArrayBuffers[v] && mCurrentArrayBuffers[v]->getCurrentBuffer()) &&
+ !mCurrentArrayInlineDataPointers[v])
{
// Disable it to avoid crash.
attribEnabled = false;
@@ -476,7 +478,7 @@ angle::Result VertexArrayMtl::setupDraw(const gl::Context *glContext,
cmdEncoder->setVertexBuffer(mCurrentArrayBuffers[v]->getCurrentBuffer(),
bufferOffset, bufferIdx);
}
- else
+ else if (mCurrentArrayInlineDataPointers[v])
{
// No buffer specified, use the client memory directly as inline constant data
ASSERT(mCurrentArrayInlineDataSizes[v] <= mInlineDataMaxSize);
diff --git a/src/libANGLE/renderer/metal/mtl_resources.mm b/src/libANGLE/renderer/metal/mtl_resources.mm
index 7e8a0dd0b8..4fd9dec733 100644
--- a/src/libANGLE/renderer/metal/mtl_resources.mm
+++ b/src/libANGLE/renderer/metal/mtl_resources.mm
@@ -271,8 +271,7 @@ angle::Result Texture::Make3DTexture(ContextMtl *context,
ANGLE_MTL_OBJC_SCOPE
{
// Use texture2DDescriptorWithPixelFormat to calculate full range mipmap range:
- uint32_t maxDimen = std::max(width, height);
- maxDimen = std::max(maxDimen, depth);
+ const uint32_t maxDimen = std::max({width, height, depth});
MTLTextureDescriptor *desc =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format.metalFormat
width:maxDimen
diff --git a/src/libANGLE/renderer/null/DeviceNULL.cpp b/src/libANGLE/renderer/null/DeviceNULL.cpp
index 4f6a9a85f6..09bd4ae0ba 100644
--- a/src/libANGLE/renderer/null/DeviceNULL.cpp
+++ b/src/libANGLE/renderer/null/DeviceNULL.cpp
@@ -29,11 +29,6 @@ egl::Error DeviceNULL::getAttribute(const egl::Display *display, EGLint attribut
return egl::EglBadAccess();
}
-EGLint DeviceNULL::getType()
-{
- return 0;
-}
-
void DeviceNULL::generateExtensions(egl::DeviceExtensions *outExtensions) const {}
} // namespace rx
diff --git a/src/libANGLE/renderer/null/DeviceNULL.h b/src/libANGLE/renderer/null/DeviceNULL.h
index a800e1501a..e43906123f 100644
--- a/src/libANGLE/renderer/null/DeviceNULL.h
+++ b/src/libANGLE/renderer/null/DeviceNULL.h
@@ -25,7 +25,6 @@ class DeviceNULL : public DeviceImpl
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
};
diff --git a/src/libANGLE/renderer/vulkan/BUILD.gn b/src/libANGLE/renderer/vulkan/BUILD.gn
index 3f60a4bd6f..eefc2ab640 100644
--- a/src/libANGLE/renderer/vulkan/BUILD.gn
+++ b/src/libANGLE/renderer/vulkan/BUILD.gn
@@ -119,11 +119,11 @@ template("angle_vulkan_backend_template") {
if (angle_enable_cl) {
deps += [
"$angle_root/third_party/clspv/:clspv_core_shared",
- "$angle_root/third_party/vulkan-deps/spirv-tools/src/:spvtools",
- "$angle_root/third_party/vulkan-deps/spirv-tools/src/:spvtools_opt",
+ "$angle_root/third_party/spirv-tools/src/:spvtools",
+ "$angle_root/third_party/spirv-tools/src/:spvtools_opt",
]
include_dirs = [
- "$angle_root/third_party/vulkan-deps/spirv-tools/src/include",
+ "$angle_root/third_party/spirv-tools/src/include",
"$angle_root/third_party/clspv/src/include",
]
}
diff --git a/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp b/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp
index a448fb2a48..4ee5e7819c 100644
--- a/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp
+++ b/src/libANGLE/renderer/vulkan/CLCommandQueueVk.cpp
@@ -58,7 +58,7 @@ angle::Result CLCommandQueueVk::init()
ANGLE_CL_IMPL_TRY_ERROR(
vk::OutsideRenderPassCommandBuffer::InitializeCommandPool(
mContext, &mCommandPool.outsideRenderPassPool,
- mContext->getRenderer()->getDeviceQueueIndex(), getProtectionType()),
+ mContext->getRenderer()->getQueueFamilyIndex(), getProtectionType()),
CL_OUT_OF_RESOURCES);
ANGLE_CL_IMPL_TRY_ERROR(mContext->getRenderer()->getOutsideRenderPassCommandBufferHelper(
diff --git a/src/libANGLE/renderer/vulkan/CLContextVk.cpp b/src/libANGLE/renderer/vulkan/CLContextVk.cpp
index 5acd9a1a8a..0aae828100 100644
--- a/src/libANGLE/renderer/vulkan/CLContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/CLContextVk.cpp
@@ -26,7 +26,9 @@ CLContextVk::CLContextVk(const cl::Context &context, const cl::DevicePtrs device
: CLContextImpl(context),
vk::Context(getPlatform()->getRenderer()),
mAssociatedDevices(devicePtrs)
-{}
+{
+ mDeviceQueueIndex = mRenderer->getDefaultDeviceQueueIndex();
+}
CLContextVk::~CLContextVk() = default;
diff --git a/src/libANGLE/renderer/vulkan/CommandProcessor.cpp b/src/libANGLE/renderer/vulkan/CommandProcessor.cpp
index a8df7b38a8..4de90d8f28 100644
--- a/src/libANGLE/renderer/vulkan/CommandProcessor.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandProcessor.cpp
@@ -45,6 +45,28 @@ void InitializeSubmitInfo(VkSubmitInfo *submitInfo,
submitInfo->pSignalSemaphores = &signalSemaphore;
}
}
+
+void GetDeviceQueue(VkDevice device,
+ bool makeProtected,
+ uint32_t queueFamilyIndex,
+ uint32_t queueIndex,
+ VkQueue *queue)
+{
+ if (makeProtected)
+ {
+ VkDeviceQueueInfo2 queueInfo2 = {};
+ queueInfo2.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2;
+ queueInfo2.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
+ queueInfo2.queueFamilyIndex = queueFamilyIndex;
+ queueInfo2.queueIndex = queueIndex;
+
+ vkGetDeviceQueue2(device, &queueInfo2, queue);
+ }
+ else
+ {
+ vkGetDeviceQueue(device, queueFamilyIndex, queueIndex, queue);
+ }
+}
} // namespace
// SharedFence implementation
@@ -1063,18 +1085,12 @@ CommandQueue::~CommandQueue() = default;
void CommandQueue::destroy(Context *context)
{
+ vk::Renderer *renderer = context->getRenderer();
+
std::lock_guard<angle::SimpleMutex> lock(mMutex);
std::lock_guard<angle::SimpleMutex> enqueuelock(mQueueSubmitMutex);
- // Force all commands to finish by flushing all queues.
- for (VkQueue queue : mQueueMap)
- {
- if (queue != VK_NULL_HANDLE)
- {
- vkQueueWaitIdle(queue);
- }
- }
- vk::Renderer *renderer = context->getRenderer();
+ mQueueMap.destroy();
// Assigns an infinite "last completed" serial to force garbage to delete.
mLastCompletedSerials.fill(Serial::Infinite());
@@ -1101,7 +1117,10 @@ void CommandQueue::destroy(Context *context)
ASSERT(mFinishedCommandBatches.empty());
}
-angle::Result CommandQueue::init(Context *context, const DeviceQueueMap &queueMap)
+angle::Result CommandQueue::init(Context *context,
+ const QueueFamily &queueFamily,
+ bool enableProtectedContent,
+ uint32_t queueCount)
{
std::lock_guard<angle::SimpleMutex> lock(mMutex);
// In case Renderer gets re-initialized, we can't rely on constructor to do initialization.
@@ -1109,11 +1128,10 @@ angle::Result CommandQueue::init(Context *context, const DeviceQueueMap &queueMa
mLastCompletedSerials.fill(kZeroSerial);
// Assign before initializing the command pools in order to get the queue family index.
- mQueueMap = queueMap;
-
+ mQueueMap.initialize(context->getDevice(), queueFamily, enableProtectedContent, 0, queueCount);
ANGLE_TRY(initCommandPool(context, ProtectionType::Unprotected));
- if (queueMap.isProtected())
+ if (mQueueMap.isProtected())
{
ANGLE_TRY(initCommandPool(context, ProtectionType::Protected));
}
@@ -1730,53 +1748,25 @@ constexpr float kVulkanQueuePriorityHigh = 1.0;
const float QueueFamily::kQueuePriorities[static_cast<uint32_t>(egl::ContextPriority::EnumCount)] =
{kVulkanQueuePriorityMedium, kVulkanQueuePriorityHigh, kVulkanQueuePriorityLow};
-egl::ContextPriority DeviceQueueMap::getDevicePriority(egl::ContextPriority priority) const
-{
- return mPriorities[priority];
-}
-
DeviceQueueMap::~DeviceQueueMap() {}
-DeviceQueueMap &DeviceQueueMap::operator=(const DeviceQueueMap &other)
-{
- ASSERT(this != &other);
- if ((this != &other) && other.valid())
- {
- mIndex = other.mIndex;
- mIsProtected = other.mIsProtected;
- mPriorities[egl::ContextPriority::Low] = other.mPriorities[egl::ContextPriority::Low];
- mPriorities[egl::ContextPriority::Medium] = other.mPriorities[egl::ContextPriority::Medium];
- mPriorities[egl::ContextPriority::High] = other.mPriorities[egl::ContextPriority::High];
- *static_cast<angle::PackedEnumMap<egl::ContextPriority, VkQueue> *>(this) = other;
- }
- return *this;
-}
-
-void QueueFamily::getDeviceQueue(VkDevice device,
- bool makeProtected,
- uint32_t queueIndex,
- VkQueue *queue)
+void DeviceQueueMap::destroy()
{
- if (makeProtected)
- {
- VkDeviceQueueInfo2 queueInfo2 = {};
- queueInfo2.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2;
- queueInfo2.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
- queueInfo2.queueFamilyIndex = mIndex;
- queueInfo2.queueIndex = queueIndex;
-
- vkGetDeviceQueue2(device, &queueInfo2, queue);
- }
- else
+ // Force all commands to finish by flushing all queues.
+ for (const QueueAndIndex &queueAndIndex : mQueueAndIndices)
{
- vkGetDeviceQueue(device, mIndex, queueIndex, queue);
+ if (queueAndIndex.queue != VK_NULL_HANDLE)
+ {
+ vkQueueWaitIdle(queueAndIndex.queue);
+ }
}
}
-DeviceQueueMap QueueFamily::initializeQueueMap(VkDevice device,
- bool makeProtected,
- uint32_t queueIndex,
- uint32_t queueCount)
+void DeviceQueueMap::initialize(VkDevice device,
+ const QueueFamily &queueFamily,
+ bool makeProtected,
+ uint32_t queueIndex,
+ uint32_t queueCount)
{
// QueueIndexing:
constexpr uint32_t kQueueIndexMedium = 0;
@@ -1784,44 +1774,49 @@ DeviceQueueMap QueueFamily::initializeQueueMap(VkDevice device,
constexpr uint32_t kQueueIndexLow = 2;
ASSERT(queueCount);
- ASSERT((queueIndex + queueCount) <= mProperties.queueCount);
- DeviceQueueMap queueMap(mIndex, makeProtected);
+ ASSERT((queueIndex + queueCount) <= queueFamily.getProperties()->queueCount);
+ mQueueFamilyIndex = queueFamily.getQueueFamilyIndex();
+ mIsProtected = makeProtected;
- getDeviceQueue(device, makeProtected, queueIndex + kQueueIndexMedium,
- &queueMap[egl::ContextPriority::Medium]);
- queueMap.mPriorities[egl::ContextPriority::Medium] = egl::ContextPriority::Medium;
+ VkQueue queue = VK_NULL_HANDLE;
+ GetDeviceQueue(device, makeProtected, mQueueFamilyIndex, queueIndex + kQueueIndexMedium,
+ &queue);
+ mQueueAndIndices[egl::ContextPriority::Medium] = {egl::ContextPriority::Medium, queue,
+ queueIndex + kQueueIndexMedium};
// If at least 2 queues, High has its own queue
if (queueCount > 1)
{
- getDeviceQueue(device, makeProtected, queueIndex + kQueueIndexHigh,
- &queueMap[egl::ContextPriority::High]);
- queueMap.mPriorities[egl::ContextPriority::High] = egl::ContextPriority::High;
+ GetDeviceQueue(device, makeProtected, mQueueFamilyIndex, queueIndex + kQueueIndexHigh,
+ &queue);
+ mQueueAndIndices[egl::ContextPriority::High] = {egl::ContextPriority::High, queue,
+ queueIndex + kQueueIndexHigh};
}
else
{
- queueMap[egl::ContextPriority::High] = queueMap[egl::ContextPriority::Medium];
- queueMap.mPriorities[egl::ContextPriority::High] = egl::ContextPriority::Medium;
+ mQueueAndIndices[egl::ContextPriority::High] =
+ mQueueAndIndices[egl::ContextPriority::Medium];
}
// If at least 3 queues, Low has its own queue. Adjust Low priority.
if (queueCount > 2)
{
- getDeviceQueue(device, makeProtected, queueIndex + kQueueIndexLow,
- &queueMap[egl::ContextPriority::Low]);
- queueMap.mPriorities[egl::ContextPriority::Low] = egl::ContextPriority::Low;
+ GetDeviceQueue(device, makeProtected, mQueueFamilyIndex, queueIndex + kQueueIndexLow,
+ &queue);
+ mQueueAndIndices[egl::ContextPriority::Low] = {egl::ContextPriority::Low, queue,
+ queueIndex + kQueueIndexLow};
}
else
{
- queueMap[egl::ContextPriority::Low] = queueMap[egl::ContextPriority::Medium];
- queueMap.mPriorities[egl::ContextPriority::Low] = egl::ContextPriority::Medium;
+ mQueueAndIndices[egl::ContextPriority::Low] =
+ mQueueAndIndices[egl::ContextPriority::Medium];
}
- return queueMap;
}
-void QueueFamily::initialize(const VkQueueFamilyProperties &queueFamilyProperties, uint32_t index)
+void QueueFamily::initialize(const VkQueueFamilyProperties &queueFamilyProperties,
+ uint32_t queueFamilyIndex)
{
- mProperties = queueFamilyProperties;
- mIndex = index;
+ mProperties = queueFamilyProperties;
+ mQueueFamilyIndex = queueFamilyIndex;
}
uint32_t QueueFamily::FindIndex(const std::vector<VkQueueFamilyProperties> &queueFamilyProperties,
diff --git a/src/libANGLE/renderer/vulkan/CommandProcessor.h b/src/libANGLE/renderer/vulkan/CommandProcessor.h
index e4290f8cdc..92b311980a 100644
--- a/src/libANGLE/renderer/vulkan/CommandProcessor.h
+++ b/src/libANGLE/renderer/vulkan/CommandProcessor.h
@@ -300,12 +300,13 @@ class QueueFamily final : angle::NonCopyable
static const uint32_t kQueueCount = static_cast<uint32_t>(egl::ContextPriority::EnumCount);
static const float kQueuePriorities[static_cast<uint32_t>(egl::ContextPriority::EnumCount)];
- QueueFamily() : mProperties{}, mIndex(kInvalidIndex) {}
+ QueueFamily() : mProperties{}, mQueueFamilyIndex(kInvalidIndex) {}
~QueueFamily() {}
- void initialize(const VkQueueFamilyProperties &queueFamilyProperties, uint32_t index);
- bool valid() const { return (mIndex != kInvalidIndex); }
- uint32_t getIndex() const { return mIndex; }
+ void initialize(const VkQueueFamilyProperties &queueFamilyProperties,
+ uint32_t queueFamilyIndex);
+ bool valid() const { return (mQueueFamilyIndex != kInvalidIndex); }
+ uint32_t getQueueFamilyIndex() const { return mQueueFamilyIndex; }
const VkQueueFamilyProperties *getProperties() const { return &mProperties; }
bool isGraphics() const { return ((mProperties.queueFlags & VK_QUEUE_GRAPHICS_BIT) > 0); }
bool isCompute() const { return ((mProperties.queueFlags & VK_QUEUE_COMPUTE_BIT) > 0); }
@@ -315,40 +316,52 @@ class QueueFamily final : angle::NonCopyable
}
uint32_t getDeviceQueueCount() const { return mProperties.queueCount; }
- DeviceQueueMap initializeQueueMap(VkDevice device,
- bool makeProtected,
- uint32_t queueIndex,
- uint32_t queueCount);
-
private:
VkQueueFamilyProperties mProperties;
- uint32_t mIndex;
-
- void getDeviceQueue(VkDevice device, bool makeProtected, uint32_t queueIndex, VkQueue *queue);
+ uint32_t mQueueFamilyIndex;
};
-class DeviceQueueMap : public angle::PackedEnumMap<egl::ContextPriority, VkQueue>
+class DeviceQueueMap final
{
- friend QueueFamily;
-
public:
- DeviceQueueMap() : mIndex(QueueFamily::kInvalidIndex), mIsProtected(false) {}
- DeviceQueueMap(uint32_t queueFamilyIndex, bool isProtected)
- : mIndex(queueFamilyIndex), mIsProtected(isProtected)
- {}
- DeviceQueueMap(const DeviceQueueMap &other) = default;
+ DeviceQueueMap() : mQueueFamilyIndex(QueueFamily::kInvalidIndex), mIsProtected(false) {}
~DeviceQueueMap();
- DeviceQueueMap &operator=(const DeviceQueueMap &other);
- bool valid() const { return (mIndex != QueueFamily::kInvalidIndex); }
- uint32_t getIndex() const { return mIndex; }
+ void initialize(VkDevice device,
+ const QueueFamily &queueFamily,
+ bool makeProtected,
+ uint32_t queueIndex,
+ uint32_t queueCount);
+ void destroy();
+
+ bool valid() const { return (mQueueFamilyIndex != QueueFamily::kInvalidIndex); }
+ uint32_t getQueueFamilyIndex() const { return mQueueFamilyIndex; }
bool isProtected() const { return mIsProtected; }
- egl::ContextPriority getDevicePriority(egl::ContextPriority priority) const;
+ egl::ContextPriority getDevicePriority(egl::ContextPriority priority) const
+ {
+ return mQueueAndIndices[priority].devicePriority;
+ }
+ DeviceQueueIndex getDeviceQueueIndex(egl::ContextPriority priority) const
+ {
+ return DeviceQueueIndex(mQueueFamilyIndex, mQueueAndIndices[priority].index);
+ }
+ const VkQueue &getQueue(egl::ContextPriority priority) const
+ {
+ return mQueueAndIndices[priority].queue;
+ }
private:
- uint32_t mIndex;
+ uint32_t mQueueFamilyIndex;
bool mIsProtected;
- angle::PackedEnumMap<egl::ContextPriority, egl::ContextPriority> mPriorities;
+ struct QueueAndIndex
+ {
+ // The actual priority that used
+ egl::ContextPriority devicePriority;
+ VkQueue queue;
+ // The queueIndex used for VkGetDeviceQueue
+ uint32_t index;
+ };
+ angle::PackedEnumMap<egl::ContextPriority, QueueAndIndex> mQueueAndIndices;
};
// Note all public APIs of CommandQueue class must be thread safe.
@@ -358,7 +371,11 @@ class CommandQueue : angle::NonCopyable
CommandQueue();
~CommandQueue();
- angle::Result init(Context *context, const DeviceQueueMap &queueMap);
+ angle::Result init(Context *context,
+ const QueueFamily &queueFamily,
+ bool enableProtectedContent,
+ uint32_t queueCount);
+
void destroy(Context *context);
void handleDeviceLost(Renderer *renderer);
@@ -369,9 +386,13 @@ class CommandQueue : angle::NonCopyable
{
return mQueueMap.getDevicePriority(priority);
}
- uint32_t getDeviceQueueIndex() const { return mQueueMap.getIndex(); }
- VkQueue getQueue(egl::ContextPriority priority) const { return mQueueMap[priority]; }
+ DeviceQueueIndex getDeviceQueueIndex(egl::ContextPriority priority) const
+ {
+ return mQueueMap.getDeviceQueueIndex(priority);
+ }
+
+ VkQueue getQueue(egl::ContextPriority priority) const { return mQueueMap.getQueue(priority); }
Serial getLastSubmittedSerial(SerialIndex index) const { return mLastSubmittedSerials[index]; }
@@ -513,7 +534,7 @@ class CommandQueue : angle::NonCopyable
angle::Result initCommandPool(Context *context, ProtectionType protectionType)
{
PersistentCommandPool &commandPool = mPrimaryCommandPoolMap[protectionType];
- return commandPool.init(context, protectionType, mQueueMap.getIndex());
+ return commandPool.init(context, protectionType, mQueueMap.getQueueFamilyIndex());
}
// Protect multi-thread access to mInFlightCommands.pop and ensure ordering of submission.
@@ -636,6 +657,8 @@ class CommandProcessor : public Context
}
Serial getLastEnqueuedSerial(SerialIndex index) const { return mLastEnqueuedSerials[index]; }
+ std::thread::id getThreadId() const { return mTaskThread.get_id(); }
+
private:
bool hasPendingError() const
{
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 39ca051602..05c8a3bd00 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -1209,6 +1209,12 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, vk::Rendere
mPipelineDirtyBitsMask.reset(gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING);
}
+ // Stash the mRefCountedEventRecycler in vk::Context for ImageHelper to conveniently access
+ mShareGroupRefCountedEventsGarbageRecycler =
+ mShareGroupVk->getRefCountedEventsGarbageRecycler();
+
+ mDeviceQueueIndex = renderer->getDeviceQueueIndex(mContextPriority);
+
angle::PerfMonitorCounterGroup vulkanGroup;
vulkanGroup.name = "vulkan";
@@ -1255,6 +1261,7 @@ void ContextVk::onDestroy(const gl::Context *context)
VkDevice device = getDevice();
+ mRenderer->getRefCountedEventRecycler()->destroy(getDevice());
mDefaultUniformStorage.release(mRenderer);
mEmptyBuffer.release(mRenderer);
@@ -1403,10 +1410,10 @@ angle::Result ContextVk::initialize(const angle::ImageLoadContext &imageLoadCont
// Assign initial command buffers from queue
ANGLE_TRY(vk::OutsideRenderPassCommandBuffer::InitializeCommandPool(
- this, &mCommandPools.outsideRenderPassPool, mRenderer->getDeviceQueueIndex(),
+ this, &mCommandPools.outsideRenderPassPool, mRenderer->getQueueFamilyIndex(),
getProtectionType()));
ANGLE_TRY(vk::RenderPassCommandBuffer::InitializeCommandPool(
- this, &mCommandPools.renderPassPool, mRenderer->getDeviceQueueIndex(),
+ this, &mCommandPools.renderPassPool, mRenderer->getQueueFamilyIndex(),
getProtectionType()));
ANGLE_TRY(mRenderer->getOutsideRenderPassCommandBufferHelper(
this, &mCommandPools.outsideRenderPassPool, &mOutsideRenderPassCommandsAllocator,
@@ -3648,6 +3655,9 @@ angle::Result ContextVk::submitCommands(const vk::Semaphore *signalSemaphore,
// Now that we have submitted commands, some of pending garbage may no longer pending
// and should be moved to garbage list.
mRenderer->cleanupPendingSubmissionGarbage();
+ // In case of big amount of render/submission within one frame, if we accumulate excessive
+ // amount of garbage, also trigger the cleanup.
+ mShareGroupVk->cleanupExcessiveRefCountedEventGarbage(mRenderer);
mComputeDirtyBits |= mNewComputeCommandBufferDirtyBits;
@@ -7687,12 +7697,18 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore,
// Try to detect frame boundary for both on screen and offscreen usage by detecting
// fush/finish/swap.
- if ((renderPassClosureReason == RenderPassClosureReason::GLFlush ||
- renderPassClosureReason == RenderPassClosureReason::GLFinish ||
- renderPassClosureReason == RenderPassClosureReason::EGLSwapBuffers) &&
- mShareGroupVk->isDueForBufferPoolPrune(mRenderer))
+ bool frameBoundary = renderPassClosureReason == RenderPassClosureReason::GLFlush ||
+ renderPassClosureReason == RenderPassClosureReason::GLFinish ||
+ renderPassClosureReason == RenderPassClosureReason::EGLSwapBuffers;
+ if (frameBoundary)
{
- mShareGroupVk->pruneDefaultBufferPools(mRenderer);
+ if (mShareGroupVk->isDueForBufferPoolPrune(mRenderer))
+ {
+ mShareGroupVk->pruneDefaultBufferPools(mRenderer);
+ }
+ // Always clean up grabage and destroy the excessive free list at frame boundary.
+ mShareGroupVk->cleanupRefCountedEventGarbage(mRenderer);
+ mRenderer->getRefCountedEventRecycler()->destroy(getDevice());
}
// Since we just flushed, deferred flush is no longer deferred.
@@ -7988,6 +8004,9 @@ angle::Result ContextVk::flushCommandsAndEndRenderPassWithoutSubmit(RenderPassCl
mRenderPassCommands->getAttachmentOps(), &renderPass));
flushDescriptorSetUpdates();
+ // Collect RefCountedEvent garbage before submitting to renderer
+ mRenderPassCommands->collectRefCountedEventsGarbage(
+ mShareGroupVk->getRefCountedEventsGarbageRecycler());
// Save the queueSerial before calling flushRenderPassCommands, which may return a new
// mRenderPassCommands
@@ -8269,6 +8288,11 @@ angle::Result ContextVk::flushOutsideRenderPassCommands()
flushDescriptorSetUpdates();
+ // Track completion of this command buffer.
+ mOutsideRenderPassCommands->flushSetEvents(this);
+ mOutsideRenderPassCommands->collectRefCountedEventsGarbage(
+ mShareGroupVk->getRefCountedEventsGarbageRecycler());
+
// Save the queueSerial before calling flushOutsideRPCommands, which may return a new
// mOutsideRenderPassCommands
ASSERT(QueueSerialsHaveDifferentIndexOrSmaller(mLastFlushedQueueSerial,
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h
index ed473f791e..c923e2415a 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.h
+++ b/src/libANGLE/renderer/vulkan/ContextVk.h
@@ -381,7 +381,11 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
gl::TextureBarrierVector *textureBarriers) override;
// Sets effective Context Priority. Changed by ShareGroupVk.
- void setPriority(egl::ContextPriority newPriority) { mContextPriority = newPriority; }
+ void setPriority(egl::ContextPriority newPriority)
+ {
+ mContextPriority = newPriority;
+ mDeviceQueueIndex = mRenderer->getDeviceQueueIndex(mContextPriority);
+ }
VkDevice getDevice() const;
// Effective Context Priority
diff --git a/src/libANGLE/renderer/vulkan/DeviceVk.cpp b/src/libANGLE/renderer/vulkan/DeviceVk.cpp
index d40cae4990..2d4be5d611 100644
--- a/src/libANGLE/renderer/vulkan/DeviceVk.cpp
+++ b/src/libANGLE/renderer/vulkan/DeviceVk.cpp
@@ -133,11 +133,6 @@ egl::Error DeviceVk::getAttribute(const egl::Display *display, EGLint attribute,
}
}
-EGLint DeviceVk::getType()
-{
- return EGL_VULKAN_DEVICE_ANGLE;
-}
-
void DeviceVk::generateExtensions(egl::DeviceExtensions *outExtensions) const
{
outExtensions->deviceVulkan = true;
diff --git a/src/libANGLE/renderer/vulkan/DeviceVk.h b/src/libANGLE/renderer/vulkan/DeviceVk.h
index ef1a91a478..308fc997fe 100644
--- a/src/libANGLE/renderer/vulkan/DeviceVk.h
+++ b/src/libANGLE/renderer/vulkan/DeviceVk.h
@@ -31,7 +31,6 @@ class DeviceVk : public DeviceImpl
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
vk::Renderer *getRenderer() const { return mRenderer; }
diff --git a/src/libANGLE/renderer/vulkan/DisplayVk.cpp b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
index 60817ef78e..0be7c8a4f0 100644
--- a/src/libANGLE/renderer/vulkan/DisplayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/DisplayVk.cpp
@@ -179,6 +179,8 @@ egl::Error DisplayVk::initialize(egl::Display *display)
getWSIExtension(), getWSILayer(), getWindowSystem(), mState.featureOverrides);
ANGLE_TRY(angle::ToEGL(result, EGL_NOT_INITIALIZED));
+ mDeviceQueueIndex = mRenderer->getDeviceQueueIndex(egl::ContextPriority::Medium);
+
InstallDebugAnnotator(display, mRenderer);
// Query and cache supported surface format and colorspace for later use.
diff --git a/src/libANGLE/renderer/vulkan/MemoryObjectVk.cpp b/src/libANGLE/renderer/vulkan/MemoryObjectVk.cpp
index 8f8752cc37..fa53172c38 100644
--- a/src/libANGLE/renderer/vulkan/MemoryObjectVk.cpp
+++ b/src/libANGLE/renderer/vulkan/MemoryObjectVk.cpp
@@ -247,7 +247,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
VkMemoryPropertyFlags flags = hasProtectedContent ? VK_MEMORY_PROPERTY_PROTECTED_BIT : 0;
ANGLE_TRY(image->initExternalMemory(contextVk, renderer->getMemoryProperties(),
externalMemoryRequirements, 1, &importMemoryInfo,
- renderer->getQueueFamilyIndex(), flags));
+ contextVk->getDeviceQueueIndex(), flags));
return angle::Result::Continue;
}
diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
index 3827912729..0f9c157bc9 100644
--- a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
@@ -203,15 +203,14 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex
VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
// Transfer the image to this queue if needed
- uint32_t rendererQueueFamilyIndex = contextVk->getRenderer()->getQueueFamilyIndex();
- if (mImage->isQueueChangeNeccesary(rendererQueueFamilyIndex))
+ if (mImage->isQueueFamilyChangeNeccesary(contextVk->getDeviceQueueIndex()))
{
vk::OutsideRenderPassCommandBuffer *commandBuffer;
vk::CommandBufferAccess access;
access.onExternalAcquireRelease(mImage);
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
mImage->changeLayoutAndQueue(contextVk, aspect, vk::ImageLayout::ColorWrite,
- rendererQueueFamilyIndex, commandBuffer);
+ contextVk->getDeviceQueueIndex(), commandBuffer);
ANGLE_TRY(contextVk->onEGLImageQueueChange());
}
diff --git a/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp b/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp
index a916ec1e92..6dae003151 100644
--- a/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp
+++ b/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp
@@ -71,8 +71,6 @@ angle::Result SemaphoreVk::wait(gl::Context *context,
ANGLE_TRY(contextVk->syncExternalMemory());
}
- uint32_t rendererQueueFamilyIndex = contextVk->getRenderer()->getQueueFamilyIndex();
-
if (!bufferBarriers.empty())
{
// Perform a queue ownership transfer for each buffer.
@@ -87,8 +85,8 @@ angle::Result SemaphoreVk::wait(gl::Context *context,
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
// Queue ownership transfer.
- bufferHelper.acquireFromExternal(VK_QUEUE_FAMILY_EXTERNAL, rendererQueueFamilyIndex,
- commandBuffer);
+ bufferHelper.acquireFromExternal(vk::kExternalDeviceQueueIndex,
+ contextVk->getDeviceQueueIndex(), commandBuffer);
}
}
@@ -114,8 +112,8 @@ angle::Result SemaphoreVk::wait(gl::Context *context,
ASSERT(!image.hasStagedUpdatesInAllocatedLevels() || image.hasEmulatedImageChannels());
// Queue ownership transfer and layout transition.
- image.acquireFromExternal(contextVk, VK_QUEUE_FAMILY_EXTERNAL, rendererQueueFamilyIndex,
- layout, commandBuffer);
+ image.acquireFromExternal(contextVk, vk::kExternalDeviceQueueIndex,
+ contextVk->getDeviceQueueIndex(), layout, commandBuffer);
}
}
@@ -130,8 +128,6 @@ angle::Result SemaphoreVk::signal(gl::Context *context,
ContextVk *contextVk = vk::GetImpl(context);
vk::Renderer *renderer = contextVk->getRenderer();
- uint32_t rendererQueueFamilyIndex = renderer->getQueueFamilyIndex();
-
if (!bufferBarriers.empty())
{
// Perform a queue ownership transfer for each buffer.
@@ -147,8 +143,7 @@ angle::Result SemaphoreVk::signal(gl::Context *context,
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
// Queue ownership transfer.
- bufferHelper.releaseToExternal(rendererQueueFamilyIndex, VK_QUEUE_FAMILY_EXTERNAL,
- commandBuffer);
+ bufferHelper.releaseToExternal(vk::kExternalDeviceQueueIndex, commandBuffer);
}
}
@@ -180,8 +175,8 @@ angle::Result SemaphoreVk::signal(gl::Context *context,
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
// Queue ownership transfer and layout transition.
- image.releaseToExternal(contextVk, rendererQueueFamilyIndex, VK_QUEUE_FAMILY_EXTERNAL,
- layout, commandBuffer);
+ image.releaseToExternal(contextVk, vk::kExternalDeviceQueueIndex, layout,
+ commandBuffer);
}
}
diff --git a/src/libANGLE/renderer/vulkan/ShareGroupVk.cpp b/src/libANGLE/renderer/vulkan/ShareGroupVk.cpp
index 26a3c1c1c5..c054a8c010 100644
--- a/src/libANGLE/renderer/vulkan/ShareGroupVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ShareGroupVk.cpp
@@ -160,6 +160,8 @@ void ShareGroupVk::onDestroy(const egl::Display *display)
DisplayVk *displayVk = vk::GetImpl(display);
vk::Renderer *renderer = displayVk->getRenderer();
+ mRefCountedEventsGarbageRecycler.destroy(renderer);
+
for (std::unique_ptr<vk::BufferPool> &pool : mDefaultBufferPools)
{
if (pool)
diff --git a/src/libANGLE/renderer/vulkan/ShareGroupVk.h b/src/libANGLE/renderer/vulkan/ShareGroupVk.h
index 43bfb42250..7768785883 100644
--- a/src/libANGLE/renderer/vulkan/ShareGroupVk.h
+++ b/src/libANGLE/renderer/vulkan/ShareGroupVk.h
@@ -96,6 +96,24 @@ class ShareGroupVk : public ShareGroupImpl
vk::WaitableMonolithicPipelineCreationTask *taskOut);
void waitForCurrentMonolithicPipelineCreationTask();
+ vk::RefCountedEventsGarbageRecycler *getRefCountedEventsGarbageRecycler()
+ {
+ return &mRefCountedEventsGarbageRecycler;
+ }
+ void cleanupRefCountedEventGarbage(vk::Renderer *renderer)
+ {
+ mRefCountedEventsGarbageRecycler.cleanup(renderer);
+ }
+ void cleanupExcessiveRefCountedEventGarbage(vk::Renderer *renderer)
+ {
+ // TODO: b/336844257 needs tune.
+ constexpr size_t kExcessiveGarbageCountThreshold = 256;
+ if (mRefCountedEventsGarbageRecycler.getGarbageCount() > kExcessiveGarbageCountThreshold)
+ {
+ mRefCountedEventsGarbageRecycler.cleanup(renderer);
+ }
+ }
+
private:
angle::Result updateContextsPriority(ContextVk *contextVk, egl::ContextPriority newPriority);
@@ -141,6 +159,9 @@ class ShareGroupVk : public ShareGroupImpl
// Texture update manager used to flush uploaded mutable textures.
TextureUpload mTextureUpload;
+
+ // Holds RefCountedEvent that are free and ready to reuse
+ vk::RefCountedEventsGarbageRecycler mRefCountedEventsGarbageRecycler;
};
} // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index d27035ad9e..1615dd681c 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -2797,10 +2797,7 @@ angle::Result TextureVk::flushImageStagedUpdates(ContextVk *contextVk)
angle::Result TextureVk::performImageQueueTransferIfNecessary(ContextVk *contextVk)
{
- const vk::Renderer *renderer = contextVk->getRenderer();
-
- const uint32_t rendererQueueFamilyIndex = renderer->getQueueFamilyIndex();
- if (mImage->valid() && mImage->isQueueChangeNeccesary(rendererQueueFamilyIndex))
+ if (mImage->valid() && mImage->isQueueFamilyChangeNeccesary(contextVk->getDeviceQueueIndex()))
{
vk::ImageLayout newLayout = vk::ImageLayout::AllGraphicsShadersWrite;
if (mImage->getUsage() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
@@ -2822,7 +2819,7 @@ angle::Result TextureVk::performImageQueueTransferIfNecessary(ContextVk *context
access.onExternalAcquireRelease(mImage);
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
mImage->changeLayoutAndQueue(contextVk, mImage->getAspectFlags(), newLayout,
- rendererQueueFamilyIndex, commandBuffer);
+ contextVk->getDeviceQueueIndex(), commandBuffer);
ANGLE_TRY(contextVk->onEGLImageQueueChange());
}
diff --git a/src/libANGLE/renderer/vulkan/UtilsVk.cpp b/src/libANGLE/renderer/vulkan/UtilsVk.cpp
index 526b5a0680..05feb1fd66 100644
--- a/src/libANGLE/renderer/vulkan/UtilsVk.cpp
+++ b/src/libANGLE/renderer/vulkan/UtilsVk.cpp
@@ -1064,7 +1064,7 @@ angle::spirv::Blob MakeFragShader(
code.reserve(169);
// Header
- spirv::WriteSpirvHeader(&code, kIdCount);
+ spirv::WriteSpirvHeader(&code, spirv::kVersion_1_0, kIdCount);
// The preamble
InsertPreamble(colorAttachmentCount, unresolveDepth, unresolveStencilWithShaderExport, &code);
diff --git a/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp b/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp
index 508be624d1..66db1a4484 100644
--- a/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp
+++ b/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp
@@ -446,7 +446,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
ANGLE_TRY(mImage->initExternalMemory(displayVk, renderer->getMemoryProperties(),
externalMemoryRequirements, 1, &dedicatedAllocInfoPtr,
- VK_QUEUE_FAMILY_FOREIGN_EXT, flags));
+ vk::kForeignDeviceQueueIndex, flags));
if (isExternal)
{
diff --git a/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py b/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py
index f8233b038e..86118a7061 100644
--- a/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py
+++ b/src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py
@@ -99,7 +99,7 @@ def main():
input_file_name = 'vk_mandatory_format_support_data.json'
vk_format_map_path = 'vk_format_map.json'
out_file_name = 'vk_mandatory_format_support_table_autogen.cpp'
- vk_xml_file = '../../../../third_party/vulkan-deps/vulkan-headers/src/registry/vk.xml'
+ vk_xml_file = '../../../../third_party/vulkan-headers/src/registry/vk.xml'
# auto_script parameters.
if len(sys.argv) > 1:
diff --git a/src/libANGLE/renderer/vulkan/linux/DmaBufImageSiblingVkLinux.cpp b/src/libANGLE/renderer/vulkan/linux/DmaBufImageSiblingVkLinux.cpp
index 118f37744b..d52409b011 100644
--- a/src/libANGLE/renderer/vulkan/linux/DmaBufImageSiblingVkLinux.cpp
+++ b/src/libANGLE/renderer/vulkan/linux/DmaBufImageSiblingVkLinux.cpp
@@ -570,7 +570,7 @@ angle::Result DmaBufImageSiblingVkLinux::initWithFormat(DisplayVk *displayVk,
return mImage->initExternalMemory(
displayVk, renderer->getMemoryProperties(), externalMemoryRequirements, allocateInfoCount,
- allocateInfo.allocateInfoPtr.data(), VK_QUEUE_FAMILY_FOREIGN_EXT, flags);
+ allocateInfo.allocateInfoPtr.data(), vk::kForeignDeviceQueueIndex, flags);
}
angle::Result DmaBufImageSiblingVkLinux::initImpl(DisplayVk *displayVk)
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index f237bca9ed..548bf79110 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -1526,13 +1526,8 @@ 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 (!mRefCountedEventCollector.empty())
- {
- context->getRenderer()->collectRefCountedEventsGarbage(
- mQueueSerial, std::move(mRefCountedEventCollector));
- }
+ ASSERT(mRefCountedEvents.mask.none());
+ ASSERT(mRefCountedEventCollector.empty());
}
template <class DerivedT>
@@ -1745,8 +1740,12 @@ void CommandBufferHelperCommon::flushSetEventsImpl(Context *context, CommandBuff
ASSERT(refCountedEvent.valid());
const ImageMemoryBarrierData &layoutData =
kImageMemoryBarrierData[refCountedEvent.getImageLayout()];
- commandBuffer->setEvent(refCountedEvent.getEvent().getHandle(),
- GetImageLayoutDstStageMask(context, layoutData));
+ VkPipelineStageFlags stageMask = GetImageLayoutDstStageMask(context, layoutData);
+ if (refCountedEvent.needsReset())
+ {
+ commandBuffer->resetEvent(refCountedEvent.getEvent().getHandle(), stageMask);
+ }
+ commandBuffer->setEvent(refCountedEvent.getEvent().getHandle(), stageMask);
// We no longer need event, so garbage collect it.
mRefCountedEventCollector.emplace_back(std::move(refCountedEvent));
}
@@ -1882,6 +1881,16 @@ void OutsideRenderPassCommandBufferHelper::trackImagesWithEvent(Context *context
flushSetEventsImpl(context, &mCommandBuffer);
}
+void OutsideRenderPassCommandBufferHelper::collectRefCountedEventsGarbage(
+ RefCountedEventsGarbageRecycler *garbageRecycler)
+{
+ ASSERT(garbageRecycler != nullptr);
+ if (!mRefCountedEventCollector.empty())
+ {
+ garbageRecycler->collectGarbage(mQueueSerial, std::move(mRefCountedEventCollector));
+ }
+}
+
angle::Result OutsideRenderPassCommandBufferHelper::flushToPrimary(Context *context,
CommandsState *commandsState)
{
@@ -2691,6 +2700,45 @@ void RenderPassCommandBufferHelper::trackImagesWithEvent(Context *context,
}
}
+void RenderPassCommandBufferHelper::executeSetEvents(Context *context,
+ PrimaryCommandBuffer *primary)
+{
+ // Add VkCmdSetEvent here to track the completion of this renderPass.
+ for (ImageLayout layout : mRefCountedEvents.mask)
+ {
+ // This must have been garbage collected. The VkEvent handle should have been copied to
+ // VkEvents.
+ ASSERT(!mRefCountedEvents.map[layout].valid());
+ ASSERT(mRefCountedEvents.vkEvents[layout] != VK_NULL_HANDLE);
+ const ImageMemoryBarrierData &layoutData = kImageMemoryBarrierData[layout];
+ primary->setEvent(mRefCountedEvents.vkEvents[layout],
+ GetImageLayoutDstStageMask(context, layoutData));
+ }
+ mRefCountedEvents.mask.reset();
+}
+
+void RenderPassCommandBufferHelper::collectRefCountedEventsGarbage(
+ RefCountedEventsGarbageRecycler *garbageRecycler)
+{
+ // For render pass the VkCmdSetEvent works differently from OutsideRenderPassCommands.
+ // VkCmdEndRenderPass are called in the primary command buffer, and VkCmdSetEvents has to be
+ // issued after VkCmdEndRenderPass. This means VkCmdSetEvent has to be delayed. Because of this,
+ // here we simply make a local copy of the VkEvent and then add the RefCountedEvent to the
+ // garbage collector. No VkCmdSetEvent call is issued here (they will be issued at
+ // flushToPrimary time).
+ for (ImageLayout layout : mRefCountedEvents.mask)
+ {
+ ASSERT(mRefCountedEvents.map[layout].valid());
+ mRefCountedEvents.vkEvents[layout] = mRefCountedEvents.map[layout].getEvent().getHandle();
+ mRefCountedEventCollector.emplace_back(std::move(mRefCountedEvents.map[layout]));
+ }
+
+ if (!mRefCountedEventCollector.empty())
+ {
+ garbageRecycler->collectGarbage(mQueueSerial, std::move(mRefCountedEventCollector));
+ }
+}
+
angle::Result RenderPassCommandBufferHelper::beginRenderPass(
ContextVk *contextVk,
RenderPassFramebuffer &&framebuffer,
@@ -2954,8 +3002,8 @@ angle::Result RenderPassCommandBufferHelper::flushToPrimary(Context *context,
}
primary.endRenderPass();
- // Call VkCmdSetEvent to track the completion of this renderPass.
- flushSetEventsImpl(context, &primary);
+ // Now issue VkCmdSetEvents to primary command buffer
+ executeSetEvents(context, &primary);
// Restart the command buffer.
return reset(context, &commandsState->secondaryCommands);
@@ -5077,8 +5125,7 @@ void PipelineBarrierArray::addDiagnosticsString(std::ostringstream &out) const
// BufferHelper implementation.
BufferHelper::BufferHelper()
- : mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
- mCurrentWriteAccess(0),
+ : mCurrentWriteAccess(0),
mCurrentReadAccess(0),
mCurrentWriteStages(0),
mCurrentReadStages(0),
@@ -5105,7 +5152,7 @@ BufferHelper &BufferHelper::operator=(BufferHelper &&other)
mSuballocation = std::move(other.mSuballocation);
mBufferWithUserSize = std::move(other.mBufferWithUserSize);
- mCurrentQueueFamilyIndex = other.mCurrentQueueFamilyIndex;
+ mCurrentDeviceQueueIndex = other.mCurrentDeviceQueueIndex;
mIsReleasedToExternal = other.mIsReleasedToExternal;
mCurrentWriteAccess = other.mCurrentWriteAccess;
mCurrentReadAccess = other.mCurrentReadAccess;
@@ -5261,7 +5308,7 @@ VkResult BufferHelper::initSuballocation(Context *context,
void BufferHelper::initializeBarrierTracker(Context *context)
{
Renderer *renderer = context->getRenderer();
- mCurrentQueueFamilyIndex = renderer->getQueueFamilyIndex();
+ mCurrentDeviceQueueIndex = context->getDeviceQueueIndex();
mIsReleasedToExternal = false;
mSerial = renderer->getResourceSerialFactory().generateBufferSerial();
mCurrentWriteAccess = 0;
@@ -5479,41 +5526,44 @@ angle::Result BufferHelper::invalidate(Renderer *renderer)
return invalidate(renderer, 0, getSize());
}
-void BufferHelper::changeQueue(uint32_t newQueueFamilyIndex,
- OutsideRenderPassCommandBuffer *commandBuffer)
+void BufferHelper::changeQueueFamily(uint32_t srcQueueFamilyIndex,
+ uint32_t dstQueueFamilyIndex,
+ OutsideRenderPassCommandBuffer *commandBuffer)
{
VkBufferMemoryBarrier bufferMemoryBarrier = {};
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
bufferMemoryBarrier.srcAccessMask = 0;
bufferMemoryBarrier.dstAccessMask = 0;
- bufferMemoryBarrier.srcQueueFamilyIndex = mCurrentQueueFamilyIndex;
- bufferMemoryBarrier.dstQueueFamilyIndex = newQueueFamilyIndex;
+ bufferMemoryBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex;
+ bufferMemoryBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex;
bufferMemoryBarrier.buffer = getBuffer().getHandle();
bufferMemoryBarrier.offset = getOffset();
bufferMemoryBarrier.size = getSize();
commandBuffer->bufferBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &bufferMemoryBarrier);
-
- mCurrentQueueFamilyIndex = newQueueFamilyIndex;
}
-void BufferHelper::acquireFromExternal(uint32_t externalQueueFamilyIndex,
- uint32_t rendererQueueFamilyIndex,
+void BufferHelper::acquireFromExternal(DeviceQueueIndex externalQueueFamilyIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
OutsideRenderPassCommandBuffer *commandBuffer)
{
- mCurrentQueueFamilyIndex = externalQueueFamilyIndex;
+ changeQueueFamily(externalQueueFamilyIndex.familyIndex(), newDeviceQueueIndex.familyIndex(),
+ commandBuffer);
+ mCurrentDeviceQueueIndex = newDeviceQueueIndex;
mIsReleasedToExternal = false;
- changeQueue(rendererQueueFamilyIndex, commandBuffer);
}
-void BufferHelper::releaseToExternal(uint32_t rendererQueueFamilyIndex,
- uint32_t externalQueueFamilyIndex,
+void BufferHelper::releaseToExternal(DeviceQueueIndex externalQueueIndex,
OutsideRenderPassCommandBuffer *commandBuffer)
{
- ASSERT(mCurrentQueueFamilyIndex == rendererQueueFamilyIndex);
+ if (mCurrentDeviceQueueIndex.familyIndex() != externalQueueIndex.familyIndex())
+ {
+ changeQueueFamily(mCurrentDeviceQueueIndex.familyIndex(), externalQueueIndex.familyIndex(),
+ commandBuffer);
+ mCurrentDeviceQueueIndex = kInvalidDeviceQueueIndex;
+ }
mIsReleasedToExternal = true;
- changeQueue(externalQueueFamilyIndex, commandBuffer);
}
bool BufferHelper::isReleasedToExternal() const
@@ -5663,7 +5713,7 @@ void ImageHelper::resetCachedProperties()
mSamples = 1;
mImageSerial = kInvalidImageSerial;
mCurrentLayout = ImageLayout::Undefined;
- mCurrentQueueFamilyIndex = std::numeric_limits<uint32_t>::max();
+ mCurrentDeviceQueueIndex = kInvalidDeviceQueueIndex;
mIsReleasedToExternal = false;
mLastNonShaderReadOnlyLayout = ImageLayout::Undefined;
mCurrentShaderReadStageMask = 0;
@@ -5976,7 +6026,7 @@ angle::Result ImageHelper::initExternal(Context *context,
imageInfo.initialLayout = ConvertImageLayoutToVkImageLayout(context, initialLayout);
mCurrentLayout = initialLayout;
- mCurrentQueueFamilyIndex = std::numeric_limits<uint32_t>::max();
+ mCurrentDeviceQueueIndex = kInvalidDeviceQueueIndex;
mIsReleasedToExternal = false;
mLastNonShaderReadOnlyLayout = ImageLayout::Undefined;
mCurrentShaderReadStageMask = 0;
@@ -6140,8 +6190,8 @@ void ImageHelper::releaseImage(Renderer *renderer)
renderer->onMemoryDealloc(mMemoryAllocationType, mAllocationSize, mMemoryTypeIndex,
mVmaAllocation.getHandle());
}
- mCurrentEvent.release(renderer->getDevice());
- mLastNonShaderReadOnlyEvent.release(renderer->getDevice());
+ mCurrentEvent.release(renderer);
+ mLastNonShaderReadOnlyEvent.release(renderer);
renderer->collectGarbage(mUse, &mImage, &mDeviceMemory, &mVmaAllocation);
mViewFormats.clear();
mUse.reset();
@@ -6250,9 +6300,8 @@ angle::Result ImageHelper::initializeNonZeroMemory(Context *context,
// Queue a DMA copy.
VkSemaphore acquireNextImageSemaphore;
- barrierImpl(context, getAspectFlags(), ImageLayout::TransferDst,
- renderer->getQueueFamilyIndex(), nullptr, &commandBuffer,
- &acquireNextImageSemaphore);
+ barrierImpl(context, getAspectFlags(), ImageLayout::TransferDst, context->getDeviceQueueIndex(),
+ nullptr, &commandBuffer, &acquireNextImageSemaphore);
// SwapChain image should not come here
ASSERT(acquireNextImageSemaphore == VK_NULL_HANDLE);
@@ -6379,7 +6428,7 @@ VkResult ImageHelper::initMemory(Context *context,
&mAllocationSize));
}
- mCurrentQueueFamilyIndex = renderer->getQueueFamilyIndex();
+ mCurrentDeviceQueueIndex = context->getDeviceQueueIndex();
mIsReleasedToExternal = false;
*sizeOut = mAllocationSize;
@@ -6424,7 +6473,7 @@ angle::Result ImageHelper::initExternalMemory(Context *context,
const VkMemoryRequirements &memoryRequirements,
uint32_t extraAllocationInfoCount,
const void **extraAllocationInfo,
- uint32_t currentQueueFamilyIndex,
+ DeviceQueueIndex currentDeviceQueueIndex,
VkMemoryPropertyFlags flags)
{
// Vulkan allows up to 4 memory planes.
@@ -6455,7 +6504,7 @@ angle::Result ImageHelper::initExternalMemory(Context *context,
extraAllocationInfo[memoryPlane], bindImagePlaneMemoryInfoPtr,
&mImage, &mMemoryTypeIndex, &mDeviceMemory));
}
- mCurrentQueueFamilyIndex = currentQueueFamilyIndex;
+ mCurrentDeviceQueueIndex = currentDeviceQueueIndex;
mIsReleasedToExternal = false;
return angle::Result::Continue;
@@ -6621,8 +6670,8 @@ void ImageHelper::destroy(Renderer *renderer)
mVmaAllocation.getHandle());
}
- mCurrentEvent.release(device);
- mLastNonShaderReadOnlyEvent.release(device);
+ mCurrentEvent.release(renderer);
+ mLastNonShaderReadOnlyEvent.release(renderer);
mImage.destroy(device);
mDeviceMemory.destroy(device);
mVmaAllocation.destroy(renderer->getAllocator());
@@ -6658,7 +6707,7 @@ void ImageHelper::init2DWeakReference(Context *context,
mUsage = usage;
mSamples = std::max(samples, 1);
mImageSerial = context->getRenderer()->getResourceSerialFactory().generateImageSerial();
- mCurrentQueueFamilyIndex = context->getRenderer()->getQueueFamilyIndex();
+ mCurrentDeviceQueueIndex = context->getDeviceQueueIndex();
mIsReleasedToExternal = false;
mCurrentLayout = ImageLayout::Undefined;
mLayerCount = 1;
@@ -6987,21 +7036,21 @@ bool ImageHelper::isWriteBarrierNecessary(ImageLayout newLayout,
void ImageHelper::changeLayoutAndQueue(Context *context,
VkImageAspectFlags aspectMask,
ImageLayout newLayout,
- uint32_t newQueueFamilyIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
OutsideRenderPassCommandBuffer *commandBuffer)
{
- ASSERT(isQueueChangeNeccesary(newQueueFamilyIndex));
+ ASSERT(isQueueFamilyChangeNeccesary(newDeviceQueueIndex));
VkSemaphore acquireNextImageSemaphore;
// barrierImpl should detect there is queue switch and fall back to pipelineBarrier properly.
- barrierImpl(context, aspectMask, newLayout, newQueueFamilyIndex, nullptr, commandBuffer,
+ barrierImpl(context, aspectMask, newLayout, newDeviceQueueIndex, nullptr, commandBuffer,
&acquireNextImageSemaphore);
// SwapChain image should not get here.
ASSERT(acquireNextImageSemaphore == VK_NULL_HANDLE);
}
void ImageHelper::acquireFromExternal(Context *context,
- uint32_t externalQueueFamilyIndex,
- uint32_t rendererQueueFamilyIndex,
+ DeviceQueueIndex externalQueueIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
ImageLayout currentLayout,
OutsideRenderPassCommandBuffer *commandBuffer)
{
@@ -7009,17 +7058,17 @@ void ImageHelper::acquireFromExternal(Context *context,
// queue. If this is not the case, it's an application bug, so ASSERT might
// eventually need to change to a warning.
ASSERT(mCurrentLayout == ImageLayout::ExternalPreInitialized ||
- mCurrentQueueFamilyIndex == externalQueueFamilyIndex);
+ mCurrentDeviceQueueIndex.familyIndex() == externalQueueIndex.familyIndex());
mCurrentLayout = currentLayout;
- mCurrentQueueFamilyIndex = externalQueueFamilyIndex;
+ mCurrentDeviceQueueIndex = externalQueueIndex;
mIsReleasedToExternal = false;
// Only change the layout and queue if the layout is anything by Undefined. If it is undefined,
// leave it to transition out as the image is used later.
if (currentLayout != ImageLayout::Undefined)
{
- changeLayoutAndQueue(context, getAspectFlags(), mCurrentLayout, rendererQueueFamilyIndex,
+ changeLayoutAndQueue(context, getAspectFlags(), mCurrentLayout, newDeviceQueueIndex,
commandBuffer);
}
@@ -7036,8 +7085,7 @@ void ImageHelper::acquireFromExternal(Context *context,
}
void ImageHelper::releaseToExternal(Context *context,
- uint32_t rendererQueueFamilyIndex,
- uint32_t externalQueueFamilyIndex,
+ DeviceQueueIndex externalQueueIndex,
ImageLayout desiredLayout,
OutsideRenderPassCommandBuffer *commandBuffer)
{
@@ -7045,9 +7093,10 @@ void ImageHelper::releaseToExternal(Context *context,
// A layout change is unnecessary if the image that was previously acquired was never used by
// GL!
- if (mCurrentQueueFamilyIndex != externalQueueFamilyIndex || mCurrentLayout != desiredLayout)
+ if (mCurrentDeviceQueueIndex.familyIndex() != externalQueueIndex.familyIndex() ||
+ mCurrentLayout != desiredLayout)
{
- changeLayoutAndQueue(context, getAspectFlags(), desiredLayout, externalQueueFamilyIndex,
+ changeLayoutAndQueue(context, getAspectFlags(), desiredLayout, externalQueueIndex,
commandBuffer);
}
@@ -7076,6 +7125,9 @@ ANGLE_INLINE void ImageHelper::initImageMemoryBarrierStruct(
uint32_t newQueueFamilyIndex,
VkImageMemoryBarrier *imageMemoryBarrier) const
{
+ ASSERT(mCurrentDeviceQueueIndex.familyIndex() != QueueFamily::kInvalidIndex);
+ ASSERT(newQueueFamilyIndex != QueueFamily::kInvalidIndex);
+
const ImageMemoryBarrierData &transitionFrom = kImageMemoryBarrierData[mCurrentLayout];
const ImageMemoryBarrierData &transitionTo = kImageMemoryBarrierData[newLayout];
@@ -7084,7 +7136,7 @@ ANGLE_INLINE void ImageHelper::initImageMemoryBarrierStruct(
imageMemoryBarrier->dstAccessMask = transitionTo.dstAccessMask;
imageMemoryBarrier->oldLayout = ConvertImageLayoutToVkImageLayout(context, mCurrentLayout);
imageMemoryBarrier->newLayout = ConvertImageLayoutToVkImageLayout(context, newLayout);
- imageMemoryBarrier->srcQueueFamilyIndex = mCurrentQueueFamilyIndex;
+ imageMemoryBarrier->srcQueueFamilyIndex = mCurrentDeviceQueueIndex.familyIndex();
imageMemoryBarrier->dstQueueFamilyIndex = newQueueFamilyIndex;
imageMemoryBarrier->image = mImage.getHandle();
@@ -7101,7 +7153,7 @@ template <typename CommandBufferT>
void ImageHelper::barrierImpl(Context *context,
VkImageAspectFlags aspectMask,
ImageLayout newLayout,
- uint32_t newQueueFamilyIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
RefCountedEventCollector *eventCollector,
CommandBufferT *commandBuffer,
VkSemaphore *acquireNextImageSemaphoreOut)
@@ -7117,7 +7169,7 @@ void ImageHelper::barrierImpl(Context *context,
{
// For now we always use pipelineBarrier for singlebuffer mode. We could use event here in
// future.
- mCurrentEvent.release(context->getDevice());
+ mCurrentEvent.release(context);
const ImageMemoryBarrierData &transition = kImageMemoryBarrierData[mCurrentLayout];
VkMemoryBarrier memoryBarrier = {};
@@ -7137,7 +7189,7 @@ void ImageHelper::barrierImpl(Context *context,
const ImageMemoryBarrierData &transitionTo = kImageMemoryBarrierData[newLayout];
VkImageMemoryBarrier imageMemoryBarrier = {};
- initImageMemoryBarrierStruct(context, aspectMask, newLayout, newQueueFamilyIndex,
+ initImageMemoryBarrierStruct(context, aspectMask, newLayout, newDeviceQueueIndex.familyIndex(),
&imageMemoryBarrier);
VkPipelineStageFlags dstStageMask = GetImageLayoutDstStageMask(context, transitionTo);
@@ -7147,7 +7199,7 @@ void ImageHelper::barrierImpl(Context *context,
// element of pBufferMemoryBarriers or pImageMemoryBarriers must be equal
// (VUID-vkCmdWaitEvents-srcQueueFamilyIndex-02803).
BarrierType barrierType =
- mCurrentEvent.valid() && mCurrentQueueFamilyIndex == newQueueFamilyIndex
+ mCurrentEvent.valid() && mCurrentDeviceQueueIndex == newDeviceQueueIndex
? BarrierType::Event
: BarrierType::Pipeline;
@@ -7174,11 +7226,11 @@ void ImageHelper::barrierImpl(Context *context,
}
commandBuffer->imageBarrier(srcStageMask, dstStageMask, imageMemoryBarrier);
// We use pipelineBarrier here, no needs to wait for events any more.
- mCurrentEvent.release(context->getDevice());
+ mCurrentEvent.release(context);
}
mCurrentLayout = newLayout;
- mCurrentQueueFamilyIndex = newQueueFamilyIndex;
+ mCurrentDeviceQueueIndex = newDeviceQueueIndex;
resetSubresourcesWrittenSinceBarrier();
// We must release the event so that new event will be created and added. If we did not add new
@@ -7192,7 +7244,7 @@ template void ImageHelper::barrierImpl<priv::CommandBuffer>(
Context *context,
VkImageAspectFlags aspectMask,
ImageLayout newLayout,
- uint32_t newQueueFamilyIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
RefCountedEventCollector *eventCollector,
priv::CommandBuffer *commandBuffer,
VkSemaphore *acquireNextImageSemaphoreOut);
@@ -7238,7 +7290,7 @@ void ImageHelper::recordWriteBarrier(Context *context,
{
ASSERT(!mCurrentEvent.valid() || !commands->hasSetEventPendingFlush(mCurrentEvent));
VkSemaphore acquireNextImageSemaphore;
- barrierImpl(context, aspectMask, newLayout, context->getRenderer()->getQueueFamilyIndex(),
+ barrierImpl(context, aspectMask, newLayout, context->getDeviceQueueIndex(),
commands->getRefCountedEventCollector(), &commands->getCommandBuffer(),
&acquireNextImageSemaphore);
@@ -7267,7 +7319,7 @@ void ImageHelper::recordReadSubresourceBarrier(Context *context,
{
ASSERT(!mCurrentEvent.valid() || !commands->hasSetEventPendingFlush(mCurrentEvent));
VkSemaphore acquireNextImageSemaphore;
- barrierImpl(context, aspectMask, newLayout, context->getRenderer()->getQueueFamilyIndex(),
+ barrierImpl(context, aspectMask, newLayout, context->getDeviceQueueIndex(),
commands->getRefCountedEventCollector(), &commands->getCommandBuffer(),
&acquireNextImageSemaphore);
@@ -7293,7 +7345,7 @@ void ImageHelper::recordReadBarrier(Context *context,
ASSERT(!mCurrentEvent.valid() || !commands->hasSetEventPendingFlush(mCurrentEvent));
VkSemaphore acquireNextImageSemaphore;
- barrierImpl(context, aspectMask, newLayout, context->getRenderer()->getQueueFamilyIndex(),
+ barrierImpl(context, aspectMask, newLayout, context->getDeviceQueueIndex(),
commands->getRefCountedEventCollector(), &commands->getCommandBuffer(),
&acquireNextImageSemaphore);
@@ -7322,7 +7374,13 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
ASSERT(context->getRenderer()->getFeatures().useVkEventForImageBarrier.enabled ||
!mCurrentEvent.valid());
- if (!mCurrentEvent.valid())
+ if (mCurrentDeviceQueueIndex != context->getDeviceQueueIndex())
+ {
+ // Fallback to pipelineBarrier if the VkQueue has changed.
+ barrierType = BarrierType::Pipeline;
+ mCurrentDeviceQueueIndex = context->getDeviceQueueIndex();
+ }
+ else if (!mCurrentEvent.valid())
{
// Fallback to pipelineBarrier if there is no event tracking image.
barrierType = BarrierType::Pipeline;
@@ -7368,7 +7426,7 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
// Release it. No need to garbage collect since we did not use the event here. ALl
// previous use of event should garbage tracked already.
- mCurrentEvent.release(context->getDevice());
+ mCurrentEvent.release(context);
}
mBarrierQueueSerial = queueSerial;
}
@@ -7394,6 +7452,8 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
return;
}
+ ASSERT(!mLastNonShaderReadOnlyEvent.valid() ||
+ mLastNonShaderReadOnlyEvent.getImageLayout() == mLastNonShaderReadOnlyLayout);
if (!mLastNonShaderReadOnlyEvent.valid())
{
barrierType = BarrierType::Pipeline;
@@ -7401,8 +7461,11 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
if (barrierType == BarrierType::Event)
{
- eventBarriers->addMemoryEvent(context, mLastNonShaderReadOnlyEvent, dstStageMask,
- transitionTo.dstAccessMask);
+ // If we already inserted a barrier in the same renderPass, we has to add
+ // the new stage mask to the existing VkCmdWaitEvent call, otherwise VVL will
+ // complain.
+ eventBarriers->addAdditionalStageAccess(mLastNonShaderReadOnlyEvent, dstStageMask,
+ transitionTo.dstAccessMask);
eventCollector->emplace_back(mLastNonShaderReadOnlyEvent);
}
else
@@ -7424,21 +7487,12 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
{
eventCollector->emplace_back(std::move(mCurrentEvent));
}
-
- const ImageMemoryBarrierData &layoutData =
- kImageMemoryBarrierData[mLastNonShaderReadOnlyLayout];
- pipelineBarriers->mergeMemoryBarrier(
- transitionTo.barrierIndex, GetImageLayoutSrcStageMask(context, layoutData),
- dstStageMask, layoutData.srcAccessMask, transitionTo.dstAccessMask);
- mBarrierQueueSerial = queueSerial;
- // Accumulate new read stage.
- mCurrentShaderReadStageMask |= dstStageMask;
}
else
{
VkImageMemoryBarrier imageMemoryBarrier = {};
initImageMemoryBarrierStruct(context, aspectMask, newLayout,
- context->getRenderer()->getQueueFamilyIndex(),
+ context->getDeviceQueueIndex().familyIndex(),
&imageMemoryBarrier);
if (transitionFrom.layout == transitionTo.layout &&
@@ -7483,7 +7537,7 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
mLastNonShaderReadOnlyLayout = ImageLayout::Undefined;
if (mLastNonShaderReadOnlyEvent.valid())
{
- mLastNonShaderReadOnlyEvent.release(context->getDevice());
+ mLastNonShaderReadOnlyEvent.release(context);
}
}
@@ -7492,7 +7546,7 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
const bool isShaderReadOnly = IsShaderReadOnlyLayout(transitionTo);
if (isShaderReadOnly)
{
- mLastNonShaderReadOnlyEvent.release(context->getDevice());
+ mLastNonShaderReadOnlyEvent.release(context);
mLastNonShaderReadOnlyLayout = mCurrentLayout;
mCurrentShaderReadStageMask = dstStageMask;
}
@@ -7511,7 +7565,7 @@ void ImageHelper::updateLayoutAndBarrier(Context *context,
{
pipelineBarriers->mergeImageBarrier(transitionTo.barrierIndex, srcStageMask,
dstStageMask, imageMemoryBarrier);
- mCurrentEvent.release(context->getDevice());
+ mCurrentEvent.release(context);
}
mBarrierQueueSerial = queueSerial;
@@ -7531,17 +7585,22 @@ void ImageHelper::setCurrentRefCountedEvent(Context *context, ImageLayoutEventMa
{
ASSERT(context->getRenderer()->getFeatures().useVkEventForImageBarrier.enabled);
+ // If there is already an event, release it first.
+ mCurrentEvent.release(context);
+
// 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);
+ if (!layoutEventMaps.map[mCurrentLayout].init(context, mCurrentLayout))
+ {
+ // If VkEvent creation fail, we fallback to pipelineBarrier
+ return;
+ }
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];
@@ -9279,7 +9338,7 @@ void ImageHelper::stageSelfAsSubresourceUpdates(
prevImage->get().mIntendedFormatID = mIntendedFormatID;
prevImage->get().mActualFormatID = mActualFormatID;
prevImage->get().mCurrentLayout = mCurrentLayout;
- prevImage->get().mCurrentQueueFamilyIndex = mCurrentQueueFamilyIndex;
+ prevImage->get().mCurrentDeviceQueueIndex = mCurrentDeviceQueueIndex;
prevImage->get().mLastNonShaderReadOnlyLayout = mLastNonShaderReadOnlyLayout;
prevImage->get().mCurrentShaderReadStageMask = mCurrentShaderReadStageMask;
prevImage->get().mLevelCount = levelCount;
@@ -9291,7 +9350,7 @@ void ImageHelper::stageSelfAsSubresourceUpdates(
// Reset information for current (invalid) image.
mCurrentLayout = ImageLayout::Undefined;
- mCurrentQueueFamilyIndex = std::numeric_limits<uint32_t>::max();
+ mCurrentDeviceQueueIndex = kInvalidDeviceQueueIndex;
mIsReleasedToExternal = false;
mLastNonShaderReadOnlyLayout = ImageLayout::Undefined;
mCurrentShaderReadStageMask = 0;
@@ -10206,7 +10265,7 @@ angle::Result ImageHelper::copySurfaceImageToBuffer(DisplayVk *displayVk,
// We may have a valid event here but we do not have a collector to collect it. Release the
// event here to force pipelineBarrier.
- mCurrentEvent.release(displayVk->getDevice());
+ mCurrentEvent.release(displayVk->getRenderer());
PrimaryCommandBuffer primaryCommandBuffer;
ANGLE_TRY(renderer->getCommandBufferOneOff(displayVk, ProtectionType::Unprotected,
@@ -10214,7 +10273,7 @@ angle::Result ImageHelper::copySurfaceImageToBuffer(DisplayVk *displayVk,
VkSemaphore acquireNextImageSemaphore;
barrierImpl(displayVk, getAspectFlags(), ImageLayout::TransferSrc,
- renderer->getQueueFamilyIndex(), nullptr, &primaryCommandBuffer,
+ displayVk->getDeviceQueueIndex(), nullptr, &primaryCommandBuffer,
&acquireNextImageSemaphore);
primaryCommandBuffer.copyImageToBuffer(mImage, getCurrentLayout(displayVk),
bufferHelper->getBuffer().getHandle(), 1, &region);
@@ -10258,7 +10317,7 @@ angle::Result ImageHelper::copyBufferToSurfaceImage(DisplayVk *displayVk,
// We may have a valid event here but we do not have a collector to collect it. Release the
// event here to force pipelineBarrier.
- mCurrentEvent.release(displayVk->getDevice());
+ mCurrentEvent.release(displayVk->getRenderer());
PrimaryCommandBuffer commandBuffer;
ANGLE_TRY(
@@ -10266,7 +10325,7 @@ angle::Result ImageHelper::copyBufferToSurfaceImage(DisplayVk *displayVk,
VkSemaphore acquireNextImageSemaphore;
barrierImpl(displayVk, getAspectFlags(), ImageLayout::TransferDst,
- renderer->getQueueFamilyIndex(), nullptr, &commandBuffer,
+ displayVk->getDeviceQueueIndex(), nullptr, &commandBuffer,
&acquireNextImageSemaphore);
commandBuffer.copyBufferToImage(bufferHelper->getBuffer().getHandle(), mImage,
getCurrentLayout(displayVk), 1, &region);
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index e434f12f63..1ce7c93821 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -175,6 +175,8 @@ struct ImageLayoutEventMaps
// loop of map
angle::PackedEnumMap<ImageLayout, RefCountedEvent> map;
angle::PackedEnumBitSet<ImageLayout, uint64_t> mask;
+ // Only used by RenderPassCommandBufferHelper
+ angle::PackedEnumMap<ImageLayout, VkEvent> vkEvents;
};
// A dynamic buffer is conceptually an infinitely long buffer. Each time you write to the buffer,
@@ -971,16 +973,17 @@ class BufferHelper : public ReadWriteResource
angle::Result invalidate(Renderer *renderer);
angle::Result invalidate(Renderer *renderer, VkDeviceSize offset, VkDeviceSize size);
- void changeQueue(uint32_t newQueueFamilyIndex, OutsideRenderPassCommandBuffer *commandBuffer);
+ void changeQueueFamily(uint32_t srcQueueFamilyIndex,
+ uint32_t dstQueueFamilyIndex,
+ OutsideRenderPassCommandBuffer *commandBuffer);
// Performs an ownership transfer from an external instance or API.
- void acquireFromExternal(uint32_t externalQueueFamilyIndex,
- uint32_t rendererQueueFamilyIndex,
+ void acquireFromExternal(DeviceQueueIndex externalQueueIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
OutsideRenderPassCommandBuffer *commandBuffer);
// Performs an ownership transfer to an external instance or API.
- void releaseToExternal(uint32_t rendererQueueFamilyIndex,
- uint32_t externalQueueFamilyIndex,
+ void releaseToExternal(DeviceQueueIndex externalQueueIndex,
OutsideRenderPassCommandBuffer *commandBuffer);
// Returns true if the image is owned by an external API or instance.
@@ -1041,7 +1044,7 @@ class BufferHelper : public ReadWriteResource
Buffer mBufferWithUserSize;
// For memory barriers.
- uint32_t mCurrentQueueFamilyIndex;
+ DeviceQueueIndex mCurrentDeviceQueueIndex;
VkFlags mCurrentWriteAccess;
VkFlags mCurrentReadAccess;
VkPipelineStageFlags mCurrentWriteStages;
@@ -1349,8 +1352,6 @@ class CommandBufferHelperCommon : angle::NonCopyable
template <typename CommandBufferT>
void flushSetEventsImpl(Context *context, CommandBufferT *commandBuffer);
- RefCountedEventCollector *getRefCountedEventCollector() { return &mRefCountedEventCollector; }
-
const QueueSerial &getQueueSerial() const { return mQueueSerial; }
void setAcquireNextImageSemaphore(VkSemaphore semaphore)
@@ -1523,8 +1524,13 @@ class OutsideRenderPassCommandBufferHelper final : public CommandBufferHelperCom
void trackImagesWithEvent(Context *context, ImageHelper *srcImage, ImageHelper *dstImage);
void trackImagesWithEvent(Context *context, const ImageHelperPtr *images, size_t count);
- // Issues VkCmdSetEvent calls.
+ // Issues SetEvent calls to the command buffer.
void flushSetEvents(Context *context) { flushSetEventsImpl(context, &mCommandBuffer); }
+ // 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.
+ void collectRefCountedEventsGarbage(RefCountedEventsGarbageRecycler *garbageRecycler);
+
+ RefCountedEventCollector *getRefCountedEventCollector() { return &mRefCountedEventCollector; }
angle::Result flushToPrimary(Context *context, CommandsState *commandsState);
@@ -1874,6 +1880,8 @@ class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon
void updateDepthStencilReadOnlyMode(RenderPassUsageFlags dsUsageFlags,
VkImageAspectFlags dsAspectFlags);
+ void collectRefCountedEventsGarbage(RefCountedEventsGarbageRecycler *garbageRecycler);
+
private:
uint32_t getSubpassCommandBufferCount() const { return mCurrentSubpassCommandBufferIndex + 1; }
@@ -1911,6 +1919,7 @@ class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon
void finalizeFragmentShadingRateImageLayout(Context *context);
void trackImagesWithEvent(Context *context, const ImageHelperPtr *images, size_t count);
+ void executeSetEvents(Context *context, PrimaryCommandBuffer *primary);
// 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.
@@ -2092,7 +2101,7 @@ class ImageHelper final : public Resource, public angle::Subject
const VkMemoryRequirements &memoryRequirements,
uint32_t extraAllocationInfoCount,
const void **extraAllocationInfo,
- uint32_t currentQueueFamilyIndex,
+ DeviceQueueIndex currentDeviceQueueIndex,
VkMemoryPropertyFlags flags);
static constexpr VkImageUsageFlags kDefaultImageViewUsageFlags = 0;
@@ -2518,7 +2527,7 @@ class ImageHelper final : public Resource, public angle::Subject
// Since we are doing an out of order one off submission, there shouldn't be any pending
// setEvent.
ASSERT(!mCurrentEvent.valid());
- barrierImpl(context, getAspectFlags(), newLayout, mCurrentQueueFamilyIndex, nullptr,
+ barrierImpl(context, getAspectFlags(), newLayout, mCurrentDeviceQueueIndex, nullptr,
commandBuffer, acquireNextImageSemaphoreOut);
}
@@ -2540,15 +2549,15 @@ class ImageHelper final : public Resource, public angle::Subject
ImageLayout newLayout,
OutsideRenderPassCommandBufferHelper *commands);
- bool isQueueChangeNeccesary(uint32_t newQueueFamilyIndex) const
+ bool isQueueFamilyChangeNeccesary(DeviceQueueIndex newDeviceQueueIndex) const
{
- return mCurrentQueueFamilyIndex != newQueueFamilyIndex;
+ return mCurrentDeviceQueueIndex.familyIndex() != newDeviceQueueIndex.familyIndex();
}
void changeLayoutAndQueue(Context *context,
VkImageAspectFlags aspectMask,
ImageLayout newLayout,
- uint32_t newQueueFamilyIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
OutsideRenderPassCommandBuffer *commandBuffer);
// Returns true if barrier has been generated
@@ -2564,15 +2573,14 @@ class ImageHelper final : public Resource, public angle::Subject
// Performs an ownership transfer from an external instance or API.
void acquireFromExternal(Context *context,
- uint32_t externalQueueFamilyIndex,
- uint32_t rendererQueueFamilyIndex,
+ DeviceQueueIndex externalQueueIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
ImageLayout currentLayout,
OutsideRenderPassCommandBuffer *commandBuffer);
// Performs an ownership transfer to an external instance or API.
void releaseToExternal(Context *context,
- uint32_t rendererQueueFamilyIndex,
- uint32_t externalQueueFamilyIndex,
+ DeviceQueueIndex externalQueueIndex,
ImageLayout desiredLayout,
OutsideRenderPassCommandBuffer *commandBuffer);
@@ -2854,7 +2862,7 @@ class ImageHelper final : public Resource, public angle::Subject
void barrierImpl(Context *context,
VkImageAspectFlags aspectMask,
ImageLayout newLayout,
- uint32_t newQueueFamilyIndex,
+ DeviceQueueIndex newDeviceQueueIndex,
RefCountedEventCollector *eventCollector,
CommandBufferT *commandBuffer,
VkSemaphore *acquireNextImageSemaphoreOut);
@@ -3078,7 +3086,7 @@ class ImageHelper final : public Resource, public angle::Subject
// Current state.
ImageLayout mCurrentLayout;
- uint32_t mCurrentQueueFamilyIndex;
+ DeviceQueueIndex mCurrentDeviceQueueIndex;
// For optimizing transition between different shader readonly layouts
ImageLayout mLastNonShaderReadOnlyLayout;
VkPipelineStageFlags mCurrentShaderReadStageMask;
diff --git a/src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp
index 32897a5a75..efd95edb85 100644
--- a/src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.cpp
@@ -15,58 +15,189 @@ namespace rx
{
namespace vk
{
-void RefCountedEvent::init(Context *context, ImageLayout layout)
+bool 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;
- // Use device only for performance reasons.
- createInfo.flags = context->getFeatures().supportsSynchronization2.enabled
- ? VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR
- : 0;
- mHandle->get().event.init(context->getDevice(), createInfo);
+ // First try with recycler. We must issue VkCmdResetEvent before VkCmdSetEvent
+ if (context->getRefCountedEventsGarbageRecycler()->fetch(this) ||
+ context->getRenderer()->getRefCountedEventRecycler()->fetch(this))
+ {
+ mHandle->get().needsReset = true;
+ }
+ else
+ {
+ // If failed to fetch from recycler, then create a new event.
+ mHandle = new RefCounted<EventAndLayout>;
+ VkEventCreateInfo createInfo = {};
+ createInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+ // Use device only for performance reasons.
+ createInfo.flags = context->getFeatures().supportsSynchronization2.enabled
+ ? VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR
+ : 0;
+ VkResult result = mHandle->get().event.init(context->getDevice(), createInfo);
+ if (result != VK_SUCCESS)
+ {
+ WARN() << "event.init failed. Clean up garbage and retry again";
+ // Proactively clean up garbage and retry
+ context->getRefCountedEventsGarbageRecycler()->cleanup(context->getRenderer());
+ result = mHandle->get().event.init(context->getDevice(), createInfo);
+ if (result != VK_SUCCESS)
+ {
+ // Drivers usually can allocate huge amount of VkEvents, and we should never use
+ // that many VkEvents under normal situation. If we failed to allocate, there is a
+ // high chance that we may have a leak somewhere. This macro should help us catch
+ // such potential bugs in the bots if that happens.
+ UNREACHABLE();
+ // If still fail to create, we just return. An invalid event will trigger
+ // pipelineBarrier code path
+ return false;
+ }
+ }
+ mHandle->get().needsReset = false;
+ }
+
mHandle->addRef();
mHandle->get().imageLayout = layout;
+ return true;
+}
+
+void RefCountedEvent::release(Context *context)
+{
+ if (mHandle != nullptr)
+ {
+ releaseImpl(context->getRenderer(), context->getRefCountedEventsGarbageRecycler());
+ }
+}
+
+void RefCountedEvent::release(Renderer *renderer)
+{
+ if (mHandle != nullptr)
+ {
+ releaseImpl(renderer, renderer->getRefCountedEventRecycler());
+ }
+}
+
+template <typename RecyclerT>
+void RefCountedEvent::releaseImpl(Renderer *renderer, RecyclerT *recycler)
+{
+ ASSERT(mHandle != nullptr);
+ // This should never called from async submission thread since the refcount is not atomic. It is
+ // expected only called under context share lock.
+ ASSERT(std::this_thread::get_id() != renderer->getCommandProcessorThreadId());
+
+ const bool isLastReference = mHandle->getAndReleaseRef() == 1;
+ if (isLastReference)
+ {
+ // When async submission is enabled, recycler will be null when release call comes from
+ // CommandProcessor. But in that case it will not be the last reference since garbage
+ // collector should have one reference count and will never release that reference count
+ // until GPU finished.
+ ASSERT(recycler != nullptr);
+ // TODO: Disable recycler and immediately destroy the event for now until I figure out
+ // SYNC-vkCmdSetEvent-missingbarrier-reset.
+ destroy(renderer->getDevice());
+ ASSERT(mHandle == nullptr);
+ }
+ else
+ {
+ mHandle = nullptr;
+ }
+}
+
+void RefCountedEvent::destroy(VkDevice device)
+{
+ ASSERT(mHandle != nullptr);
+ ASSERT(!mHandle->isReferenced());
+ mHandle->get().event.destroy(device);
+ SafeDelete(mHandle);
}
// RefCountedEventsGarbage implementation.
-bool RefCountedEventsGarbage::destroyIfComplete(Renderer *renderer)
+bool RefCountedEventsGarbage::releaseIfComplete(Renderer *renderer,
+ RefCountedEventsGarbageRecycler *recycler)
{
- if (renderer->hasResourceUseFinished(mLifetime))
+ if (!renderer->hasQueueSerialFinished(mQueueSerial))
{
- for (RefCountedEvent &event : mRefCountedEvents)
- {
- ASSERT(event.valid());
- event.release(renderer->getDevice());
- ASSERT(!event.valid());
- }
- mRefCountedEvents.clear();
- return true;
+ return false;
+ }
+
+ while (!mRefCountedEvents.empty())
+ {
+ ASSERT(mRefCountedEvents.back().valid());
+ mRefCountedEvents.back().releaseImpl(renderer, recycler);
+ ASSERT(!mRefCountedEvents.back().valid());
+ mRefCountedEvents.pop_back();
+ }
+ return true;
+}
+
+void RefCountedEventsGarbage::destroy(Renderer *renderer)
+{
+ ASSERT(renderer->hasQueueSerialFinished(mQueueSerial));
+ while (!mRefCountedEvents.empty())
+ {
+ ASSERT(mRefCountedEvents.back().valid());
+ mRefCountedEvents.back().release(renderer);
+ mRefCountedEvents.pop_back();
}
- return false;
}
-bool RefCountedEventsGarbage::hasResourceUseSubmitted(Renderer *renderer) const
+// RefCountedEventsGarbageRecycler implementation.
+RefCountedEventsGarbageRecycler::~RefCountedEventsGarbageRecycler()
{
- return renderer->hasResourceUseSubmitted(mLifetime);
+ ASSERT(mFreeStack.empty());
+ ASSERT(mGarbageQueue.empty());
}
-// EventBarrier implementation.
-bool EventBarrier::hasEvent(const VkEvent &event) const
+void RefCountedEventsGarbageRecycler::destroy(Renderer *renderer)
{
- for (const VkEvent &existingEvent : mEvents)
+ while (!mGarbageQueue.empty())
{
- if (existingEvent == event)
+ mGarbageQueue.front().destroy(renderer);
+ mGarbageQueue.pop();
+ }
+
+ mFreeStack.destroy(renderer->getDevice());
+}
+
+void RefCountedEventsGarbageRecycler::cleanup(Renderer *renderer)
+{
+ // Destroy free stack first. The garbage clean up process will add more events to the free
+ // stack. If everything is stable between each frame, grabage should release enough events to
+ // recycler for next frame's needs.
+ mFreeStack.destroy(renderer->getDevice());
+
+ while (!mGarbageQueue.empty())
+ {
+ size_t count = mGarbageQueue.front().size();
+ bool released = mGarbageQueue.front().releaseIfComplete(renderer, this);
+ if (released)
{
- return true;
+ mGarbageCount -= count;
+ mGarbageQueue.pop();
}
+ else
+ {
+ break;
+ }
+ }
+}
+
+bool RefCountedEventsGarbageRecycler::fetch(RefCountedEvent *outObject)
+{
+ if (!mFreeStack.empty())
+ {
+ mFreeStack.fetch(outObject);
+ ASSERT(outObject->valid());
+ ASSERT(!outObject->mHandle->isReferenced());
+ return true;
}
return false;
}
+// EventBarrier implementation.
void EventBarrier::addDiagnosticsString(std::ostringstream &out) const
{
if (mMemoryBarrierSrcAccess != 0 || mMemoryBarrierDstAccess != 0)
@@ -82,50 +213,47 @@ void EventBarrier::execute(PrimaryCommandBuffer *primary)
{
return;
}
+ ASSERT(mEvent != VK_NULL_HANDLE);
+ ASSERT(mImageMemoryBarrierCount == 0 ||
+ (mImageMemoryBarrierCount == 1 && mImageMemoryBarrier.image != VK_NULL_HANDLE));
// Issue vkCmdWaitEvents call
VkMemoryBarrier memoryBarrier = {};
- uint32_t memoryBarrierCount = 0;
- if (mMemoryBarrierDstAccess != 0)
- {
- memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
- memoryBarrier.srcAccessMask = mMemoryBarrierSrcAccess;
- memoryBarrier.dstAccessMask = mMemoryBarrierDstAccess;
- memoryBarrierCount++;
- }
+ memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+ memoryBarrier.srcAccessMask = mMemoryBarrierSrcAccess;
+ memoryBarrier.dstAccessMask = mMemoryBarrierDstAccess;
- primary->waitEvents(static_cast<uint32_t>(mEvents.size()), mEvents.data(), mSrcStageMask,
- mDstStageMask, memoryBarrierCount, &memoryBarrier, 0, nullptr,
- static_cast<uint32_t>(mImageMemoryBarriers.size()),
- mImageMemoryBarriers.data());
-
- reset();
+ primary->waitEvents(1, &mEvent, mSrcStageMask, mDstStageMask, 1, &memoryBarrier, 0, nullptr,
+ mImageMemoryBarrierCount,
+ mImageMemoryBarrierCount == 0 ? nullptr : &mImageMemoryBarrier);
}
// EventBarrierArray implementation.
-void EventBarrierArray::addMemoryEvent(Context *context,
- const RefCountedEvent &waitEvent,
- VkPipelineStageFlags dstStageMask,
- VkAccessFlags dstAccess)
+void EventBarrierArray::addAdditionalStageAccess(const RefCountedEvent &waitEvent,
+ VkPipelineStageFlags dstStageMask,
+ VkAccessFlags dstAccess)
{
- ASSERT(waitEvent.valid());
-
for (EventBarrier &barrier : mBarriers)
{
- // If the event is already in the waiting list, just add the new stageMask to the
- // dstStageMask. Otherwise we will end up with two waitEvent calls that wait for the same
- // VkEvent but for different dstStage and confuses VVL.
if (barrier.hasEvent(waitEvent.getEvent().getHandle()))
{
barrier.addAdditionalStageAccess(dstStageMask, dstAccess);
return;
}
}
+ UNREACHABLE();
+}
+void EventBarrierArray::addMemoryEvent(Context *context,
+ const RefCountedEvent &waitEvent,
+ VkPipelineStageFlags dstStageMask,
+ VkAccessFlags dstAccess)
+{
+ ASSERT(waitEvent.valid());
VkAccessFlags accessMask;
VkPipelineStageFlags stageFlags = GetRefCountedEventStageMask(context, waitEvent, &accessMask);
- // Since this is used with WAW without layout change, dstStageMask should be the same as event's
- // stageMask. Otherwise you should get into addImageEvent.
+ // This should come down as WAW without layout change, dstStageMask should be the same as
+ // event's stageMask. Otherwise you should get into addImageEvent.
ASSERT(stageFlags == dstStageMask && accessMask == dstAccess);
mBarriers.emplace_back(stageFlags, dstStageMask, accessMask, dstAccess,
waitEvent.getEvent().getHandle());
@@ -138,30 +266,18 @@ void EventBarrierArray::addImageEvent(Context *context,
{
ASSERT(waitEvent.valid());
VkPipelineStageFlags srcStageFlags = GetRefCountedEventStageMask(context, waitEvent);
-
- mBarriers.emplace_back();
- EventBarrier &barrier = mBarriers.back();
- // VkCmdWaitEvent must uses the same stageMask as VkCmdSetEvent due to
- // VUID-vkCmdWaitEvents-srcStageMask-01158 requirements.
- barrier.mSrcStageMask = srcStageFlags;
- // If there is an event, we use the waitEvent to do layout change.
- barrier.mEvents.emplace_back(waitEvent.getEvent().getHandle());
- barrier.mDstStageMask = dstStageMask;
- barrier.mImageMemoryBarriers.emplace_back(imageMemoryBarrier);
+ mBarriers.emplace_back(srcStageFlags, dstStageMask, waitEvent.getEvent().getHandle(),
+ imageMemoryBarrier);
}
void EventBarrierArray::execute(Renderer *renderer, PrimaryCommandBuffer *primary)
{
- if (mBarriers.empty())
- {
- return;
- }
-
- for (EventBarrier &barrier : mBarriers)
+ while (!mBarriers.empty())
{
- barrier.execute(primary);
+ mBarriers.back().execute(primary);
+ mBarriers.pop_back();
}
- mBarriers.clear();
+ reset();
}
void EventBarrierArray::addDiagnosticsString(std::ostringstream &out) const
diff --git a/src/libANGLE/renderer/vulkan/vk_ref_counted_event.h b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.h
index 19df7ad63f..6ce1e65d2e 100644
--- a/src/libANGLE/renderer/vulkan/vk_ref_counted_event.h
+++ b/src/libANGLE/renderer/vulkan/vk_ref_counted_event.h
@@ -15,6 +15,7 @@
#include <queue>
#include "common/PackedEnums.h"
+#include "common/SimpleMutex.h"
#include "common/debug.h"
#include "libANGLE/renderer/serial_utils.h"
#include "libANGLE/renderer/vulkan/vk_resource.h"
@@ -45,6 +46,7 @@ struct EventAndLayout
bool valid() const { return event.valid(); }
Event event;
ImageLayout imageLayout;
+ bool needsReset;
};
// The VkCmdSetEvent is called after VkCmdEndRenderPass and all images that used at the given
@@ -94,26 +96,21 @@ class RefCountedEvent final
// 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);
+ // Create VkEvent and associated it with given layout. Returns true if success and false if
+ // failed.
+ bool 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 (mHandle != nullptr)
- {
- const bool isLastReference = mHandle->getAndReleaseRef() == 1;
- if (isLastReference)
- {
- destroy(device);
- }
- else
- {
- mHandle = nullptr;
- }
- }
- }
+ // Release one reference count to the underline Event object and destroy or recycle the handle
+ // to renderer's recycler if this is the very last reference.
+ void release(Renderer *renderer);
+
+ // Release one reference count to the underline Event object and destroy or recycle the handle
+ // to the context share group's recycler if this is the very last reference.
+ void release(Context *context);
+
+ // Destroy the event and mHandle. Caller must ensure there is no outstanding reference to the
+ // mHandle.
+ void destroy(VkDevice device);
bool valid() const { return mHandle != nullptr; }
@@ -131,18 +128,24 @@ class RefCountedEvent final
return mHandle->get().imageLayout;
}
- private:
- void destroy(VkDevice device)
+ bool needsReset() const
{
- ASSERT(mHandle != nullptr);
- ASSERT(!mHandle->isReferenced());
- mHandle->get().event.destroy(device);
- SafeDelete(mHandle);
+ ASSERT(valid());
+ return mHandle->get().needsReset;
}
- AtomicRefCounted<EventAndLayout> *mHandle;
+ private:
+ // Release one reference count to the underline Event object and destroy or recycle the handle
+ // to the provided recycler if this is the very last reference.
+ friend class RefCountedEventRecycler;
+ friend class RefCountedEventsGarbage;
+ friend class RefCountedEventsGarbageRecycler;
+ template <typename RecyclerT>
+ void releaseImpl(Renderer *renderer, RecyclerT *recycler);
+
+ RefCounted<EventAndLayout> *mHandle;
};
-using RefCountedEventCollector = std::vector<RefCountedEvent>;
+using RefCountedEventCollector = std::deque<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
@@ -159,27 +162,30 @@ class RefCountedEventsGarbage final
RefCountedEventsGarbage(const QueueSerial &queueSerial,
RefCountedEventCollector &&refCountedEvents)
- : mLifetime(queueSerial), mRefCountedEvents(std::move(refCountedEvents))
+ : mQueueSerial(queueSerial), mRefCountedEvents(std::move(refCountedEvents))
{
ASSERT(refCountedEvents.empty());
ASSERT(!mRefCountedEvents.empty());
}
RefCountedEventsGarbage(RefCountedEventsGarbage &&other)
- : mLifetime(other.mLifetime), mRefCountedEvents(std::move(other.mRefCountedEvents))
+ : mQueueSerial(other.mQueueSerial), mRefCountedEvents(std::move(other.mRefCountedEvents))
{}
RefCountedEventsGarbage &operator=(RefCountedEventsGarbage &&other)
{
ASSERT(mRefCountedEvents.empty());
- mLifetime = other.mLifetime;
+ mQueueSerial = other.mQueueSerial;
mRefCountedEvents = std::move(other.mRefCountedEvents);
return *this;
}
- bool destroyIfComplete(Renderer *renderer);
- bool hasResourceUseSubmitted(Renderer *renderer) const;
- VkDeviceSize getSize() const { return mRefCountedEvents.size(); }
+ void destroy(Renderer *renderer);
+
+ // Check the queue serial and release the events to context if GPU finished. Note that release
+ // to context may end up recycle the object instead of destroy. Returns true if it is GPU
+ // finished.
+ bool releaseIfComplete(Renderer *renderer, RefCountedEventsGarbageRecycler *recycler);
// Move event to the garbage list
void add(RefCountedEvent &&event) { mRefCountedEvents.emplace_back(std::move(event)); }
@@ -187,12 +193,8 @@ class RefCountedEventsGarbage final
// Move the vector of events to the garbage list
void add(RefCountedEventCollector &&events)
{
- mRefCountedEvents.reserve(mRefCountedEvents.size() + events.size());
- for (RefCountedEvent &event : events)
- {
- mRefCountedEvents.emplace_back(std::move(event));
- }
- events.clear();
+ mRefCountedEvents.insert(mRefCountedEvents.end(), events.begin(), events.end());
+ ASSERT(events.empty());
}
// Make a copy of event (which adds another refcount to the VkEvent) and add the copied event to
@@ -207,17 +209,111 @@ class RefCountedEventsGarbage final
bool empty() const { return mRefCountedEvents.empty(); }
+ size_t size() const { return mRefCountedEvents.size(); }
+
private:
- ResourceUse mLifetime;
+ friend class RefCountedEventsGarbageRecycler;
+ QueueSerial mQueueSerial;
RefCountedEventCollector mRefCountedEvents;
};
+// Thread safe event recycler, protected by its own lock.
+class RefCountedEventRecycler final
+{
+ public:
+ void recycle(RefCountedEvent &&garbageObject)
+ {
+ ASSERT(garbageObject.valid());
+ ASSERT(!garbageObject.mHandle->isReferenced());
+ std::lock_guard<angle::SimpleMutex> lock(mMutex);
+ mFreeStack.recycle(std::move(garbageObject));
+ }
+
+ void releaseOrRecycle(Renderer *renderer, RefCountedEventCollector &&eventCollector)
+ {
+ // Take lock once and then use event's releaseImpl function to directly recycle into the
+ // underlying recycling storage.
+ std::lock_guard<angle::SimpleMutex> lock(mMutex);
+ while (!eventCollector.empty())
+ {
+ eventCollector.back().releaseImpl(renderer, &mFreeStack);
+ eventCollector.pop_back();
+ }
+ }
+
+ bool fetch(RefCountedEvent *outObject)
+ {
+ std::lock_guard<angle::SimpleMutex> lock(mMutex);
+ if (mFreeStack.empty())
+ {
+ return false;
+ }
+ mFreeStack.fetch(outObject);
+ ASSERT(outObject->valid());
+ ASSERT(!outObject->mHandle->isReferenced());
+ return true;
+ }
+
+ void destroy(VkDevice device)
+ {
+ std::lock_guard<angle::SimpleMutex> lock(mMutex);
+ mFreeStack.destroy(device);
+ }
+
+ private:
+ angle::SimpleMutex mMutex;
+ Recycler<RefCountedEvent> mFreeStack;
+};
+
+// Not thread safe event garbage collection and recycler. Caller must ensure the thread safety. It
+// is intended to use by ShareGroupVk which all access should already protected by share context
+// lock.
+class RefCountedEventsGarbageRecycler final
+{
+ public:
+ RefCountedEventsGarbageRecycler() : mGarbageCount(0) {}
+ ~RefCountedEventsGarbageRecycler();
+
+ // Release all garbage and free events.
+ void destroy(Renderer *renderer);
+
+ // Walk the garbage list and move completed garbage to free list
+ void cleanup(Renderer *renderer);
+
+ void collectGarbage(const QueueSerial &queueSerial, RefCountedEventCollector &&refCountedEvents)
+ {
+ mGarbageCount += refCountedEvents.size();
+ mGarbageQueue.emplace(queueSerial, std::move(refCountedEvents));
+ }
+
+ void recycle(RefCountedEvent &&garbageObject)
+ {
+ ASSERT(garbageObject.valid());
+ ASSERT(!garbageObject.mHandle->isReferenced());
+ mFreeStack.recycle(std::move(garbageObject));
+ }
+
+ bool fetch(RefCountedEvent *outObject);
+
+ size_t getGarbageCount() const { return mGarbageCount; }
+
+ private:
+ Recycler<RefCountedEvent> mFreeStack;
+ std::queue<RefCountedEventsGarbage> mGarbageQueue;
+ size_t mGarbageCount;
+};
+
// This wraps data and API for vkCmdWaitEvent call
class EventBarrier : angle::NonCopyable
{
public:
EventBarrier()
- : mSrcStageMask(0), mDstStageMask(0), mMemoryBarrierSrcAccess(0), mMemoryBarrierDstAccess(0)
+ : mSrcStageMask(0),
+ mDstStageMask(0),
+ mMemoryBarrierSrcAccess(0),
+ mMemoryBarrierDstAccess(0),
+ mImageMemoryBarrierCount(0),
+ mEvent(VK_NULL_HANDLE)
{}
EventBarrier(VkPipelineStageFlags srcStageMask,
@@ -228,9 +324,11 @@ class EventBarrier : angle::NonCopyable
: mSrcStageMask(srcStageMask),
mDstStageMask(dstStageMask),
mMemoryBarrierSrcAccess(srcAccess),
- mMemoryBarrierDstAccess(dstAccess)
+ mMemoryBarrierDstAccess(dstAccess),
+ mImageMemoryBarrierCount(0),
+ mEvent(event)
{
- mEvents.push_back(event);
+ ASSERT(mEvent != VK_NULL_HANDLE);
}
EventBarrier(VkPipelineStageFlags srcStageMask,
@@ -240,40 +338,37 @@ class EventBarrier : angle::NonCopyable
: mSrcStageMask(srcStageMask),
mDstStageMask(dstStageMask),
mMemoryBarrierSrcAccess(0),
- mMemoryBarrierDstAccess(0)
+ mMemoryBarrierDstAccess(0),
+ mImageMemoryBarrierCount(1),
+ mEvent(event),
+ mImageMemoryBarrier(imageMemoryBarrier)
{
- ASSERT(event != VK_NULL_HANDLE);
- ASSERT(imageMemoryBarrier.pNext == nullptr);
- mEvents.push_back(event);
- mImageMemoryBarriers.push_back(imageMemoryBarrier);
+ ASSERT(mEvent != VK_NULL_HANDLE);
+ ASSERT(mImageMemoryBarrier.image != VK_NULL_HANDLE);
+ ASSERT(mImageMemoryBarrier.pNext == nullptr);
}
EventBarrier(EventBarrier &&other)
{
- mSrcStageMask = other.mSrcStageMask;
- mDstStageMask = other.mDstStageMask;
- mMemoryBarrierSrcAccess = other.mMemoryBarrierSrcAccess;
- mMemoryBarrierDstAccess = other.mMemoryBarrierDstAccess;
- std::swap(mEvents, other.mEvents);
- std::swap(mImageMemoryBarriers, other.mImageMemoryBarriers);
- other.mSrcStageMask = 0;
- other.mDstStageMask = 0;
- other.mMemoryBarrierSrcAccess = 0;
- other.mMemoryBarrierDstAccess = 0;
+ mSrcStageMask = other.mSrcStageMask;
+ mDstStageMask = other.mDstStageMask;
+ mMemoryBarrierSrcAccess = other.mMemoryBarrierSrcAccess;
+ mMemoryBarrierDstAccess = other.mMemoryBarrierDstAccess;
+ mImageMemoryBarrierCount = other.mImageMemoryBarrierCount;
+ std::swap(mEvent, other.mEvent);
+ std::swap(mImageMemoryBarrier, other.mImageMemoryBarrier);
+ other.mSrcStageMask = 0;
+ other.mDstStageMask = 0;
+ other.mMemoryBarrierSrcAccess = 0;
+ other.mMemoryBarrierDstAccess = 0;
+ other.mImageMemoryBarrierCount = 0;
}
- ~EventBarrier()
- {
- ASSERT(mImageMemoryBarriers.empty());
- ASSERT(mEvents.empty());
- }
+ ~EventBarrier() {}
- bool isEmpty() const
- {
- return mEvents.empty() && mImageMemoryBarriers.empty() && mMemoryBarrierDstAccess == 0;
- }
+ bool isEmpty() const { return mEvent == VK_NULL_HANDLE; }
- bool hasEvent(const VkEvent &event) const;
+ bool hasEvent(const VkEvent &event) const { return mEvent == event; }
void addAdditionalStageAccess(VkPipelineStageFlags dstStageMask, VkAccessFlags dstAccess)
{
@@ -283,12 +378,6 @@ class EventBarrier : angle::NonCopyable
void execute(PrimaryCommandBuffer *primary);
- void reset()
- {
- mEvents.clear();
- mImageMemoryBarriers.clear();
- }
-
void addDiagnosticsString(std::ostringstream &out) const;
private:
@@ -297,8 +386,9 @@ class EventBarrier : angle::NonCopyable
VkPipelineStageFlags mDstStageMask;
VkAccessFlags mMemoryBarrierSrcAccess;
VkAccessFlags mMemoryBarrierDstAccess;
- std::vector<VkEvent> mEvents;
- std::vector<VkImageMemoryBarrier> mImageMemoryBarriers;
+ uint32_t mImageMemoryBarrierCount;
+ VkEvent mEvent;
+ VkImageMemoryBarrier mImageMemoryBarrier;
};
class EventBarrierArray final
@@ -308,6 +398,11 @@ class EventBarrierArray final
void execute(Renderer *renderer, PrimaryCommandBuffer *primary);
+ // Add the additional stageMask to the existing waitEvent.
+ void addAdditionalStageAccess(const RefCountedEvent &waitEvent,
+ VkPipelineStageFlags dstStageMask,
+ VkAccessFlags dstAccess);
+
void addMemoryEvent(Context *context,
const RefCountedEvent &waitEvent,
VkPipelineStageFlags dstStageMask,
@@ -318,12 +413,12 @@ class EventBarrierArray final
VkPipelineStageFlags dstStageMask,
const VkImageMemoryBarrier &imageMemoryBarrier);
- void reset() { mBarriers.clear(); }
+ void reset() { ASSERT(mBarriers.empty()); }
void addDiagnosticsString(std::ostringstream &out) const;
private:
- std::vector<EventBarrier> mBarriers;
+ std::deque<EventBarrier> mBarriers;
};
VkPipelineStageFlags GetRefCountedEventStageMask(Context *context, const RefCountedEvent &event);
diff --git a/src/libANGLE/renderer/vulkan/vk_renderer.cpp b/src/libANGLE/renderer/vulkan/vk_renderer.cpp
index 4c4a49d719..983c90f433 100644
--- a/src/libANGLE/renderer/vulkan/vk_renderer.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_renderer.cpp
@@ -161,6 +161,12 @@ bool IsXclipse()
return strstr(modelName.c_str(), "SM-S901B") != nullptr;
}
+bool ShouldUseEventForImageBarrier()
+{
+ // Disabled for now while performance is under investigation
+ return false;
+}
+
bool StrLess(const char *a, const char *b)
{
return strcmp(a, b) < 0;
@@ -293,6 +299,12 @@ constexpr const char *kNoListRestartSkippedMessages[] = {
"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06252",
};
+// VVL appears has a bug tracking stageMask on VkEvent with secondary command buffer.
+// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7849
+constexpr const char *kSkippedMessagesWithVulkanSecondaryCommandBuffer[] = {
+ "VUID-vkCmdWaitEvents-srcStageMask-parameter",
+};
+
// Some syncval errors are resolved in the presence of the NONE load or store render pass ops. For
// those, ANGLE makes no further attempt to resolve them and expects vendor support for the
// extensions instead. The list of skipped messages is split based on this support.
@@ -1494,8 +1506,7 @@ Renderer::~Renderer() {}
bool Renderer::hasSharedGarbage()
{
- return !mSharedGarbageList.empty() || !mSuballocationGarbageList.empty() ||
- !mRefCountedEventGarbageList.empty();
+ return !mSharedGarbageList.empty() || !mSuballocationGarbageList.empty();
}
void Renderer::onDestroy(vk::Context *context)
@@ -1513,6 +1524,8 @@ void Renderer::onDestroy(vk::Context *context)
ASSERT(!hasSharedGarbage());
ASSERT(mOrphanedBufferBlockList.empty());
+ mRefCountedEventRecycler.destroy(mDevice);
+
for (OneOffCommandPool &oneOffCommandPool : mOneOffCommandPoolMap)
{
oneOffCommandPool.destroy(mDevice);
@@ -1884,7 +1897,11 @@ angle::Result Renderer::initialize(vk::Context *context,
// Fine grain control of validation layer features
const char *name = "VK_LAYER_KHRONOS_validation";
const VkBool32 setting_validate_core = VK_TRUE;
- const VkBool32 setting_validate_sync = IsAndroid() ? VK_FALSE : VK_TRUE;
+ // SyncVal is very slow (https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7285)
+ // for VkEvent which causes a few tests fail on the bots. Disable syncVal if VkEvent is enabled
+ // for now.
+ const VkBool32 setting_validate_sync =
+ IsAndroid() || ShouldUseEventForImageBarrier() ? VK_FALSE : VK_TRUE;
const VkBool32 setting_thread_safety = VK_TRUE;
// http://anglebug.com/7050 - Shader validation caching is broken on Android
const VkBool32 setting_check_shaders = IsAndroid() ? VK_FALSE : VK_TRUE;
@@ -3559,10 +3576,7 @@ angle::Result Renderer::createDeviceAndQueue(vk::Context *context, uint32_t queu
initDeviceExtensionEntryPoints();
- vk::DeviceQueueMap graphicsQueueMap =
- queueFamily.initializeQueueMap(mDevice, enableProtectedContent, 0, queueCount);
-
- ANGLE_TRY(mCommandQueue.init(context, graphicsQueueMap));
+ ANGLE_TRY(mCommandQueue.init(context, queueFamily, enableProtectedContent, queueCount));
ANGLE_TRY(mCommandProcessor.init());
if (mFeatures.forceMaxUniformBufferSize16KB.enabled)
@@ -3645,6 +3659,16 @@ void Renderer::initializeValidationMessageSuppressions()
kNoListRestartSkippedMessages + ArraySize(kNoListRestartSkippedMessages));
}
+ if (getFeatures().useVkEventForImageBarrier.enabled &&
+ (!vk::OutsideRenderPassCommandBuffer::ExecutesInline() ||
+ !vk::RenderPassCommandBuffer::ExecutesInline()))
+ {
+ mSkippedValidationMessages.insert(
+ mSkippedValidationMessages.end(), kSkippedMessagesWithVulkanSecondaryCommandBuffer,
+ kSkippedMessagesWithVulkanSecondaryCommandBuffer +
+ ArraySize(kSkippedMessagesWithVulkanSecondaryCommandBuffer));
+ }
+
// Build the list of syncval errors that are currently expected and should be skipped.
mSkippedSyncvalMessages.insert(mSkippedSyncvalMessages.end(), kSkippedSyncvalMessages,
kSkippedSyncvalMessages + ArraySize(kSkippedSyncvalMessages));
@@ -4046,9 +4070,6 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
return;
}
- constexpr uint32_t kPixel2DriverWithRelaxedPrecision = 0x801EA000;
- constexpr uint32_t kPixel4DriverWithWorkingSpecConstSupport = 0x80201000;
-
const bool isAMD = IsAMD(mPhysicalDeviceProperties.vendorID);
const bool isApple = IsAppleGPU(mPhysicalDeviceProperties.vendorID);
const bool isARM = IsARM(mPhysicalDeviceProperties.vendorID);
@@ -4080,7 +4101,11 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
isARM && getPhysicalDeviceProperties().limits.maxDrawIndirectCount <= 1;
// Parse the ARM driver version to be readable/comparable
const ARMDriverVersion armDriverVersion =
- ParseARMDriverVersion(mPhysicalDeviceProperties.driverVersion);
+ ParseARMVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
+
+ // Parse the Qualcomm driver version.
+ const QualcommDriverVersion qualcommDriverVersion =
+ ParseQualcommVulkanDriverVersion(mPhysicalDeviceProperties.driverVersion);
// Parse the Intel driver version. (Currently it only supports the Windows driver.)
const IntelDriverVersion intelDriverVersion =
@@ -4435,10 +4460,11 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
ANGLE_FEATURE_CONDITION(&mFeatures, enablePreRotateSurfaces, IsAndroid());
// http://anglebug.com/3078
+ // Precision qualifiers are disabled for Pixel 2 before the driver included relaxed precision.
ANGLE_FEATURE_CONDITION(
&mFeatures, enablePrecisionQualifiers,
!(IsPixel2(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID) &&
- (mPhysicalDeviceProperties.driverVersion < kPixel2DriverWithRelaxedPrecision)) &&
+ (qualcommDriverVersion < QualcommDriverVersion(512, 490, 0))) &&
!IsPixel4(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID));
// http://anglebug.com/7488
@@ -4468,7 +4494,7 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
// Prefer driver uniforms over specialization constants in the following:
//
- // - Older Qualcomm drivers where specialization constants severly degrade the performance of
+ // - Older Qualcomm drivers where specialization constants severely degrade the performance of
// pipeline creation. http://issuetracker.google.com/173636783
// - ARM hardware
// - Imagination hardware
@@ -4476,8 +4502,7 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
//
ANGLE_FEATURE_CONDITION(
&mFeatures, preferDriverUniformOverSpecConst,
- (isQualcommProprietary &&
- mPhysicalDeviceProperties.driverVersion < kPixel4DriverWithWorkingSpecConstSupport) ||
+ (isQualcommProprietary && qualcommDriverVersion < QualcommDriverVersion(512, 513, 0)) ||
isARM || isPowerVR || isSwiftShader);
// The compute shader used to generate mipmaps needs -
@@ -4560,8 +4585,9 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
// vkCmdClearAttachments races with draw calls on Qualcomm hardware as observed on Pixel2 and
// Pixel4. https://issuetracker.google.com/issues/166809097
- ANGLE_FEATURE_CONDITION(&mFeatures, preferDrawClearOverVkCmdClearAttachments,
- isQualcommProprietary);
+ ANGLE_FEATURE_CONDITION(
+ &mFeatures, preferDrawClearOverVkCmdClearAttachments,
+ isQualcommProprietary && qualcommDriverVersion < QualcommDriverVersion(512, 762, 12));
// r32f image emulation is done unconditionally so VK_FORMAT_FEATURE_STORAGE_*_ATOMIC_BIT is not
// required.
@@ -4650,10 +4676,10 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
// Important games are not checking supported extensions properly, and are confusing the
// GL_EXT_shader_framebuffer_fetch_non_coherent as the GL_EXT_shader_framebuffer_fetch
- // extension. Therefore, don't enable the extension on Arm and Qualcomm by default.
+ // extension. Therefore, don't enable the extension on Android by default.
// https://issuetracker.google.com/issues/186643966
- ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFramebufferFetchNonCoherent,
- (IsAndroid() && !(isARM || isQualcomm)) || isSwiftShader);
+ // https://issuetracker.google.com/issues/340665604
+ ANGLE_FEATURE_CONDITION(&mFeatures, supportsShaderFramebufferFetchNonCoherent, isSwiftShader);
// On tile-based renderers, breaking the render pass is costly. Changing into and out of
// framebuffer fetch causes the render pass to break so that the layout of the color attachments
@@ -4676,15 +4702,18 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
// usable. Additionally, the following platforms don't support INPUT_ATTACHMENT usage for the
// swapchain, so they are excluded:
//
- // - Intel
+ // - Intel on windows
+ // - Intel on Linux before mesa 22.0
//
// The above platforms are not excluded if behind MESA Virtio-GPU Venus driver since WSI is
// implemented with external memory there.
//
// Without VK_GOOGLE_surfaceless_query, there is no way to automatically deduce this support.
+ const bool isMesaAtLeast22_0_0 = mesaVersion.major >= 22;
ANGLE_FEATURE_CONDITION(
&mFeatures, emulateAdvancedBlendEquations,
- !mFeatures.supportsBlendOperationAdvanced.enabled && (isVenus || !isIntel));
+ !mFeatures.supportsBlendOperationAdvanced.enabled &&
+ (isVenus || !isIntel || (isIntel && IsLinux() && isMesaAtLeast22_0_0)));
// http://anglebug.com/6933
// Android expects VkPresentRegionsKHR rectangles with a bottom-left origin, while spec
@@ -5049,9 +5078,9 @@ void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
ANGLE_FEATURE_CONDITION(&mFeatures, supportsExternalFormatResolve, false);
#endif
- // Disable use of VkCmdWaitEvent for image barriers for now.
- // https://issuetracker.google.com/336844257
- ANGLE_FEATURE_CONDITION(&mFeatures, useVkEventForImageBarrier, false);
+ // initialize() is disabling syncval if event is used, which comes before feature flag is set.
+ // Use ShouldUseEventForImageBarrier to enable/disable event for certain config if needed.
+ ANGLE_FEATURE_CONDITION(&mFeatures, useVkEventForImageBarrier, ShouldUseEventForImageBarrier());
// Disable memory report feature overrides if extension is not supported.
if ((mFeatures.logMemoryReportCallbacks.enabled || mFeatures.logMemoryReportStats.enabled) &&
@@ -5506,8 +5535,6 @@ void Renderer::cleanupGarbage()
// Note: do this after clean up mSuballocationGarbageList so that we will have more chances to
// find orphaned blocks being empty.
mOrphanedBufferBlockList.pruneEmptyBufferBlocks(this);
- // Clean up event garbages
- mRefCountedEventGarbageList.cleanupSubmittedGarbage(this);
}
void Renderer::cleanupPendingSubmissionGarbage()
@@ -5515,7 +5542,6 @@ void Renderer::cleanupPendingSubmissionGarbage()
// Check if pending garbage is still pending. If not, move them to the garbage list.
mSharedGarbageList.cleanupUnsubmittedGarbage(this);
mSuballocationGarbageList.cleanupUnsubmittedGarbage(this);
- mRefCountedEventGarbageList.cleanupUnsubmittedGarbage(this);
}
void Renderer::onNewValidationMessage(const std::string &message)
diff --git a/src/libANGLE/renderer/vulkan/vk_renderer.h b/src/libANGLE/renderer/vulkan/vk_renderer.h
index 228da259fd..da7bb390f3 100644
--- a/src/libANGLE/renderer/vulkan/vk_renderer.h
+++ b/src/libANGLE/renderer/vulkan/vk_renderer.h
@@ -228,6 +228,15 @@ class Renderer : angle::NonCopyable
{
return mQueueFamilyProperties[mCurrentQueueFamilyIndex];
}
+ const DeviceQueueIndex getDeviceQueueIndex(egl::ContextPriority priority) const
+ {
+ return mCommandQueue.getDeviceQueueIndex(priority);
+ }
+ const DeviceQueueIndex getDefaultDeviceQueueIndex() const
+ {
+ // By default it will always use medium priority
+ return mCommandQueue.getDeviceQueueIndex(egl::ContextPriority::Medium);
+ }
const vk::MemoryProperties &getMemoryProperties() const { return mMemoryProperties; }
@@ -277,7 +286,6 @@ class Renderer : angle::NonCopyable
{
return mCommandQueue.getDriverPriority(priority);
}
- ANGLE_INLINE uint32_t getDeviceQueueIndex() { return mCommandQueue.getDeviceQueueIndex(); }
VkQueue getQueue(egl::ContextPriority priority) { return mCommandQueue.getQueue(priority); }
@@ -339,14 +347,6 @@ class Renderer : angle::NonCopyable
mSuballocationGarbageList.add(this, std::move(garbage));
}
- void collectRefCountedEventsGarbage(const QueueSerial &queueSerial,
- vk::RefCountedEventCollector &&refCountedEvents)
- {
- ASSERT(!refCountedEvents.empty());
- vk::RefCountedEventsGarbage garbage(queueSerial, std::move(refCountedEvents));
- mRefCountedEventGarbageList.add(this, std::move(garbage));
- }
-
angle::Result getPipelineCache(vk::Context *context, vk::PipelineCacheAccess *pipelineCacheOut);
angle::Result mergeIntoPipelineCache(vk::Context *context,
const vk::PipelineCache &pipelineCache);
@@ -748,6 +748,10 @@ class Renderer : angle::NonCopyable
return mPipelineCacheGraphDumpPath.c_str();
}
+ vk::RefCountedEventRecycler *getRefCountedEventRecycler() { return &mRefCountedEventRecycler; }
+
+ std::thread::id getCommandProcessorThreadId() const { return mCommandProcessor.getThreadId(); }
+
private:
angle::Result setupDevice(vk::Context *context,
const angle::FeatureOverrides &featureOverrides,
@@ -957,8 +961,8 @@ class Renderer : angle::NonCopyable
vk::SharedGarbageList<vk::BufferSuballocationGarbage> mSuballocationGarbageList;
// Holds orphaned BufferBlocks when ShareGroup gets destroyed
vk::BufferBlockGarbageList mOrphanedBufferBlockList;
- // Holds RefCountedEvent garbage
- vk::SharedGarbageList<vk::RefCountedEventsGarbage> mRefCountedEventGarbageList;
+ // Holds RefCountedEvent that are free and ready to reuse
+ vk::RefCountedEventRecycler mRefCountedEventRecycler;
VkDeviceSize mPendingGarbageSizeLimit;
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.cpp b/src/libANGLE/renderer/vulkan/vk_utils.cpp
index 3c4390f7a1..0699e95e83 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_utils.cpp
@@ -370,7 +370,9 @@ VkImageAspectFlags GetFormatAspectFlags(const angle::Format &format)
}
// Context implementation.
-Context::Context(Renderer *renderer) : mRenderer(renderer), mPerfCounters{} {}
+Context::Context(Renderer *renderer)
+ : mRenderer(renderer), mShareGroupRefCountedEventsGarbageRecycler(nullptr), mPerfCounters{}
+{}
Context::~Context() {}
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h
index dc4ebdf9d6..0df93a457f 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.h
+++ b/src/libANGLE/renderer/vulkan/vk_utils.h
@@ -132,6 +132,65 @@ class Renderer;
// Used for memory allocation tracking.
enum class MemoryAllocationType;
+// Encapsulate the graphics family index and VkQueue index (as seen in vkGetDeviceQueue API
+// arguments) into one integer so that we can easily pass around without introduce extra overhead..
+class DeviceQueueIndex final
+{
+ public:
+ constexpr DeviceQueueIndex()
+ : mFamilyIndex(kInvalidQueueFamilyIndex), mQueueIndex(kInvalidQueueIndex)
+ {}
+ constexpr DeviceQueueIndex(uint32_t familyIndex)
+ : mFamilyIndex((int8_t)familyIndex), mQueueIndex(kInvalidQueueIndex)
+ {
+ ASSERT(static_cast<uint32_t>(mFamilyIndex) == familyIndex);
+ }
+ DeviceQueueIndex(uint32_t familyIndex, uint32_t queueIndex)
+ : mFamilyIndex((int8_t)familyIndex), mQueueIndex((int8_t)queueIndex)
+ {
+ // Ensure the value we actually don't truncate the useful bits.
+ ASSERT(static_cast<uint32_t>(mFamilyIndex) == familyIndex);
+ ASSERT(static_cast<uint32_t>(mQueueIndex) == queueIndex);
+ }
+ DeviceQueueIndex(const DeviceQueueIndex &other) { *this = other; }
+
+ DeviceQueueIndex &operator=(const DeviceQueueIndex &other)
+ {
+ mValue = other.mValue;
+ return *this;
+ }
+
+ constexpr uint32_t familyIndex() const { return mFamilyIndex; }
+ constexpr uint32_t queueIndex() const { return mQueueIndex; }
+
+ bool operator==(const DeviceQueueIndex &other) const { return mValue == other.mValue; }
+ bool operator!=(const DeviceQueueIndex &other) const { return mValue != other.mValue; }
+
+ private:
+ static constexpr int8_t kInvalidQueueFamilyIndex = -1;
+ static constexpr int8_t kInvalidQueueIndex = -1;
+ // The expectation is that these indices are small numbers that could easily fit into int8_t.
+ // int8_t is used instead of uint8_t because we need to handle VK_QUEUE_FAMILY_FOREIGN_EXT and
+ // VK_QUEUE_FAMILY_EXTERNAL properly which are essentially are negative values.
+ union
+ {
+ struct
+ {
+ int8_t mFamilyIndex;
+ int8_t mQueueIndex;
+ };
+ uint16_t mValue;
+ };
+};
+static constexpr DeviceQueueIndex kInvalidDeviceQueueIndex = DeviceQueueIndex();
+static constexpr DeviceQueueIndex kForeignDeviceQueueIndex =
+ DeviceQueueIndex(VK_QUEUE_FAMILY_FOREIGN_EXT);
+static constexpr DeviceQueueIndex kExternalDeviceQueueIndex =
+ DeviceQueueIndex(VK_QUEUE_FAMILY_EXTERNAL);
+static_assert(kForeignDeviceQueueIndex.familyIndex() == VK_QUEUE_FAMILY_FOREIGN_EXT);
+static_assert(kExternalDeviceQueueIndex.familyIndex() == VK_QUEUE_FAMILY_EXTERNAL);
+static_assert(kInvalidDeviceQueueIndex.familyIndex() == VK_QUEUE_FAMILY_IGNORED);
+
// A packed attachment index interface with vulkan API
class PackedAttachmentIndex final
{
@@ -278,6 +337,7 @@ class [[nodiscard]] ScopedQueueSerialIndex final : angle::NonCopyable
QueueSerialIndexAllocator *mIndexAllocator;
};
+class RefCountedEventsGarbageRecycler;
// Abstracts error handling. Implemented by ContextVk for GL, DisplayVk for EGL, worker threads,
// CLContextVk etc.
class Context : angle::NonCopyable
@@ -296,9 +356,17 @@ class Context : angle::NonCopyable
const angle::VulkanPerfCounters &getPerfCounters() const { return mPerfCounters; }
angle::VulkanPerfCounters &getPerfCounters() { return mPerfCounters; }
+ RefCountedEventsGarbageRecycler *getRefCountedEventsGarbageRecycler()
+ {
+ return mShareGroupRefCountedEventsGarbageRecycler;
+ }
+ const DeviceQueueIndex &getDeviceQueueIndex() const { return mDeviceQueueIndex; }
protected:
Renderer *const mRenderer;
+ // Stash the ShareGroupVk's RefCountedEventRecycler here ImageHelper to conveniently access
+ RefCountedEventsGarbageRecycler *mShareGroupRefCountedEventsGarbageRecycler;
+ DeviceQueueIndex mDeviceQueueIndex;
angle::VulkanPerfCounters mPerfCounters;
};
@@ -664,6 +732,12 @@ class RefCounted : angle::NonCopyable
mRefCount--;
}
+ uint32_t getAndReleaseRef()
+ {
+ ASSERT(isReferenced());
+ return mRefCount--;
+ }
+
bool isReferenced() const { return mRefCount != 0; }
T &get() { return mObject; }
@@ -702,9 +776,7 @@ class AtomicRefCounted : angle::NonCopyable
unsigned int getAndReleaseRef()
{
ASSERT(isReferenced());
- // 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);
+ return mRefCount.fetch_sub(1, std::memory_order_relaxed);
}
bool isReferenced() const { return mRefCount.load(std::memory_order_relaxed) != 0; }
@@ -907,7 +979,7 @@ class Recycler final : angle::NonCopyable
bool empty() const { return mObjectFreeList.empty(); }
private:
- std::vector<T> mObjectFreeList;
+ std::deque<T> mObjectFreeList;
};
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
diff --git a/src/libANGLE/renderer/wgpu/DeviceWgpu.cpp b/src/libANGLE/renderer/wgpu/DeviceWgpu.cpp
index f2b2f5fcec..a35a686bc2 100644
--- a/src/libANGLE/renderer/wgpu/DeviceWgpu.cpp
+++ b/src/libANGLE/renderer/wgpu/DeviceWgpu.cpp
@@ -29,11 +29,6 @@ egl::Error DeviceWgpu::getAttribute(const egl::Display *display, EGLint attribut
return egl::EglBadAccess();
}
-EGLint DeviceWgpu::getType()
-{
- return 0;
-}
-
void DeviceWgpu::generateExtensions(egl::DeviceExtensions *outExtensions) const {}
} // namespace rx
diff --git a/src/libANGLE/renderer/wgpu/DeviceWgpu.h b/src/libANGLE/renderer/wgpu/DeviceWgpu.h
index a4c799bf2e..b8966a3119 100644
--- a/src/libANGLE/renderer/wgpu/DeviceWgpu.h
+++ b/src/libANGLE/renderer/wgpu/DeviceWgpu.h
@@ -25,7 +25,6 @@ class DeviceWgpu : public DeviceImpl
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
- EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
};
diff --git a/src/libANGLE/validationEGL.cpp b/src/libANGLE/validationEGL.cpp
index 18404cc50a..4a3cbed55b 100644
--- a/src/libANGLE/validationEGL.cpp
+++ b/src/libANGLE/validationEGL.cpp
@@ -6416,8 +6416,14 @@ bool ValidateQueryDeviceAttribEXT(const ValidationContext *val,
switch (attribute)
{
case EGL_D3D11_DEVICE_ANGLE:
+ if (!device->getExtensions().deviceD3D11)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
case EGL_D3D9_DEVICE_ANGLE:
- if (!device->getExtensions().deviceD3D || device->getType() != attribute)
+ if (!device->getExtensions().deviceD3D9)
{
val->setError(EGL_BAD_ATTRIBUTE);
return false;
diff --git a/src/libGLESv2/entry_points_gles_2_0_autogen.cpp b/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
index b68fd658bb..4760f088eb 100644
--- a/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
@@ -121,7 +121,7 @@ void GL_APIENTRY GL_BindBuffer(GLenum target, GLuint buffer)
{
BufferBinding targetPacked = PackParam<BufferBinding>(target);
BufferID bufferPacked = PackParam<BufferID>(buffer);
- SCOPED_SHARE_CONTEXT_LOCK(context);
+
bool isCallValid = (context->skipValidation() ||
ValidateBindBuffer(context, angle::EntryPoint::GLBindBuffer,
targetPacked, bufferPacked));
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index f5bdcba673..31296ecd29 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -199,6 +199,7 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
7866 WIN INTEL VULKAN : VulkanPerformanceCounterTest.PipelineCacheIsRestoredWithProgramBinary/* = SKIP
7866 WIN INTEL VULKAN : VulkanPerformanceCounterTest.PipelineCacheIsRestoredWithProgramBinaryTwice/* = SKIP
7866 WIN INTEL VULKAN : VulkanPerformanceCounterTest.PipelineCacheIsWarmedUpAtLinkTime/* = SKIP
+342557702 WIN INTEL VULKAN : StateChangeTestES3.RasterizerDiscard/ES3_Vulkan_NoSupportsExtendedDynamicState2 = SKIP
// vk_icdNegotiateLoaderICDInterfaceVersion crashes (possibly Mesa bug?)
8179 LINUX INTEL VULKAN : RGBTextureBufferTestES31.* = SKIP
8179 LINUX INTEL VULKAN : TextureBufferTestES31.TexBufferFormatMismatch/* = SKIP
@@ -458,7 +459,6 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
6480 PIXEL4ORXL GLES : RobustResourceInitTestES3.CheckMultisampleDepthStencilRenderbufferIsCleared/* = SKIP
5981 PIXEL4ORXL GLES : SimpleStateChangeTestES31.ClearThenSampleWithCompute/* = SKIP
5981 PIXEL4ORXL GLES : SimpleStateChangeTestES31.InvalidateThenStorageWriteThenBlend/* = SKIP
-6744 PIXEL4ORXL GLES : SimpleStateChangeTestES3.OutOfBoundsByteAttribute/* = SKIP
5981 PIXEL4ORXL GLES : SimpleStateChangeTestES31.TransformFeedbackThenReadWithCompute/* = SKIP
5981 PIXEL4ORXL GLES : Texture3DTestES2.DefineTexture2DArrayShouldFail/* = SKIP
5981 PIXEL4ORXL GLES : Texture3DTestES2.CopySubImageAlpha/* = SKIP
@@ -506,7 +506,6 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
5981 PIXEL4ORXL VULKAN : PointSpriteTest.TrianglesNotTreatedAsPointSprites/* = SKIP
5981 PIXEL4ORXL VULKAN : ProgramBinaryTransformFeedbackTest.GetTransformFeedbackVarying/* = SKIP
5981 PIXEL4ORXL VULKAN : TransformFeedbackTestIOBlocks.Interleaved/* = SKIP
-6744 PIXEL4ORXL VULKAN : SimpleStateChangeTestES3.OutOfBoundsByteAttribute/* = SKIP
6843 PIXEL4ORXL VULKAN : ImageTest.SourceYUVAHBTargetExternalRGBSampleInitData/* = SKIP
6843 PIXEL4ORXL VULKAN : ImageTestES3.SourceYUVAHBTargetExternalYUVSampleLinearFiltering/* = SKIP
7108 PIXEL4ORXL VULKAN : ImageTestES3.SourceAHBMipTarget2DMip/* = SKIP
@@ -1211,7 +1210,6 @@ b/267953710 GALAXYS22 VULKAN : VulkanPerformanceCounterTest_ES31.ColorMaskedFram
8185 GALAXYQUALCOMM VULKAN : RobustResourceInitTest.MaskedStencilClear/* = SKIP
8185 GALAXYQUALCOMM VULKAN : RobustResourceInitTestES3.MaskedStencilClearBuffer/* = SKIP
8185 GALAXYQUALCOMM VULKAN : SampleVariablesTest.SamplePosition/* = SKIP
-8185 GALAXYQUALCOMM VULKAN : SimpleStateChangeTestES3.OutOfBoundsByteAttribute/* = SKIP
8185 GALAXYQUALCOMM VULKAN : StateChangeTestES3.StencilReferenceAndCompareMask/* = SKIP
8185 GALAXYQUALCOMM VULKAN : Texture2DTestES3.TexImageWithStencilData/* = SKIP
8185 GALAXYQUALCOMM VULKAN : Texture2DTestES3.TexImageWithStencilPBO/* = SKIP
diff --git a/src/tests/deqp_support/deqp.gni b/src/tests/deqp_support/deqp.gni
index 65de2dffd4..c65d9ba894 100644
--- a/src/tests/deqp_support/deqp.gni
+++ b/src/tests/deqp_support/deqp.gni
@@ -869,6 +869,10 @@ deqp_khr_common_sources = [
"$deqp_path/external/openglcts/modules/common/glcAggressiveShaderOptimizationsTests.hpp",
"$deqp_path/external/openglcts/modules/common/glcBlendEquationAdvancedTests.cpp",
"$deqp_path/external/openglcts/modules/common/glcBlendEquationAdvancedTests.hpp",
+ "$deqp_path/external/openglcts/modules/common/glcBufferObjectsTests.cpp",
+ "$deqp_path/external/openglcts/modules/common/glcBufferObjectsTests.hpp",
+ "$deqp_path/external/openglcts/modules/common/glcClipDistance.cpp",
+ "$deqp_path/external/openglcts/modules/common/glcClipDistance.hpp",
"$deqp_path/external/openglcts/modules/common/glcCompressedFormatTests.cpp",
"$deqp_path/external/openglcts/modules/common/glcCompressedFormatTests.hpp",
"$deqp_path/external/openglcts/modules/common/glcCompressedFormatTests_data.inl",
@@ -886,6 +890,8 @@ deqp_khr_common_sources = [
"$deqp_path/external/openglcts/modules/common/glcContext.hpp",
"$deqp_path/external/openglcts/modules/common/glcContextFlagsTests.cpp",
"$deqp_path/external/openglcts/modules/common/glcContextFlagsTests.hpp",
+ "$deqp_path/external/openglcts/modules/common/glcCullDistance.cpp",
+ "$deqp_path/external/openglcts/modules/common/glcCullDistance.hpp",
"$deqp_path/external/openglcts/modules/common/glcExposedExtensionsTests.cpp",
"$deqp_path/external/openglcts/modules/common/glcExposedExtensionsTests.hpp",
"$deqp_path/external/openglcts/modules/common/glcExtTokens.cpp",
@@ -986,6 +992,8 @@ deqp_khr_common_sources = [
"$deqp_path/external/openglcts/modules/common/glcTextureRepeatModeTests.hpp",
"$deqp_path/external/openglcts/modules/common/glcUniformBlockCase.cpp",
"$deqp_path/external/openglcts/modules/common/glcUniformBlockCase.hpp",
+ "$deqp_path/external/openglcts/modules/common/glcUniformBlockNegativeTests.cpp",
+ "$deqp_path/external/openglcts/modules/common/glcUniformBlockNegativeTests.hpp",
"$deqp_path/external/openglcts/modules/common/glcUniformBlockTests.cpp",
"$deqp_path/external/openglcts/modules/common/glcUniformBlockTests.hpp",
"$deqp_path/external/openglcts/modules/common/glcViewportArrayTests.cpp",
@@ -1056,12 +1064,8 @@ deqp_khr_test_module_headers = [
]
deqp_khr_gl_sources = [
- "$deqp_path/external/openglcts/modules/gl/gl3cClipDistance.cpp",
- "$deqp_path/external/openglcts/modules/gl/gl3cClipDistance.hpp",
"$deqp_path/external/openglcts/modules/gl/gl3cCommonBugsTests.cpp",
"$deqp_path/external/openglcts/modules/gl/gl3cCommonBugsTests.hpp",
- "$deqp_path/external/openglcts/modules/gl/gl3cCullDistanceTests.cpp",
- "$deqp_path/external/openglcts/modules/gl/gl3cCullDistanceTests.hpp",
"$deqp_path/external/openglcts/modules/gl/gl3cGLSLnoperspectiveTests.cpp",
"$deqp_path/external/openglcts/modules/gl/gl3cGLSLnoperspectiveTests.hpp",
"$deqp_path/external/openglcts/modules/gl/gl3cGPUShader5Tests.cpp",
diff --git a/src/tests/deqp_support/deqp_gl46_test_expectations.txt b/src/tests/deqp_support/deqp_gl46_test_expectations.txt
index 3deca78873..d05228700f 100644
--- a/src/tests/deqp_support/deqp_gl46_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gl46_test_expectations.txt
@@ -81,3 +81,4 @@
7566 SWIFTSHADER UBSAN : KHR-GL46.shader_bitfield_operation.bitfieldInsert.int_3 = SKIP
+8693 SWIFTSHADER : KHR-GL46.buffer_objects.* = FAIL
diff --git a/src/tests/deqp_support/deqp_gles2_test_expectations.txt b/src/tests/deqp_support/deqp_gles2_test_expectations.txt
index 33e3936aed..8ed4da8f64 100644
--- a/src/tests/deqp_support/deqp_gles2_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles2_test_expectations.txt
@@ -365,3 +365,12 @@ b/328156792 PINEAPPLE VULKAN : dEQP-GLES2.functional.texture*cube* = SKIP
b/328156792 PINEAPPLE VULKAN : dEQP-GLES2.functional.uniform_api.random.* = SKIP
b/328156792 PINEAPPLE VULKAN : dEQP-GLES2.functional.uniform_api.value.assigned.* = SKIP
+// BGRA failures
+8692 : dEQP-GLES2.functional.fbo.completeness.renderable.renderbuffer*bgra = FAIL
+8692 : dEQP-GLES2.functional.fbo.render.color*bgra* = FAIL
+8692 : dEQP-GLES2.functional.fbo.render.depth*bgra* = FAIL
+8692 : dEQP-GLES2.functional.fbo.render.*_colorbuffer*bgra* = FAIL
+8692 : dEQP-GLES2.functional.fbo.render.*_depthbuffer*bgra* = FAIL
+8692 : dEQP-GLES2.functional.fbo.render.*_stencilbuffer*bgra* = FAIL
+8692 : dEQP-GLES2.functional.fbo.render.resize*bgra* = FAIL
+8692 : dEQP-GLES2.functional.fbo.render.stencil*bgra* = FAIL
diff --git a/src/tests/deqp_support/deqp_gles31_test_expectations.txt b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
index a11c78a32a..a0bacc6c64 100644
--- a/src/tests/deqp_support/deqp_gles31_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
@@ -179,20 +179,8 @@ b/266710445 WIN OPENGL NVIDIA : dEQP-GLES31.functional.image_load_store.buffer.a
3886 VULKAN NVIDIA : dEQP-GLES31.functional.image_load_store.3d.*single_layer = SKIP
// Emulated advanced blend equations (only Nvidia and SwiftShader support the Vulkan extension):
-3586 AMD VULKAN : dEQP-GLES31.functional.blend_equation_advanced.msaa.* = FAIL
3586 INTEL VULKAN : dEQP-GLES31.functional.blend_equation_advanced.msaa.* = FAIL
3586 PIXEL4ORXL VULKAN : dEQP-GLES31.functional.blend_equation_advanced.msaa.* = FAIL
-////
-//// AMD Vulkan expectations
-////
-
-// Cannot support the per-sample shading when gl_SampleID or gl_SamplePosition:
-3588 VULKAN AMD : dEQP-GLES31.functional.shaders.sample_variables.sample_mask_in.bit*_per_sample.multisample_*_1 = FAIL
-3588 VULKAN AMD : dEQP-GLES31.functional.shaders.sample_variables.sample_mask_in.bit*_per_sample.multisample_*_2 = FAIL
-3588 VULKAN AMD : dEQP-GLES31.functional.shaders.sample_variables.sample_mask_in.bit*_per_sample.multisample_*_4 = FAIL
-3588 VULKAN AMD : dEQP-GLES31.functional.shaders.sample_variables.sample_mask_in.bit*_per_sample.multisample_*_8 = FAIL
-3588 VULKAN AMD : dEQP-GLES31.functional.shaders.sample_variables.sample_mask_in.bit_count_per_two_samples.multisample_*_4 = FAIL
-3588 VULKAN AMD : dEQP-GLES31.functional.shaders.sample_variables.sample_mask_in.bit_count_per_two_samples.multisample_*_8 = FAIL
////
//// Android (i.e. Pixel*) Vulkan expectations
@@ -208,16 +196,11 @@ b/266710445 WIN OPENGL NVIDIA : dEQP-GLES31.functional.image_load_store.buffer.a
4371 SWIFTSHADER : dEQP-GLES31.functional.shaders.implicit_conversions.* = FAIL
// Desktop cards without native etc support, angle emulated format fails
-5276 AMD VULKAN : dEQP-GLES31.functional.copy_image.compressed.viewclass_eac* = FAIL
-5276 AMD VULKAN : dEQP-GLES31.functional.copy_image.compressed.viewclass_etc* = FAIL
-5276 AMD VULKAN : dEQP-GLES31.functional.copy_image.mixed.*eac* = FAIL
5276 NVIDIA VULKAN : dEQP-GLES31.functional.copy_image.compressed.viewclass_eac* = FAIL
5276 NVIDIA VULKAN : dEQP-GLES31.functional.copy_image.compressed.viewclass_etc* = FAIL
5276 NVIDIA VULKAN : dEQP-GLES31.functional.copy_image.mixed.*eac* = FAIL
// Copy image tests fail on desktop cards where ASTC is emulated
-7415 AMD VULKAN : dEQP-GLES31.functional.copy_image.mixed.*astc* = FAIL
-7415 AMD VULKAN : dEQP-GLES31.functional.copy_image.compressed.viewclass_astc* = FAIL
7415 NVIDIA VULKAN : dEQP-GLES31.functional.copy_image.mixed.*astc* = FAIL
7415 NVIDIA VULKAN : dEQP-GLES31.functional.copy_image.compressed.viewclass_astc* = FAIL
diff --git a/src/tests/deqp_support/deqp_gles3_test_expectations.txt b/src/tests/deqp_support/deqp_gles3_test_expectations.txt
index 78c97197fe..55668810e7 100644
--- a/src/tests/deqp_support/deqp_gles3_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles3_test_expectations.txt
@@ -859,3 +859,7 @@ b/328156792 PINEAPPLE VULKAN : dEQP-GLES3.functional.uniform_api.value.assigned.
4140 VULKAN : dEQP-GLES3.functional.transform_feedback.array_element.interleaved.* = FAIL
4140 VULKAN : dEQP-GLES3.functional.transform_feedback.array_element.separate.* = FAIL
4140 VULKAN : dEQP-GLES3.functional.transform_feedback.random.* = FAIL
+
+// BGRA failures
+8692 : dEQP-GLES3.functional.fbo.completeness.renderable.renderbuffer*bgra = FAIL
+8692 MAC : dEQP-GLES3.functional.texture.filtering.2d_array.formats.bgra* = FAIL \ No newline at end of file
diff --git a/src/tests/deqp_support/deqp_khr_gles32_test_expectations.txt b/src/tests/deqp_support/deqp_khr_gles32_test_expectations.txt
index 211b4e5d5e..6959e7e4ec 100644
--- a/src/tests/deqp_support/deqp_khr_gles32_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_khr_gles32_test_expectations.txt
@@ -95,17 +95,12 @@
3577 VULKAN PIXEL4ORXL : KHR-GLES32.core.gpu_shader5.*clamp*_edge = SKIP
// Desktop cards without native etc support
-5276 AMD VULKAN LINUX : KHR-GLES32.core.texture_cube_map_array.etc2_texture = FAIL
-5276 AMD VULKAN WIN : KHR-GLES32.core.texture_cube_map_array.etc2_texture = FAIL
5276 NVIDIA VULKAN : KHR-GLES32.core.texture_cube_map_array.etc2_texture = FAIL
// Validation errors
6441 VULKAN NVIDIA : KHR-GLES32.core.compressed_format.api.copy_compressed_to_uncompressed = FAIL
6441 VULKAN NVIDIA : KHR-GLES32.core.compressed_format.api.copy_uncompressed_to_compressed = FAIL
6441 VULKAN NVIDIA : KHR-GLES32.core.compressed_format.api.copy_compressed_to_compressed = FAIL
-// Looks like test error where ASTC support is not queried
-6441 VULKAN NVIDIA : KHR-GLES32.core.compressed_format.format.*astc* = FAIL
-6441 VULKAN AMD : KHR-GLES32.core.compressed_format.format.*astc* = FAIL
// Pixel 4 expectations.
5990 PIXEL4ORXL VULKAN : KHR-GLES32.core.draw_buffers_indexed.color_masks = SKIP
diff --git a/src/tests/deqp_support/deqp_khr_gles3_test_expectations.txt b/src/tests/deqp_support/deqp_khr_gles3_test_expectations.txt
index 7a9b640a43..2c53c907c6 100644
--- a/src/tests/deqp_support/deqp_khr_gles3_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_khr_gles3_test_expectations.txt
@@ -12,6 +12,8 @@
// Texture related failure on Pixel 4.
8616 VULKAN PIXEL4ORXL : KHR-GLES3.texture_lod_basic.lod_selection = FAIL
+341780527 VULKAN PIXEL4ORXL : KHR-GLES3.clip_distance.coverage = FAIL
+
// Test bug - fails in ASAN
6678 VULKAN ANDROID : KHR-GLES3.packed_pixels.varied_rectangle.* = SKIP
6678 VULKAN NVIDIA : KHR-GLES3.packed_pixels.varied_rectangle.r8_snorm = SKIP
@@ -20,6 +22,11 @@
5976 LINUX VULKAN NVIDIA : KHR-GLES3.shaders.indexing.tmp_array.vertexid = FAIL
+341780527 LINUX VULKAN NVIDIA : KHR-GLES3.clip_distance.coverage = FAIL
+341780527 LINUX VULKAN NVIDIA : KHR-GLES3.cull_distance.functional = FAIL
+341780527 WIN VULKAN NVIDIA : KHR-GLES3.clip_distance.coverage = FAIL
+341780527 WIN VULKAN NVIDIA : KHR-GLES3.cull_distance.functional = FAIL
+
// Fails only with SwiftShader:
// These only fail on Android
@@ -59,6 +66,9 @@
4019 SWIFTSHADER : KHR-GLES3.shaders.indexing.matrix_subscript.mat4_static_write_dynamic_read_vertex = FAIL
4019 SWIFTSHADER : KHR-GLES3.shaders.indexing.matrix_subscript.mat4_static_write_static_loop_read_fragment = FAIL
4019 SWIFTSHADER : KHR-GLES3.shaders.indexing.matrix_subscript.mat4_static_write_static_loop_read_vertex = FAIL
+341780527 SWIFTSHADER : KHR-GLES3.clip_distance.coverage = FAIL
+341780527 SWIFTSHADER : KHR-GLES3.clip_distance.functional = FAIL
+341780527 SWIFTSHADER : KHR-GLES3.cull_distance.functional = FAIL
// https://gitlab.khronos.org/opengl/API/-/issues/180
8048 VULKAN NVIDIA : KHR-GLES3.packed_pixels.pbo_rectangle.r8_snorm = SKIP
@@ -83,6 +93,8 @@
// Samsung Galaxy S23
8157 GALAXYS23 VULKAN : KHR-GLES3.shaders.function.global_variable_aliasing_fragment = SKIP
+341780527 GALAXYS23 VULKAN : KHR-GLES3.clip_distance.coverage = FAIL
+341780527 GALAXYS23 VULKAN : KHR-GLES3.cull_distance.functional = FAIL
// Snapdragon 8 Gen3 Mobile Reference Device
b/328156792 PINEAPPLE VULKAN : KHR-GLES3.copy_tex_image_conversions.required.* = SKIP
@@ -96,3 +108,6 @@ b/328156792 PINEAPPLE VULKAN : KHR-GLES3.shaders.function.global_variable_aliasi
8636 LINUX : KHR-GLES3.framebuffer_blit.framebuffer_blit_functionality_multisampled_to_singlesampled_blit = FAIL
8636 WIN : KHR-GLES3.framebuffer_blit.framebuffer_blit_functionality_multisampled_to_singlesampled_blit = FAIL
b/332383430 PIXEL6 VULKAN : KHR-GLES3.texture_lod_bias.texture_lod_bias_all = FAIL
+
+// Flaky timeout
+b/332383430 TSAN SWIFTSHADER : KHR-GLES3.texture_lod_bias.texture_lod_bias_all = SKIP
diff --git a/src/tests/egl_tests/EGLDeviceTest.cpp b/src/tests/egl_tests/EGLDeviceTest.cpp
index 8042aa9286..05c1834fe9 100644
--- a/src/tests/egl_tests/EGLDeviceTest.cpp
+++ b/src/tests/egl_tests/EGLDeviceTest.cpp
@@ -333,9 +333,6 @@ class EGLDeviceQueryTest : public ANGLETest<>
void testSetUp() override
{
- const char *extensionString =
- static_cast<const char *>(eglQueryString(getEGLWindow()->getDisplay(), EGL_EXTENSIONS));
-
if (!eglQueryDeviceStringEXT)
{
FAIL() << "ANGLE extension EGL_EXT_device_query export eglQueryDeviceStringEXT was not "
@@ -357,11 +354,13 @@ class EGLDeviceQueryTest : public ANGLETest<>
EGLAttrib angleDevice = 0;
EXPECT_EGL_TRUE(
eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
- extensionString = static_cast<const char *>(
- eglQueryDeviceStringEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_EXTENSIONS));
- if (strstr(extensionString, "EGL_ANGLE_device_d3d") == nullptr)
+ if (!IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ "EGL_ANGLE_device_d3d9") &&
+ !IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ "EGL_ANGLE_device_d3d11"))
{
- FAIL() << "ANGLE extension EGL_ANGLE_device_d3d was not found";
+ FAIL() << "ANGLE extensions EGL_ANGLE_device_d3d9 or EGL_ANGLE_device_d3d11 were not "
+ "found";
}
}
};
@@ -372,27 +371,29 @@ class EGLDeviceQueryTest : public ANGLETest<>
// If the test is confitured to use D3D9, then it should succeed to obtain a D3D9 device.
TEST_P(EGLDeviceQueryTest, QueryDevice)
{
- EGLAttrib device = 0;
EGLAttrib angleDevice = 0;
- if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ EXPECT_EGL_TRUE(
+ eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+
+ if (IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ "EGL_ANGLE_device_d3d11"))
{
- EXPECT_EGL_TRUE(
- eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EGLAttrib device11 = 0;
EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
- EGL_D3D11_DEVICE_ANGLE, &device));
- ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
+ EGL_D3D11_DEVICE_ANGLE, &device11));
+ ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device11);
IDXGIDevice *dxgiDevice = DynamicCastComObject<IDXGIDevice>(d3d11Device);
EXPECT_TRUE(dxgiDevice != nullptr);
SafeRelease(dxgiDevice);
}
- if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
+ if (IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ "EGL_ANGLE_device_d3d9"))
{
- EXPECT_EGL_TRUE(
- eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EGLAttrib device9 = 0;
EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
- EGL_D3D9_DEVICE_ANGLE, &device));
- IDirect3DDevice9 *d3d9Device = reinterpret_cast<IDirect3DDevice9 *>(device);
+ EGL_D3D9_DEVICE_ANGLE, &device9));
+ IDirect3DDevice9 *d3d9Device = reinterpret_cast<IDirect3DDevice9 *>(device9);
IDirect3D9 *d3d9 = nullptr;
EXPECT_EQ(S_OK, d3d9Device->GetDirect3D(&d3d9));
EXPECT_TRUE(d3d9 != nullptr);
@@ -406,22 +407,24 @@ TEST_P(EGLDeviceQueryTest, QueryDevice)
// If the test is confitured to use D3D9, then it should fail to obtain a D3D9 device.
TEST_P(EGLDeviceQueryTest, QueryDeviceBadAttribute)
{
- EGLAttrib device = 0;
EGLAttrib angleDevice = 0;
- if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ EXPECT_EGL_TRUE(
+ eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+
+ if (!IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ "EGL_ANGLE_device_d3d11"))
{
- EXPECT_EGL_TRUE(
- eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EGLAttrib device11 = 0;
EXPECT_EGL_FALSE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
- EGL_D3D9_DEVICE_ANGLE, &device));
+ EGL_D3D11_DEVICE_ANGLE, &device11));
}
- if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
+ if (!IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ "EGL_ANGLE_device_d3d9"))
{
- EXPECT_EGL_TRUE(
- eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+ EGLAttrib device9 = 0;
EXPECT_EGL_FALSE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
- EGL_D3D11_DEVICE_ANGLE, &device));
+ EGL_D3D9_DEVICE_ANGLE, &device9));
}
}
diff --git a/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp b/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp
index d098f86535..e413cff0f3 100644
--- a/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp
+++ b/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp
@@ -1293,6 +1293,73 @@ TEST_P(IOSurfaceClientBufferTest, ReadFromBGRX8888IOSurfaceWithTexBaseMaxLevelSe
});
}
+// Test that the following scenario works:
+// - change IOSurface bound texture's max level to 0.
+// - attach IOSurface bound texture to a FBO 1.
+// - bind FBO 1
+// - clear FBO 1 -> this should trigger render targets initialization in backends.
+// - bind FBO 0.
+// - draw IOSurface bound texture to FBO 0.
+// -> In the past, this could trigger the texture's render targets invalidation in metal backend.
+// See https://issues.chromium.org/issues/335353385
+// - bind FBO 1
+// - blit FBO 0 to FBO 1.
+// -> this will reconstruct render pass descriptor in metal backend.
+// - flush to restart render encoder with new render pass descriptor.
+// - draw.
+TEST_P(IOSurfaceClientBufferTest, SetMaxLevelWouldInvalidateRenderTargetBug)
+{
+ ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());
+ ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
+
+ ANGLE_GL_PROGRAM(blueProgram, angle::essl1_shaders::vs::Simple(),
+ angle::essl1_shaders::fs::Blue());
+
+ ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'BGRA', 4);
+
+ GLTexture texture;
+ glBindTexture(getGLTextureTarget(), texture);
+
+ // Bind the IOSurface to a texture.
+ EGLSurface pbuffer;
+ bindIOSurfaceToTexture(ioSurface, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &pbuffer, &texture);
+
+ // 1. Change the texture's max level to 0.
+ glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, 0);
+ EXPECT_GL_NO_ERROR();
+
+ // 2. Attach IOSurface bound texture to a FBO and clear it.
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ EXPECT_GL_NO_ERROR();
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getGLTextureTarget(), texture, 0);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // 3. Draw IOSurface bound texture to default FBO.
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ doSampleTestWithTexture(texture, R | G | B);
+
+ // 3. Draw to custom FBO again
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glClear(GL_COLOR_BUFFER_BIT);
+ // Using a blit is important: it will trigger render pass reconstruction in
+ // metal backend due to DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 dirty bit.
+ glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glFlush(); // flush so that render encoder will be recreated again in metal backend.
+ glUseProgram(blueProgram);
+ drawQuad(blueProgram, angle::essl1_shaders::PositionAttrib(), 0.5f);
+ glFlush();
+
+ // Expect the final color to be accumulated color
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(1, 2, 255, 255));
+}
+
// TODO(cwallez@chromium.org): Test setting width and height to less than the IOSurface's work as
// expected.
diff --git a/src/tests/egl_tests/EGLSyncTest.cpp b/src/tests/egl_tests/EGLSyncTest.cpp
index 7a6d7d26ae..cf3b3aa623 100644
--- a/src/tests/egl_tests/EGLSyncTest.cpp
+++ b/src/tests/egl_tests/EGLSyncTest.cpp
@@ -708,4 +708,16 @@ void main(void)
EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
}
+// Test that leaked fences are cleaned up in a safe way. Regression test for sync objects using tail
+// calls for destruction.
+TEST_P(EGLSyncTest, DISABLED_LeakSyncToDisplayDestruction)
+{
+ ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
+
+ EGLDisplay display = getEGLWindow()->getDisplay();
+
+ EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
+ EXPECT_NE(sync, EGL_NO_SYNC_KHR);
+}
+
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(EGLSyncTest);
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 58feeaf77b..43a58852c0 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -3512,6 +3512,26 @@ TEST_P(GLSLTest_ES3, InitGlobalArrayWithArrayIndexing)
EXPECT_NE(0u, program);
}
+// Test that constant global matrix array with an initializer compiles.
+TEST_P(GLSLTest_ES3, InitConstantMatrixArray)
+{
+ constexpr char kFS[] = R"(#version 300 es
+ precision highp float;
+ uniform int index;
+
+ const mat4 matrix = mat4(1.0);
+ const mat4 array[1] = mat4[1](matrix);
+ out vec4 my_FragColor;
+ void main() {
+ my_FragColor = vec4(array[index][1].rgb, 1.0);
+ })";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+
+ drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
// Test that index-constant sampler array indexing is supported.
TEST_P(GLSLTest, IndexConstantSamplerArrayIndexing)
{
@@ -19231,6 +19251,52 @@ Foo foo(float bar)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
+// Test that double underscores user defined name is allowed
+TEST_P(GLSLTest_ES3, DoubleUnderscoresName)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision mediump float;
+out vec4 oColor;
+uniform struct __Data {float red;} data;
+void main() {oColor=vec4(data.red,0,1,1);})";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+ glUseProgram(program);
+ // populate uniform
+ GLint uniformLocation = glGetUniformLocation(program, "data.red");
+ EXPECT_NE(uniformLocation, -1);
+ glUniform1f(uniformLocation, 0);
+
+ drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
+ ASSERT_GL_NO_ERROR();
+}
+
+// Test that user defined name starts with "ANGLE" or "ANGLE_"
+TEST_P(GLSLTest_ES3, VariableNameStartsWithANGLE)
+{
+ constexpr char kFS[] = R"(#version 300 es
+precision mediump float;
+out vec4 oColor;
+uniform struct ANGLEData{float red;} data;
+uniform struct ANGLE_Data{float green;} _data;
+void main() {oColor=vec4(data.red,_data.green,1,1);})";
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+ glUseProgram(program);
+ // populate uniform
+ GLint uniformRedLocation = glGetUniformLocation(program, "data.red");
+ GLint uniformGreenLocation = glGetUniformLocation(program, "_data.green");
+ EXPECT_NE(uniformRedLocation, -1);
+ EXPECT_NE(uniformGreenLocation, -1);
+ glUniform1f(uniformRedLocation, 0);
+ glUniform1f(uniformGreenLocation, 0);
+
+ drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
+ ASSERT_GL_NO_ERROR();
+}
+
// Test that underscores in array names work with out arrays.
TEST_P(GLSLTest_ES3, UnderscoresWorkWithOutArrays)
{
diff --git a/src/tests/gl_tests/MultithreadingTest.cpp b/src/tests/gl_tests/MultithreadingTest.cpp
index 869cb191f7..25711061ee 100644
--- a/src/tests/gl_tests/MultithreadingTest.cpp
+++ b/src/tests/gl_tests/MultithreadingTest.cpp
@@ -3847,6 +3847,254 @@ TEST_P(MultithreadingTest, ProgramLinkAndBind)
ASSERT_NE(currentStep, Step::Abort);
}
+// Test that two contexts in share group can generate, delete and bind buffers for themselves in
+// parallel.
+TEST_P(MultithreadingTestES3, SimultaneousBufferBindAndGen)
+{
+ ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
+
+ constexpr char kFS[] = R"(#version 300 es
+precision mediump float;
+
+layout(std140) uniform Block
+{
+ vec4 colorIn;
+};
+
+out vec4 color;
+
+void main()
+{
+ color = colorIn;
+})";
+
+ constexpr int kSurfaceWidth = 32;
+ constexpr int kSurfaceHeight = 128;
+
+ // Sync primitives
+ std::mutex mutex;
+ std::condition_variable condVar;
+
+ enum class Step
+ {
+ Start,
+ Thread0Ready,
+ Thread1Ready,
+ Finish,
+ Abort,
+ };
+ Step currentStep = Step::Start;
+
+ auto threadFunc = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context, uint32_t index) {
+ ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
+ EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+
+ // Make sure the two threads start work around the same time
+ if (index == 0)
+ {
+ threadSynchronization.nextStep(Step::Thread0Ready);
+ ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Ready));
+ }
+ else
+ {
+ ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Ready));
+ threadSynchronization.nextStep(Step::Thread1Ready);
+ }
+
+ std::vector<GLuint> buffers(kSurfaceWidth * kSurfaceHeight);
+
+ glEnable(GL_SCISSOR_TEST);
+ for (int y = 0; y < kSurfaceHeight; ++y)
+ {
+ for (int x = 0; x < kSurfaceWidth; ++x)
+ {
+ GLuint &buffer = buffers[y * kSurfaceWidth + x];
+ const float bufferData[4] = {
+ ((y * kSurfaceWidth + x + index * 100) % 255) / 255.0f,
+ ((y * kSurfaceWidth + x + index * 100 + 1) % 255) / 255.0f,
+ ((y * kSurfaceWidth + x + index * 100 + 2) % 255) / 255.0f,
+ ((y * kSurfaceWidth + x + index * 100 + 3) % 255) / 255.0f,
+ };
+
+ // Generate one buffer per pixel and shade the pixel with it.
+ glGenBuffers(1, &buffer);
+ glBindBuffer(GL_UNIFORM_BUFFER, buffers[y * kSurfaceWidth + x]);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
+
+ glScissor(x, y, 1, 1);
+ drawQuad(program, essl3_shaders::PositionAttrib(), 0);
+
+ if ((x + y) % 2 == 0)
+ {
+ glDeleteBuffers(1, &buffer);
+ buffer = 0;
+ }
+ }
+ }
+
+ // Verify the results
+ auto verify = [&](int x, int y) {
+ const GLColor expect((y * kSurfaceWidth + x + index * 100) % 255,
+ (y * kSurfaceWidth + x + index * 100 + 1) % 255,
+ (y * kSurfaceWidth + x + index * 100 + 2) % 255,
+ (y * kSurfaceWidth + x + index * 100 + 3) % 255);
+ EXPECT_PIXEL_COLOR_EQ(x, y, expect);
+ };
+
+ verify(0, 0);
+ verify(0, kSurfaceHeight - 1);
+ verify(kSurfaceWidth - 1, 0);
+ verify(kSurfaceWidth - 1, kSurfaceHeight - 1);
+ verify(kSurfaceWidth / 2, kSurfaceHeight / 2);
+ ASSERT_GL_NO_ERROR();
+
+ if (index == 0)
+ {
+ threadSynchronization.nextStep(Step::Finish);
+ }
+ else
+ {
+ ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
+ }
+ };
+
+ auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
+ threadFunc(dpy, surface, context, 0);
+ };
+ auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
+ threadFunc(dpy, surface, context, 1);
+ };
+
+ std::array<LockStepThreadFunc, 2> threadFuncs = {
+ std::move(thread0),
+ std::move(thread1),
+ };
+
+ RunLockStepThreadsWithSize(getEGLWindow(), kSurfaceWidth, kSurfaceHeight, threadFuncs.size(),
+ threadFuncs.data());
+
+ ASSERT_NE(currentStep, Step::Abort);
+}
+
+// Test that ref counting is thread-safe when the same buffer is used in multiple threads.
+TEST_P(MultithreadingTestES3, SimultaneousBufferBind)
+{
+ ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
+
+ constexpr char kFS[] = R"(#version 300 es
+precision mediump float;
+
+layout(std140) uniform Block
+{
+ vec4 colorIn;
+};
+
+out vec4 color;
+
+void main()
+{
+ color = colorIn;
+})";
+
+ constexpr int kSurfaceWidth = 32;
+ constexpr int kSurfaceHeight = 128;
+
+ GLuint buffer;
+ GLsync sync = nullptr;
+
+ // Sync primitives
+ std::mutex mutex;
+ std::condition_variable condVar;
+
+ enum class Step
+ {
+ Start,
+ Thread0Ready,
+ Thread1Ready,
+ Finish,
+ Abort,
+ };
+ Step currentStep = Step::Start;
+
+ auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
+ ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
+ EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+
+ // Create the buffer in this context
+ glGenBuffers(1, &buffer);
+
+ constexpr float kBufferData[4] = {
+ 10.0f / 255.0f,
+ 50.0f / 255.0f,
+ 130.0f / 255.0f,
+ 220.0f / 255.0f,
+ };
+ glBindBuffer(GL_UNIFORM_BUFFER, buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(kBufferData), kBufferData, GL_STATIC_DRAW);
+
+ sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+
+ // Make sure the two threads start work around the same time
+ threadSynchronization.nextStep(Step::Thread0Ready);
+ ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Ready));
+
+ // Bind and unbind the buffer many times. If ref counting is not thread safe, chances are
+ // the ref count would be incorrect in the end. This can result in the buffer prematurely
+ // getting deleted.
+ for (uint32_t i = 0; i < 8000; ++i)
+ {
+ glBindBuffer(GL_UNIFORM_BUFFER, i % 2 == 0 ? 0 : buffer);
+ }
+ ASSERT_GL_NO_ERROR();
+
+ ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
+ };
+ auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
+ ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
+ EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));
+
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
+
+ ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Ready));
+ threadSynchronization.nextStep(Step::Thread1Ready);
+
+ glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
+
+ // Bind and unbind the buffer many times.
+ for (uint32_t i = 0; i < 4000; ++i)
+ {
+ glBindBuffer(GL_UNIFORM_BUFFER, i % 2 == 0 ? buffer : 0);
+ }
+
+ // Draw with it to make sure buffer is still valid and not accidentally deleted due to bad
+ // ref counting.
+ glBindBuffer(GL_UNIFORM_BUFFER, buffer);
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
+ drawQuad(program, essl3_shaders::PositionAttrib(), 0);
+
+ // Verify the results
+ const GLColor expect(10, 50, 130, 220);
+ EXPECT_PIXEL_RECT_EQ(0, 0, kSurfaceWidth, kSurfaceHeight, expect);
+ ASSERT_GL_NO_ERROR();
+
+ threadSynchronization.nextStep(Step::Finish);
+ };
+
+ std::array<LockStepThreadFunc, 2> threadFuncs = {
+ std::move(thread0),
+ std::move(thread1),
+ };
+
+ RunLockStepThreadsWithSize(getEGLWindow(), kSurfaceWidth, kSurfaceHeight, threadFuncs.size(),
+ threadFuncs.data());
+
+ ASSERT_NE(currentStep, Step::Abort);
+}
ANGLE_INSTANTIATE_TEST(
MultithreadingTest,
ES2_OPENGL(),
diff --git a/src/tests/gl_tests/RobustResourceInitTest.cpp b/src/tests/gl_tests/RobustResourceInitTest.cpp
index f38a0f99f4..1a1922bc53 100644
--- a/src/tests/gl_tests/RobustResourceInitTest.cpp
+++ b/src/tests/gl_tests/RobustResourceInitTest.cpp
@@ -2235,25 +2235,6 @@ TEST_P(RobustResourceInitTestES31, Multisample2DTextureArray)
}
}
-// Tests that using an out of bounds draw offset with a dynamic array succeeds.
-TEST_P(RobustResourceInitTest, DynamicVertexArrayOffsetOutOfBounds)
-{
- ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
- glUseProgram(program);
-
- GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
- ASSERT_NE(-1, posLoc);
-
- glEnableVertexAttribArray(posLoc);
- GLBuffer buf;
- glBindBuffer(GL_ARRAY_BUFFER, buf);
- glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const void *>(500));
- glBufferData(GL_ARRAY_BUFFER, 100, nullptr, GL_DYNAMIC_DRAW);
- glDrawArrays(GL_TRIANGLES, 0, 3);
-
- // Either no error or invalid operation is okay.
-}
-
// Test to cover a bug that the multisampled depth attachment of a framebuffer are not successfully
// initialized before it is used as the read framebuffer in blitFramebuffer.
// Referenced from the following WebGL CTS:
diff --git a/src/tests/gl_tests/ShaderAlgorithmTest.cpp b/src/tests/gl_tests/ShaderAlgorithmTest.cpp
index e2a5ca0d3b..4ec785c7cb 100644
--- a/src/tests/gl_tests/ShaderAlgorithmTest.cpp
+++ b/src/tests/gl_tests/ShaderAlgorithmTest.cpp
@@ -118,7 +118,7 @@ TEST_P(ShaderAlgorithmTest, rgb_to_hsl_vertex_shader)
ASSERT_GL_NO_ERROR();
- float maxVal = std::max(sx, std::max(sy, 0.33f * sx + 0.5f * sy));
+ float maxVal = std::max({sx, sy, 0.33f * sx + 0.5f * sy});
if (abs(maxVal - sx) <= epsilon)
{
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
diff --git a/src/tests/gl_tests/StateChangeTest.cpp b/src/tests/gl_tests/StateChangeTest.cpp
index ed0e19fa00..4881115c8c 100644
--- a/src/tests/gl_tests/StateChangeTest.cpp
+++ b/src/tests/gl_tests/StateChangeTest.cpp
@@ -8056,22 +8056,6 @@ TEST_P(SimpleStateChangeTestES3, InvalidateFramebufferShouldntInvalidateReadFram
EXPECT_GL_NO_ERROR();
}
-// Covers situations where vertex conversion could read out of bounds.
-TEST_P(SimpleStateChangeTestES3, OutOfBoundsByteAttribute)
-{
- ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
- glUseProgram(testProgram);
-
- GLBuffer buffer;
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(GL_ARRAY_BUFFER, 2, nullptr, GL_STREAM_COPY);
-
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 4, GL_BYTE, false, 0xff, reinterpret_cast<const void *>(0xfe));
-
- glDrawArraysInstanced(GL_TRIANGLE_STRIP, 1, 10, 1000);
-}
-
// Test that respecifies a buffer after we start XFB.
TEST_P(SimpleStateChangeTestES3, RespecifyBufferAfterBeginTransformFeedback)
{
diff --git a/src/tests/gl_tests/VertexAttributeTest.cpp b/src/tests/gl_tests/VertexAttributeTest.cpp
index a1572e05d0..1b1d6c4555 100644
--- a/src/tests/gl_tests/VertexAttributeTest.cpp
+++ b/src/tests/gl_tests/VertexAttributeTest.cpp
@@ -4507,43 +4507,6 @@ void main()
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
}
-// Test that vertex conversion correctly no-ops when the vertex format requires conversion but there
-// are no vertices to convert.
-TEST_P(VertexAttributeTest, ConversionWithNoVertices)
-{
- constexpr char kVS[] = R"(precision highp float;
-attribute vec3 attr1;
-void main(void) {
- gl_Position = vec4(attr1, 1.0);
-})";
-
- constexpr char kFS[] = R"(precision highp float;
-void main(void) {
- gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
-})";
-
- GLBuffer buffer;
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- std::array<int8_t, 12> data = {
- 1,
- };
- glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(data[0]), data.data(), GL_STATIC_DRAW);
-
- ANGLE_GL_PROGRAM(program, kVS, kFS);
- glBindAttribLocation(program, 0, "attr1");
- glLinkProgram(program);
- ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
- glUseProgram(program);
-
- // Set the offset the athe attribute past the end of the buffer but use a format that requires
- // conversion in Vulkan
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_BYTE, true, 128, reinterpret_cast<void *>(256));
-
- glDrawArrays(GL_TRIANGLES, 0, 3);
- EXPECT_GL_NO_ERROR();
-}
-
// Test that pipeline is recreated properly when switching from ARRAY buffer to client buffer,
// while removing client buffer. Bug observed in Dragonmania game.
TEST_P(VertexAttributeTestES31, ArrayToClientBufferStride)
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 028e11767d..4062cf844c 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -6365,6 +6365,78 @@ void main() {
}
}
+// Test that vertex conversion correctly no-ops when the vertex format requires conversion but there
+// are no vertices to convert.
+TEST_P(WebGLCompatibilityTest, ConversionWithNoVertices)
+{
+ constexpr char kVS[] = R"(precision highp float;
+attribute vec3 attr1;
+void main(void) {
+ gl_Position = vec4(attr1, 1.0);
+})";
+
+ constexpr char kFS[] = R"(precision highp float;
+void main(void) {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+})";
+
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ std::array<int8_t, 12> data = {
+ 1,
+ };
+ glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(data[0]), data.data(), GL_STATIC_DRAW);
+
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
+ glBindAttribLocation(program, 0, "attr1");
+ glLinkProgram(program);
+ ASSERT_TRUE(CheckLinkStatusAndReturnProgram(program, true));
+ glUseProgram(program);
+
+ // Set the offset of the attribute past the end of the buffer but use a format that requires
+ // conversion in Vulkan
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_BYTE, true, 128, reinterpret_cast<void *>(256));
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ // Either no error or invalid operation is okay.
+}
+
+// Tests that using an out of bounds draw offset with a dynamic array succeeds.
+TEST_P(WebGLCompatibilityTest, DynamicVertexArrayOffsetOutOfBounds)
+{
+ ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
+ glUseProgram(program);
+
+ GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
+ ASSERT_NE(-1, posLoc);
+
+ glEnableVertexAttribArray(posLoc);
+ GLBuffer buf;
+ glBindBuffer(GL_ARRAY_BUFFER, buf);
+ glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<const void *>(500));
+ glBufferData(GL_ARRAY_BUFFER, 100, nullptr, GL_DYNAMIC_DRAW);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ // Either no error or invalid operation is okay.
+}
+
+// Covers situations where vertex conversion could read out of bounds.
+TEST_P(WebGL2CompatibilityTest, OutOfBoundsByteAttribute)
+{
+ ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
+ glUseProgram(testProgram);
+
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ glBufferData(GL_ARRAY_BUFFER, 2, nullptr, GL_STREAM_COPY);
+
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 4, GL_BYTE, false, 0xff, reinterpret_cast<const void *>(0xfe));
+
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 1, 10, 1000);
+}
+
// Test for a mishandling of instanced vertex attributes with zero-sized buffers bound on Apple
// OpenGL drivers.
TEST_P(WebGL2CompatibilityTest, DrawWithZeroSizedBuffer)
diff --git a/src/tests/perf_tests/TracePerfTest.cpp b/src/tests/perf_tests/TracePerfTest.cpp
index ccc98b9792..567f92e49c 100644
--- a/src/tests/perf_tests/TracePerfTest.cpp
+++ b/src/tests/perf_tests/TracePerfTest.cpp
@@ -848,9 +848,9 @@ TracePerfTest::TracePerfTest(std::unique_ptr<const TracePerfParams> params)
mStartFrame(0),
mEndFrame(0)
{
- bool isAMD = IsAMD() && !mParams->isSwiftshader();
- bool isAMDLinux = isAMD && IsLinux();
- // bool isAMDLinuxANGLE = isAMDLinux && mParams->isANGLE();
+ bool isAMD = IsAMD() && !mParams->isSwiftshader();
+ bool isAMDLinux = isAMD && IsLinux();
+ bool isAMDLinuxANGLE = isAMDLinux && mParams->isANGLE();
bool isAMDLinuxNative = isAMDLinux && !mParams->isANGLE();
bool isAMDWin = isAMD && IsWindows();
bool isAMDWinANGLE = isAMDWin && mParams->isANGLE();
@@ -1497,6 +1497,10 @@ TracePerfTest::TracePerfTest(std::unique_ptr<const TracePerfParams> params)
if (traceNameIs("antutu_refinery"))
{
+ if (isIntelLinuxANGLE || isAMDLinuxANGLE)
+ {
+ skipTest("https://anglebug.com/342545097 fails on Mesa 23.2.1");
+ }
addExtensionPrerequisite("GL_ANDROID_extension_pack_es31a");
}
diff --git a/testing b/testing
-Subproject a2a6e48c98e5e5869e822b542e935514d843c43
+Subproject 940cfd4db1dfb7712cb94d68f19e476f6ed6e3a
diff --git a/third_party/SwiftShader b/third_party/SwiftShader
-Subproject da334852e70510d259bfa8cbaa7c5412966b2f4
+Subproject 90519141a709a92db90640b52176aaf82942e93
diff --git a/third_party/VK-GL-CTS/src b/third_party/VK-GL-CTS/src
-Subproject 9d7b4c3d553331e316321942e2eb8413e4081c7
+Subproject fd5cc7b1e07578e8e807696034ab894b134f428
diff --git a/third_party/abseil-cpp b/third_party/abseil-cpp
-Subproject 31bdf8fec41f04dfe86976734cbad22ded4ca1f
+Subproject b027bd3c0b3ce035c8da06a78e7ab8db2d5c444
diff --git a/third_party/android_deps b/third_party/android_deps
-Subproject 36a6c64282adbe58f343d9c0cbdf45d0e6402db
+Subproject 2888a739e9b8b8514807a5a0d8b26f91a7e4e91
diff --git a/third_party/catapult b/third_party/catapult
-Subproject 47d3198a953f28d06b46bb6f9293b4e0b384d15
+Subproject ec40c25bd83f043ebc76fb368414016b0515675
diff --git a/third_party/clspv/BUILD.gn b/third_party/clspv/BUILD.gn
index 90770466c5..8b266473d3 100644
--- a/third_party/clspv/BUILD.gn
+++ b/third_party/clspv/BUILD.gn
@@ -222,7 +222,7 @@ source_set("clspv_passes") {
":clspv_reflection",
"gn/llvm/config:llvm-config",
"gn/llvm/sources:clspv_llvm_components",
- "//third_party/vulkan-deps/spirv-headers/src:spv_headers",
+ "//third_party/spirv-headers/src:spv_headers",
]
configs += [
@@ -359,7 +359,7 @@ executable("clspv-reflection") {
":clspv_core",
":clspv_reflection",
"${spirv_tools_dir}:spvtools_link",
- "//third_party/vulkan-deps/spirv-headers/src:spv_headers",
+ "//third_party/spirv-headers/src:spv_headers",
]
include_dirs = [
diff --git a/third_party/dawn b/third_party/dawn
-Subproject 5406e9dfbe0ba766e5a7571e1ad7c2dc48ad57e
+Subproject d32858a3045a89e8c5ff919107ee76c8b103afd
diff --git a/third_party/depot_tools b/third_party/depot_tools
-Subproject df437783c243fef294e6af2e44de383e751a376
+Subproject 09c232e7c0d5670695d1f8f70d05ed1a215e438
diff --git a/third_party/flatbuffers/DIR_METADATA b/third_party/flatbuffers/DIR_METADATA
index 637eb4dc77..f34553f340 100644
--- a/third_party/flatbuffers/DIR_METADATA
+++ b/third_party/flatbuffers/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
component: "Platform>Extensions>API"
}
+buganizer_public: {
+ component_id: 1456781
+}
diff --git a/third_party/flatbuffers/README.chromium b/third_party/flatbuffers/README.chromium
index b45064f841..47669af672 100644
--- a/third_party/flatbuffers/README.chromium
+++ b/third_party/flatbuffers/README.chromium
@@ -1,8 +1,8 @@
Name: FlatBuffers
Short Name: flatbuffers
URL: https://github.com/google/flatbuffers
-Version: bcb9ef187628fe07514e57756d05e6a6296f7dc5
-Date: 2023-10-03
+Version: c696275eaffec33796b5ca8755614fd9fec0a6a7
+Date: 2024-05-09
License: Apache 2.0
License File: LICENSE
Security Critical: yes
diff --git a/third_party/flatbuffers/generated/tests/alignment_test_generated.h b/third_party/flatbuffers/generated/tests/alignment_test_generated.h
index a23479e2c6..e123300e28 100644
--- a/third_party/flatbuffers/generated/tests/alignment_test_generated.h
+++ b/third_party/flatbuffers/generated/tests/alignment_test_generated.h
@@ -7,8 +7,8 @@
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
-static_assert(FLATBUFFERS_VERSION_MAJOR == 23 && FLATBUFFERS_VERSION_MINOR == 5 &&
- FLATBUFFERS_VERSION_REVISION == 26,
+static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && FLATBUFFERS_VERSION_MINOR == 3 &&
+ FLATBUFFERS_VERSION_REVISION == 25,
"Non-compatible flatbuffers version included");
struct BadAlignmentSmall;
diff --git a/third_party/flatbuffers/generated/tests/arrays_test_generated.h b/third_party/flatbuffers/generated/tests/arrays_test_generated.h
index 45e5f2475a..f2264df536 100644
--- a/third_party/flatbuffers/generated/tests/arrays_test_generated.h
+++ b/third_party/flatbuffers/generated/tests/arrays_test_generated.h
@@ -7,8 +7,8 @@
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
-static_assert(FLATBUFFERS_VERSION_MAJOR == 23 && FLATBUFFERS_VERSION_MINOR == 5 &&
- FLATBUFFERS_VERSION_REVISION == 26,
+static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && FLATBUFFERS_VERSION_MINOR == 3 &&
+ FLATBUFFERS_VERSION_REVISION == 25,
"Non-compatible flatbuffers version included");
namespace MyGame
diff --git a/third_party/flatbuffers/src b/third_party/flatbuffers/src
-Subproject bcb9ef187628fe07514e57756d05e6a6296f7dc
+Subproject 150644d7f4d030a0629c564fd90dc3becab7763
diff --git a/third_party/glslang/DIR_METADATA b/third_party/glslang/DIR_METADATA
new file mode 100644
index 0000000000..348e5424b5
--- /dev/null
+++ b/third_party/glslang/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail {
+ component: "Internals>GPU>Internals"
+}
+team_email: "graphics-dev@chromium.org"
diff --git a/third_party/glslang/LICENSE b/third_party/glslang/LICENSE
new file mode 100644
index 0000000000..8b2e82136b
--- /dev/null
+++ b/third_party/glslang/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2015-2016 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
+KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
+SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
+ https://www.khronos.org/registry/
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
diff --git a/third_party/glslang/README.chromium b/third_party/glslang/README.chromium
new file mode 100644
index 0000000000..7c3e05ab69
--- /dev/null
+++ b/third_party/glslang/README.chromium
@@ -0,0 +1,16 @@
+Name: Khronos reference front-end for GLSL and ESSL
+Short Name: glslang
+URL: https://github.com/KhronosGroup/glslang
+Version: Unknown
+Security Critical: yes
+Shipped: no
+License: MIT
+License File: LICENSE
+
+Description:
+An OpenGL and OpenGL ES shader front end and validator.
+
+Local Modifications:
+Added OWNERS, README.chromium.
+Ported build rules from CMake to GN.
+5/13/2016 - Updated GN build rules to include new files added in repository.
diff --git a/third_party/glslang/src b/third_party/glslang/src
new file mode 160000
+Subproject 7c3c50ea94354d06dc8c280de8b8a5d5aacbbb1
diff --git a/third_party/libc++/src b/third_party/libc++/src
-Subproject e3b94d0e5b86883fd77696bf10dc33ba250ba99
+Subproject 852bc6746f45add53fec19f3a29280e69e358d4
diff --git a/third_party/libc++abi/src b/third_party/libc++abi/src
-Subproject d17298ab09b44bbc95e5e59c0f285145d0e5f8a
+Subproject ba370858669b1e905db5ded82c8887095b61dc1
diff --git a/third_party/libunwind/src b/third_party/libunwind/src
-Subproject 419b03c0b8f20d6da9ddcb0d661a94a97cdd7da
+Subproject e0a4f3561e7f7ce10573917b60c7027e3b599e6
diff --git a/third_party/spirv-cross/DIR_METADATA b/third_party/spirv-cross/DIR_METADATA
new file mode 100644
index 0000000000..e353adfc5e
--- /dev/null
+++ b/third_party/spirv-cross/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail: {
+ component: "Internals>GPU>Internals"
+}
+team_email: "graphics-dev@chromium.org"
diff --git a/third_party/spirv-cross/README.chromium b/third_party/spirv-cross/README.chromium
new file mode 100644
index 0000000000..42c1f1502a
--- /dev/null
+++ b/third_party/spirv-cross/README.chromium
@@ -0,0 +1,13 @@
+Name: SPIRV-Cross
+Short Name: SPIRV-Cross
+URL: https://github.com/KhronosGroup/SPIRV-Cross
+Version: Unknown
+Security Critical: yes
+Shipped: no
+License: Apache 2.0
+License File: src/LICENSE
+
+Description:
+A translator from SPIR-V bytecode to other shading languages like GLSL, HLSL
+and MSL. This project is not secure (yet!) and should only be used for
+prototyping, and not shipped to users.
diff --git a/third_party/spirv-cross/src b/third_party/spirv-cross/src
new file mode 160000
+Subproject b8fcf307f1f347089e3c46eb4451d27f32ebc8d
diff --git a/third_party/spirv-headers/DIR_METADATA b/third_party/spirv-headers/DIR_METADATA
new file mode 100644
index 0000000000..e353adfc5e
--- /dev/null
+++ b/third_party/spirv-headers/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail: {
+ component: "Internals>GPU>Internals"
+}
+team_email: "graphics-dev@chromium.org"
diff --git a/third_party/spirv-headers/LICENSE b/third_party/spirv-headers/LICENSE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/spirv-headers/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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
+
+ http://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.
diff --git a/third_party/spirv-headers/README.chromium b/third_party/spirv-headers/README.chromium
new file mode 100644
index 0000000000..758a714920
--- /dev/null
+++ b/third_party/spirv-headers/README.chromium
@@ -0,0 +1,15 @@
+Name: SPIR-V Headers
+Short Name: spirv-headers
+URL: https://github.com/KhronosGroup/SPIRV-Headers.git
+Version: unknown
+Security Critical: yes
+Shipped: yes
+License: MIT
+License File: LICENSE
+
+Description:
+This repository contains machine-readable files from the SPIR-V Registry. This includes:
+
+* Header files for various languages.
+* JSON files describing the grammar for the SPIR-V core instruction set, and for the GLSL.std.450 extended instruction set.
+* The XML registry file.
diff --git a/third_party/spirv-headers/src b/third_party/spirv-headers/src
new file mode 160000
+Subproject 49a1fceb9b1d087f3c25ad5ec077bb0e4623129
diff --git a/third_party/spirv-tools/DIR_METADATA b/third_party/spirv-tools/DIR_METADATA
new file mode 100644
index 0000000000..376e2293f3
--- /dev/null
+++ b/third_party/spirv-tools/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+ component: "Internals>GPU>Internals"
+}
+
+team_email: "graphics-dev@chromium.org"
diff --git a/third_party/spirv-tools/LICENSE b/third_party/spirv-tools/LICENSE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/spirv-tools/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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
+
+ http://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.
diff --git a/third_party/spirv-tools/README.chromium b/third_party/spirv-tools/README.chromium
new file mode 100644
index 0000000000..a2d18d7e4d
--- /dev/null
+++ b/third_party/spirv-tools/README.chromium
@@ -0,0 +1,16 @@
+Name: SPIR-V Tools
+Short Name: SPIRV-Tools
+URL: https://github.com/KhronosGroup/SPIRV-Tools.git
+Version: Unknown
+Security Critical: yes
+Shipped: yes
+License: Apache 2.0
+License File: LICENSE
+
+Description:
+The SPIR-V Tools project provides an API and commands for processing
+SPIR-V modules.
+
+Local Modifications:
+Added OWNERS, README.chromium.
+Ported build rules from CMake to GN.
diff --git a/third_party/spirv-tools/src b/third_party/spirv-tools/src
new file mode 160000
+Subproject 77c40bece1b8b441eee432fc9d74efbf985f777
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps
-Subproject 643408ea2a0685352d831a97601997c9ea246f6
+Subproject feb3ce48e50956465d171e37c548bb8e44a30ef
diff --git a/third_party/vulkan-headers/DIR_METADATA b/third_party/vulkan-headers/DIR_METADATA
new file mode 100644
index 0000000000..e353adfc5e
--- /dev/null
+++ b/third_party/vulkan-headers/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail: {
+ component: "Internals>GPU>Internals"
+}
+team_email: "graphics-dev@chromium.org"
diff --git a/third_party/vulkan-headers/LICENSE.txt b/third_party/vulkan-headers/LICENSE.txt
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/vulkan-headers/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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
+
+ http://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.
diff --git a/third_party/vulkan-headers/README.chromium b/third_party/vulkan-headers/README.chromium
new file mode 100644
index 0000000000..947684c776
--- /dev/null
+++ b/third_party/vulkan-headers/README.chromium
@@ -0,0 +1,12 @@
+Name: Vulkan API headers
+Short Name: Vulkan
+URL: https://github.com/KhronosGroup/Vulkan-Headers
+Version: 1.2.140
+Revision: 9250d5ae8f50202005233dc0512a1d460c8b4833
+Security Critical: yes
+Shipped: yes
+License: Apache 2.0
+License File: LICENSE.txt
+
+Description:
+Vulkan Header files and API registry
diff --git a/third_party/vulkan-headers/src b/third_party/vulkan-headers/src
new file mode 160000
+Subproject 5677bafb820e476441e9e1f745371b72133407d
diff --git a/third_party/vulkan-loader/README.chromium b/third_party/vulkan-loader/README.chromium
new file mode 100644
index 0000000000..654ff3b446
--- /dev/null
+++ b/third_party/vulkan-loader/README.chromium
@@ -0,0 +1,16 @@
+Name: Vulkan Loader Components
+Short Name: Vulkan Loader
+Version: N/A
+URL: https://github.com/KhronosGroup/Vulkan-Loader
+SOURCE CODE: git clone https://github.com/KhronosGroup/Vulkan-Loader.git
+Revision: HEAD
+Security Critical: no
+Shipped: yes
+License: Apache 2.0
+License File: src/LICENSE.txt
+
+Description:
+The Vulkan Loader Components are used to build the open-source desktop Vulkan loader. The loader
+is a library that loads the Vulkan entry points and hooks them into the correct layers and the
+client driver (ICD). This is required for using Vulkan layers and applications.
+
diff --git a/third_party/vulkan-loader/src b/third_party/vulkan-loader/src
new file mode 160000
+Subproject d3d530c90dd6549bcfc7cfaedd3ff85fe8ff04a
diff --git a/third_party/vulkan-tools/README.chromium b/third_party/vulkan-tools/README.chromium
new file mode 100644
index 0000000000..ccf51ffcde
--- /dev/null
+++ b/third_party/vulkan-tools/README.chromium
@@ -0,0 +1,15 @@
+Name: Khronos Vulkan Tools Components
+Short Name: Vulkan Tools
+Version: N/A
+URL: https://github.com/KhronosGroup/Vulkan-Tools
+SOURCE CODE: git clone https://github.com/KhronosGroup/Vulkan-Tools.git
+Revision: HEAD
+Security Critical: no
+Shipped: no
+License: Apache 2.0
+License File: src/LICENSE.txt
+
+Description:
+The Khronos Vulkan Tools Components contain the Vulkan Mock Installable
+Client Driver (ICD) as well as the vulkaninfo utility.
+
diff --git a/third_party/vulkan-tools/src b/third_party/vulkan-tools/src
new file mode 160000
+Subproject d67a9d3a394e11c1c4c0f480124f5b7925cb1b4
diff --git a/third_party/vulkan-utility-libraries/README.chromium b/third_party/vulkan-utility-libraries/README.chromium
new file mode 100644
index 0000000000..64528cbc03
--- /dev/null
+++ b/third_party/vulkan-utility-libraries/README.chromium
@@ -0,0 +1,15 @@
+Name: Khronos Vulkan Utility Libraries
+Short Name: Vulkan Utility Libraries
+Version: N/A
+URL: https://github.com/KhronosGroup/Vulkan-Utility-Libraries
+SOURCE CODE: git clone https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
+Revision: HEAD
+Security Critical: no
+Shipped: no
+License: Apache 2.0
+License File: src/LICENSE.md
+
+Description:
+
+The Khronos Vulkan Utility Libraries contains the layer settings library and
+miscellaneous utility headers for Vulkan developers.
diff --git a/third_party/vulkan-utility-libraries/src b/third_party/vulkan-utility-libraries/src
new file mode 160000
+Subproject f6c54531066c6d28ef403b50ff9cff3ea195d28
diff --git a/third_party/vulkan-validation-layers/README.chromium b/third_party/vulkan-validation-layers/README.chromium
new file mode 100644
index 0000000000..1c5714b315
--- /dev/null
+++ b/third_party/vulkan-validation-layers/README.chromium
@@ -0,0 +1,18 @@
+Name: Khronos Vulkan Validation Layers Components
+Short Name: Vulkan Validation Layers
+Version: N/A
+URL: https://github.com/KhronosGroup/Vulkan-ValidationLayers
+SOURCE CODE: git clone https://github.com/KhronosGroup/Vulkan-ValidationLayers.git
+Revision: HEAD
+Security Critical: no
+Shipped: no
+License: Apache 2.0
+License File: src/LICENSE.txt
+
+Description:
+The Khronos Vulkan Validation Layers Components consist of the Vulkan
+Validation Layers. The layers help validate Vulkan programs at runtime
+for development. When enabled the Vulkan loader will hook the layers
+into the Vulkan APIs so that they evaluate Vulkan API calls and flag
+the incorrect use of the API with callbacks. The layers are essential
+for developing Vulkan applications.
diff --git a/third_party/vulkan-validation-layers/src b/third_party/vulkan-validation-layers/src
new file mode 160000
+Subproject b25dea41d4a441268745ed9a83f82757170ec45
diff --git a/third_party/zlib b/third_party/zlib
-Subproject 7d77fb7fd66d8a5640618ad32c71fdeb7d3e02d
+Subproject 209717dd69cd62f24cbacc4758261ae2dd78cfa
diff --git a/tools/android b/tools/android
-Subproject cc51a5ea8611565ff48db1a11c08e90d03484bd
+Subproject 34192533e15dd37bd3c91910247fb925d1e1532
diff --git a/tools/clang b/tools/clang
-Subproject 964cf5c799c2284d52a88b1a516481852e7a216
+Subproject 9772a0a3490ed8f5977babbb01182944b44d3ea
diff --git a/tools/mb b/tools/mb
-Subproject 54a120d570f317c69bb155481629e2121df7554
+Subproject 973c25352084d231639ecd6f110e8343e203def
diff --git a/tools/perf b/tools/perf
-Subproject 7ef4ff5ba36be22f641d0f08f34402f85db1849
+Subproject ce2f1c1daa5716c697105213772e13be838ee44
diff --git a/util/android/third_party/android_native_app_glue.c b/util/android/third_party/android_native_app_glue.c
index ad9c55816e..934e2f2b2a 100644
--- a/util/android/third_party/android_native_app_glue.c
+++ b/util/android/third_party/android_native_app_glue.c
@@ -12,18 +12,17 @@
* 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.
- *
*/
+#include "android_native_app_glue.h"
+
#include <jni.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <sys/resource.h>
-#include "android_native_app_glue.h"
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
@@ -48,17 +47,12 @@ static void free_saved_state(struct android_app* android_app) {
int8_t android_app_read_cmd(struct android_app* android_app) {
int8_t cmd;
- if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
- switch (cmd) {
- case APP_CMD_SAVE_STATE:
- free_saved_state(android_app);
- break;
- }
- return cmd;
- } else {
+ if (read(android_app->msgread, &cmd, sizeof(cmd)) != sizeof(cmd)) {
LOGE("No data on command pipe!");
+ return -1;
}
- return -1;
+ if (cmd == APP_CMD_SAVE_STATE) free_saved_state(android_app);
+ return cmd;
}
static void print_cur_config(struct android_app* android_app) {
@@ -89,7 +83,7 @@ static void print_cur_config(struct android_app* android_app) {
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_INPUT_CHANGED:
- LOGV("APP_CMD_INPUT_CHANGED\n");
+ LOGV("APP_CMD_INPUT_CHANGED");
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL) {
AInputQueue_detachLooper(android_app->inputQueue);
@@ -106,7 +100,7 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
break;
case APP_CMD_INIT_WINDOW:
- LOGV("APP_CMD_INIT_WINDOW\n");
+ LOGV("APP_CMD_INIT_WINDOW");
pthread_mutex_lock(&android_app->mutex);
android_app->window = android_app->pendingWindow;
pthread_cond_broadcast(&android_app->cond);
@@ -114,7 +108,7 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
break;
case APP_CMD_TERM_WINDOW:
- LOGV("APP_CMD_TERM_WINDOW\n");
+ LOGV("APP_CMD_TERM_WINDOW");
pthread_cond_broadcast(&android_app->cond);
break;
@@ -122,7 +116,7 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
case APP_CMD_START:
case APP_CMD_PAUSE:
case APP_CMD_STOP:
- LOGV("activityState=%d\n", cmd);
+ LOGV("activityState=%d", cmd);
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
@@ -130,14 +124,14 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
break;
case APP_CMD_CONFIG_CHANGED:
- LOGV("APP_CMD_CONFIG_CHANGED\n");
+ LOGV("APP_CMD_CONFIG_CHANGED");
AConfiguration_fromAssetManager(android_app->config,
android_app->activity->assetManager);
print_cur_config(android_app);
break;
case APP_CMD_DESTROY:
- LOGV("APP_CMD_DESTROY\n");
+ LOGV("APP_CMD_DESTROY");
android_app->destroyRequested = 1;
break;
}
@@ -146,7 +140,7 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_TERM_WINDOW:
- LOGV("APP_CMD_TERM_WINDOW\n");
+ LOGV("APP_CMD_TERM_WINDOW");
pthread_mutex_lock(&android_app->mutex);
android_app->window = NULL;
pthread_cond_broadcast(&android_app->cond);
@@ -154,7 +148,7 @@ void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
break;
case APP_CMD_SAVE_STATE:
- LOGV("APP_CMD_SAVE_STATE\n");
+ LOGV("APP_CMD_SAVE_STATE");
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 1;
pthread_cond_broadcast(&android_app->cond);
@@ -188,7 +182,7 @@ static void android_app_destroy(struct android_app* android_app) {
static void process_input(struct android_app* app, struct android_poll_source* source) {
AInputEvent* event = NULL;
while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
- LOGV("New input event: type=%d\n", AInputEvent_getType(event));
+ LOGV("New input event: type=%d", AInputEvent_getType(event));
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
continue;
}
@@ -241,9 +235,8 @@ static void* android_app_entry(void* param) {
// --------------------------------------------------------------------
static struct android_app* android_app_create(ANativeActivity* activity,
- void* savedState, size_t savedStateSize) {
- struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app));
- memset(android_app, 0, sizeof(struct android_app));
+ void* savedState, size_t savedStateSize) {
+ struct android_app* android_app = calloc(1, sizeof(struct android_app));
android_app->activity = activity;
pthread_mutex_init(&android_app->mutex, NULL);
@@ -280,7 +273,7 @@ static struct android_app* android_app_create(ANativeActivity* activity,
static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
- LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
+ LOGE("Failure writing android_app cmd: %s", strerror(errno));
}
}
@@ -333,26 +326,30 @@ static void android_app_free(struct android_app* android_app) {
free(android_app);
}
+static struct android_app* ToApp(ANativeActivity* activity) {
+ return (struct android_app*) activity->instance;
+}
+
static void onDestroy(ANativeActivity* activity) {
- LOGV("Destroy: %p\n", activity);
- android_app_free((struct android_app*)activity->instance);
+ LOGV("Destroy: %p", activity);
+ android_app_free(ToApp(activity));
}
static void onStart(ANativeActivity* activity) {
- LOGV("Start: %p\n", activity);
- android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START);
+ LOGV("Start: %p", activity);
+ android_app_set_activity_state(ToApp(activity), APP_CMD_START);
}
static void onResume(ANativeActivity* activity) {
- LOGV("Resume: %p\n", activity);
- android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME);
+ LOGV("Resume: %p", activity);
+ android_app_set_activity_state(ToApp(activity), APP_CMD_RESUME);
}
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
- struct android_app* android_app = (struct android_app*)activity->instance;
- void* savedState = NULL;
+ LOGV("SaveInstanceState: %p", activity);
- LOGV("SaveInstanceState: %p\n", activity);
+ struct android_app* android_app = ToApp(activity);
+ void* savedState = NULL;
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 0;
android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
@@ -373,69 +370,89 @@ static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
}
static void onPause(ANativeActivity* activity) {
- LOGV("Pause: %p\n", activity);
- android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE);
+ LOGV("Pause: %p", activity);
+ android_app_set_activity_state(ToApp(activity), APP_CMD_PAUSE);
}
static void onStop(ANativeActivity* activity) {
- LOGV("Stop: %p\n", activity);
- android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP);
+ LOGV("Stop: %p", activity);
+ android_app_set_activity_state(ToApp(activity), APP_CMD_STOP);
}
static void onConfigurationChanged(ANativeActivity* activity) {
- struct android_app* android_app = (struct android_app*)activity->instance;
- LOGV("ConfigurationChanged: %p\n", activity);
- android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
+ LOGV("ConfigurationChanged: %p", activity);
+ android_app_write_cmd(ToApp(activity), APP_CMD_CONFIG_CHANGED);
+}
+
+static void onContentRectChanged(ANativeActivity* activity, const ARect* r) {
+ LOGV("ContentRectChanged: l=%d,t=%d,r=%d,b=%d", r->left, r->top, r->right, r->bottom);
+ struct android_app* android_app = ToApp(activity);
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->contentRect = *r;
+ pthread_mutex_unlock(&android_app->mutex);
+ android_app_write_cmd(ToApp(activity), APP_CMD_CONTENT_RECT_CHANGED);
}
static void onLowMemory(ANativeActivity* activity) {
- struct android_app* android_app = (struct android_app*)activity->instance;
- LOGV("LowMemory: %p\n", activity);
- android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
+ LOGV("LowMemory: %p", activity);
+ android_app_write_cmd(ToApp(activity), APP_CMD_LOW_MEMORY);
}
static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
- LOGV("WindowFocusChanged: %p -- %d\n", activity, focused);
- android_app_write_cmd((struct android_app*)activity->instance,
- focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
+ LOGV("WindowFocusChanged: %p -- %d", activity, focused);
+ android_app_write_cmd(ToApp(activity), focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
}
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
- LOGV("NativeWindowCreated: %p -- %p\n", activity, window);
- android_app_set_window((struct android_app*)activity->instance, window);
+ LOGI("NativeWindowCreated: %p -- %p", activity, window);
+ android_app_set_window(ToApp(activity), window);
}
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
- LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window);
- android_app_set_window((struct android_app*)activity->instance, NULL);
+ LOGI("NativeWindowDestroyed: %p -- %p", activity, window);
+ android_app_set_window(ToApp(activity), NULL);
+}
+
+static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) {
+ LOGI("NativeWindowRedrawNeeded: %p -- %p", activity, window);
+ android_app_write_cmd(ToApp(activity), APP_CMD_WINDOW_REDRAW_NEEDED);
+}
+
+static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window) {
+ LOGI("NativeWindowResized: %p -- %p", activity, window);
+ android_app_write_cmd(ToApp(activity), APP_CMD_WINDOW_RESIZED);
}
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
- LOGV("InputQueueCreated: %p -- %p\n", activity, queue);
- android_app_set_input((struct android_app*)activity->instance, queue);
+ LOGV("InputQueueCreated: %p -- %p", activity, queue);
+ android_app_set_input(ToApp(activity), queue);
}
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
- LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue);
- android_app_set_input((struct android_app*)activity->instance, NULL);
+ LOGV("InputQueueDestroyed: %p -- %p", activity, queue);
+ android_app_set_input(ToApp(activity), NULL);
}
__attribute__((visibility("default"))) void ANativeActivity_onCreate(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
- LOGV("Creating: %p\n", activity);
+ LOGV("Creating: %p", activity);
+
+ activity->callbacks->onConfigurationChanged = onConfigurationChanged;
+ activity->callbacks->onContentRectChanged = onContentRectChanged;
activity->callbacks->onDestroy = onDestroy;
- activity->callbacks->onStart = onStart;
+ activity->callbacks->onInputQueueCreated = onInputQueueCreated;
+ activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
+ activity->callbacks->onLowMemory = onLowMemory;
+ activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
+ activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
+ activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded;
+ activity->callbacks->onNativeWindowResized = onNativeWindowResized;
+ activity->callbacks->onPause = onPause;
activity->callbacks->onResume = onResume;
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
- activity->callbacks->onPause = onPause;
+ activity->callbacks->onStart = onStart;
activity->callbacks->onStop = onStop;
- activity->callbacks->onConfigurationChanged = onConfigurationChanged;
- activity->callbacks->onLowMemory = onLowMemory;
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
- activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
- activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
- activity->callbacks->onInputQueueCreated = onInputQueueCreated;
- activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
activity->instance = android_app_create(activity, savedState, savedStateSize);
}
diff --git a/util/android/third_party/android_native_app_glue.h b/util/android/third_party/android_native_app_glue.h
index c1e4d3cb47..304815f355 100644
--- a/util/android/third_party/android_native_app_glue.h
+++ b/util/android/third_party/android_native_app_glue.h
@@ -12,7 +12,6 @@
* 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 _ANDROID_NATIVE_APP_GLUE_H
@@ -49,7 +48,7 @@ extern "C" {
*
* 2/ android_main() receives a pointer to a valid "android_app" structure
* that contains references to other important objects, e.g. the
- * ANativeActivity obejct instance the application is running in.
+ * ANativeActivity object instance the application is running in.
*
* 3/ the "android_app" object holds an ALooper instance that already
* listens to two important things:
@@ -87,17 +86,18 @@ struct android_app;
* Data associated with an ALooper fd that will be returned as the "outData"
* when that source has data ready.
*/
-struct android_poll_source {
+struct android_poll_source
+{
// The identifier of this source. May be LOOPER_ID_MAIN or
// LOOPER_ID_INPUT.
int32_t id;
// The android_app this ident is associated with.
- struct android_app* app;
+ struct android_app *app;
// Function to call to perform the standard processing of data from
// this source.
- void (*process)(struct android_app* app, struct android_poll_source* source);
+ void (*process)(struct android_app *app, struct android_poll_source *source);
};
/**
@@ -108,25 +108,26 @@ struct android_poll_source {
* VM, although it will need to be in order to make JNI calls any
* Java objects.
*/
-struct android_app {
+struct android_app
+{
// The application can place a pointer to its own state object
// here if it likes.
- void* userData;
+ void *userData;
// Fill this in with the function to process main app commands (APP_CMD_*)
- void (*onAppCmd)(struct android_app* app, int32_t cmd);
+ void (*onAppCmd)(struct android_app *app, int32_t cmd);
// Fill this in with the function to process input events. At this point
// the event has already been pre-dispatched, and it will be finished upon
// return. Return 1 if you have handled the event, 0 for any default
// dispatching.
- int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
+ int32_t (*onInputEvent)(struct android_app *app, AInputEvent *event);
// The ANativeActivity object instance that this app is running in.
- ANativeActivity* activity;
+ ANativeActivity *activity;
// The current configuration the app is running in.
- AConfiguration* config;
+ AConfiguration *config;
// This is the last instance's saved state, as provided at creation time.
// It is NULL if there was no state. You can use this as you need; the
@@ -136,18 +137,18 @@ struct android_app {
// at which point they will be initialized to NULL and you can malloc your
// state and place the information here. In that case the memory will be
// freed for you later.
- void* savedState;
+ void *savedState;
size_t savedStateSize;
// The ALooper associated with the app's thread.
- ALooper* looper;
+ ALooper *looper;
// When non-NULL, this is the input queue from which the app will
// receive user input events.
- AInputQueue* inputQueue;
+ AInputQueue *inputQueue;
// When non-NULL, this is the window surface that the app can draw in.
- ANativeWindow* window;
+ ANativeWindow *window;
// Current content rectangle of the window; this is the area where the
// window's content should be placed to be seen by the user.
@@ -179,12 +180,13 @@ struct android_app {
int stateSaved;
int destroyed;
int redrawNeeded;
- AInputQueue* pendingInputQueue;
- ANativeWindow* pendingWindow;
+ AInputQueue *pendingInputQueue;
+ ANativeWindow *pendingWindow;
ARect pendingContentRect;
};
-enum {
+enum
+{
/**
* Looper data ID of commands coming from the app's main thread, which
* is returned as an identifier from ALooper_pollOnce(). The data for this
@@ -209,7 +211,8 @@ enum {
LOOPER_ID_USER = 3,
};
-enum {
+enum
+{
/**
* Command from main thread: the AInputQueue has changed. Upon processing
* this command, android_app->inputQueue will be updated to the new queue
@@ -315,32 +318,37 @@ enum {
* Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next
* app command message.
*/
-int8_t android_app_read_cmd(struct android_app* android_app);
+int8_t android_app_read_cmd(struct android_app *android_app);
/**
* Call with the command returned by android_app_read_cmd() to do the
* initial pre-processing of the given command. You can perform your own
* actions for the command after calling this function.
*/
-void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
+void android_app_pre_exec_cmd(struct android_app *android_app, int8_t cmd);
/**
* Call with the command returned by android_app_read_cmd() to do the
* final post-processing of the given command. You must have done your own
* actions for the command before calling this function.
*/
-void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
+void android_app_post_exec_cmd(struct android_app *android_app, int8_t cmd);
/**
- * Dummy function you can call to ensure glue code isn't stripped.
+ * No-op function that used to be used to prevent the linker from stripping app
+ * glue code. No longer necessary, since __attribute__((visibility("default")))
+ * does this for us.
*/
-void app_dummy(void);
+__attribute__((
+ deprecated("Calls to app_dummy are no longer necessary. See "
+ "https://github.com/android-ndk/ndk/issues/381."))) void
+app_dummy(void);
/**
* This is the function that application code must implement, representing
* the main entry to the app.
*/
-extern void android_main(struct android_app* app);
+extern void android_main(struct android_app *app);
#ifdef __cplusplus
}