From 110c9a08cf72085fee165586fda45d39083fe659 Mon Sep 17 00:00:00 2001 From: Kimmo Kinnunen Date: Mon, 3 Apr 2023 03:54:07 -0700 Subject: [PATCH] Update ANGLE to 2023-03-30 (5fcd027edec5ae756c4484a7d6e32f8aad147984) https://bugs.webkit.org/show_bug.cgi?id=254802 rdar://problem/107461268 Unreviewed, to be reviewed by Dean Jackson. Contains upstream commits: git log --oneline 12aefbc0dbfb8942723c061f6727638f0739fe02..5fcd027edec5ae756c4484a7d6e32f8aad147984 --pretty=%h %s 5fcd027ed Fix the watchOS build for the mirror clamp to edge extension 20f3df078 Vulkan: ImageHelper::initExternal missing some variable init 98151770a Vulkan: Use midRenderPass clear if RP has started but inactive ad9537af7 Vulkan: Reactivate already started render pass when possible 18b675ea4 Roll vulkan-deps from d56f491466de to e13e8828cf66 (29 revisions) 3c8aee63b D3D11: Fix streamed instanced attribute size calculation. 48b431ca6 Vulkan: Fix stage component reservations w.r.t xfb 31321cb39 Tests: Add Minecraft Bedrock trace 29abd5a29 Explicitly Add Aliased Memory Decoration in SpirV 219776e23 Roll Chromium from c83e966b4c7e to f7c2a70f23b1 (1902 revisions) bb15ceefd Remove syncing of extended dirty bits for TexImage calls. 14ddf5691 Tests: Add fishdom trace 4afbbe85d Tests: Add Vainglory trace fe45418c6 Translator: Limit the size of private variables in WebGL shaders 97897d92d Vulkan: Work around driver bug with dynamic primitive restart 8b81a3d27 GLES1: Use ASCII minus in comment 6d12a280e D3D11: Support NV_shader_noperspective_interpolation da7dd31f2 GL: Disable extended dirty bit states for internal blits. 21ffb23a5 Add sample coverage regression tests 57dd0e5fe Translator: Initialize out arguments too for WebGL fcf0ddeb6 Vulkan: Add more blitFramebuffer test db3b28757 Manual roll VK-GL-CTS from 9e822059a32e to e873c6862868 (18 revisions) c6ec59dca Explicitly pass the extended dirty bits to syncState. fc7cb00e9 Metal: Support NV_shader_noperspective_interpolation 1ee27fcdb Fix translation of noperspective interpolation qualifier fbb16d646 Mali: Disable disjointTimerQueries on ChromeOS with MaliT8xxOrOlder abbbe9709 [GL backend] Get texture bindings size from frontend caps d8c9ba9af Avoid defaulted comparison operator afc1e5dcc GL: Support OES_sample_variables 98cfb969a Roll vulkan-deps from 672a6d1840c9 to d56f491466de (13 revisions) 1301402c5 Vulkan: improve etc to bc grident texture precison. 249b03aca restricted_trace_perf: Delete settings when using default 435e557c5 Vulkan: Do not enforce custom ANGLEs secondary command buffers. aa8f2e4b4 Vulkan: Minor SecondaryCommandPool::destroy() optimization. 85735eb48 Vulkan: Enable async features for Secondary Command Buffers. 2bd8acfef Tests: Add Geometry Dash trace e27e7c6aa Vulkan: Retire Command Buffers before destroying the Pools. 9524c639a Vulkan: Fix Secondary Command Buffers with asyncCommandQueue. 87632d645 Roll SwiftShader from f988757e44a3 to c85d70d97009 (3 revisions) f76021701 Roll vulkan-deps from 886b2b7b32a4 to 672a6d1840c9 (11 revisions) dae99340c Remove uninited pixel check from TexStorageWithPBO c1e45f0c7 Adjust copied dylibs in update_chrome_angle.py f2c5ce4e8 Re-enable mutable texture upload for one context 997c4c7b3 D3D11: Implement EXT_conservative_depth 648f3657c Metal: Implement EXT_conservative_depth 34a06e25d Start MacBook Pro AMD 2019 experiment on ANGLE bots 860a401fb Roll vulkan-deps from 379ee8599f0f to 886b2b7b32a4 (12 revisions) 0e502f8c0 Vulkan: Update SharedCommandBlockPool::valid() method. fc308f4ab Roll SwiftShader from 0cc04d07ab24 to f988757e44a3 (1 revision) e7b7f9772 Roll Chromium from 27821cf1b122 to c83e966b4c7e (630 revisions) 74edb4b44 Skip PixelLocalStorageTest.Interrupt on iOS Metal 888ca8d9e Bind FBO before timer query on Mali GL driver. ad52f12e5 Implement EXT_conservative_depth 11d920527 Roll vulkan-deps from 469b8c0e07d5 to 379ee8599f0f (10 revisions) 5b87328fb Roll SwiftShader from 9c9608fa94a9 to 0cc04d07ab24 (1 revision) 903d24c13 Roll Chromium from 23433174ff7f to 27821cf1b122 (589 revisions) a621ea88c Adding a trace point for texture metrics. ec9595f1a restricted_trace_perf: Run against default driver a491bbe3b Add PLS utilities for interrupting a rendering pass 23ad4fa2b Don't hold global surface lock during AcquireNextImage ba845fcf2 Metal: Implement EXT_clip_control 1e6dd013f Metal: Support centroid qualifier 53d1a179d Makes ToposortStructs() return consistent results f56952445 Fix sample qualifier validation c8c742f64 Roll vulkan-deps from 35cbe26c4b3a to 469b8c0e07d5 (8 revisions) 0709b6fdf Roll SwiftShader from 85772f1891db to 9c9608fa94a9 (7 revisions) 0cb6697a0 Capture/restricted_traces: update documentation 1beb6ef88 Roll Chromium from 528cae6045de to 23433174ff7f (599 revisions) d7201a0f7 Tests: Add New Legend of the Condor Heroes trace bacc066b4 Unskip dEQP-EGL tests e809e7bdf Reland "Implement EXT_depth_clamp" 5384667f4 IWYU: missing include for std::atomic in FixedQueue.h ee9a7df0b IWYU: usage of size_t requires include in texture_utils 518afe765 Roll SwiftShader from 7d001b3fac09 to 85772f1891db (1 revision) 151339b30 Roll vulkan-deps from 250e3914595d to 35cbe26c4b3a (10 revisions) 9c29f84ce Roll VK-GL-CTS from 20d674342f00 to 9e822059a32e (10 revisions) 462dcdcab Roll Chromium from 7a04676dce36 to 528cae6045de (657 revisions) 070749680 Validate gl[Push,Pop]DebugGroup 4a77b0f52 Revert "Implement EXT_depth_clamp" d521ccb31 Tests: Add Rise Of Empires trace 7d1a401b4 Vulkan: Fix freeing not completed Secondary Command Buffers. 9b6368ccf Vulkan: Fix freeing Secondary Command Buffers from wrong thread. 29f80edae Vulkan: Hot fix crash when using Invalid VkSemaphore Object. 12b3d52d8 Prevent bugs in "FastVector" class. 6ea6b3602 Fix allowed_keywords dEQP test failures 50dec7168 Linux skips RegisterContextCompatibilityTests altogether. f8c141831 Implement EXT_depth_clamp 21a3367a1 Tests: Reduce load of computation heavy tests for Swiftshader. 973244574 Roll SwiftShader from fa0e42592666 to 7d001b3fac09 (1 revision) 72c18fe64 Roll vulkan-deps from 88a74be445b7 to 250e3914595d (6 revisions) aecfcefc3 Roll Chromium from 0abde2e3b92a to 7a04676dce36 (552 revisions) Canonical link: https://commits.webkit.org/262503@main --- Source/ThirdParty/ANGLE/.gn | 3 + Source/ThirdParty/ANGLE/ANGLE.plist | 6 +- Source/ThirdParty/ANGLE/DEPS | 137 ++- Source/ThirdParty/ANGLE/changes.diff | 30 +- .../ANGLE_shader_pixel_local_storage.txt | 148 ++- .../ANGLE/include/GLES2/gl2ext_angle.h | 4 + .../ANGLE/include/GLSLANG/ShaderLang.h | 7 +- .../ANGLE/include/GLSLANG/ShaderVars.h | 6 +- .../include/platform/FeaturesGL_autogen.h | 6 + .../include/platform/FeaturesVk_autogen.h | 12 + .../ANGLE/include/platform/gl_features.json | 9 + .../ANGLE/include/platform/vk_features.json | 17 + .../ThirdParty/ANGLE/infra/specs/angle.json | 226 +++- .../ANGLE/infra/specs/waterfalls.pyl | 1 + .../samples/sample_util/texture_utils.cpp | 1 + .../ANGLE_features.json | 12 +- .../ANGLE_shader_translator.json | 4 +- .../Extension_files.json | 2 +- .../GL_CTS_(dEQP)_build_files.json | 12 +- .../GL_EGL_WGL_loader.json | 10 +- .../GL_EGL_entry_points.json | 30 +- .../GLenum_value_to_string_map.json | 2 +- .../Test_spec_JSON.json | 6 +- .../Vulkan_internal_shader_programs.json | 6 +- ...Vulkan_mandatory_format_support_table.json | 2 +- .../interpreter_utils.json | 4 +- .../code_generation_hashes/proc_table.json | 8 +- .../restricted_traces.json | 2 +- .../ANGLE/scripts/generate_entry_points.py | 1 + .../ThirdParty/ANGLE/scripts/gl_angle_ext.xml | 8 + .../ANGLE/scripts/update_chrome_angle.py | 5 +- Source/ThirdParty/ANGLE/src/angle_commit.h | 6 +- .../src/common/ANGLEShaderProgramVersion.h | 2 +- .../ThirdParty/ANGLE/src/common/FastVector.h | 47 +- .../ThirdParty/ANGLE/src/common/FixedQueue.h | 1 + .../ThirdParty/ANGLE/src/common/FixedVector.h | 13 +- .../base/anglebase/trace_event/trace_event.h | 239 ++-- .../src/common/entry_points_enum_autogen.cpp | 4 + .../src/common/entry_points_enum_autogen.h | 2 + .../src/compiler/fuzz/translator_fuzzer.cpp | 1 + .../ANGLE/src/compiler/translator/BaseTypes.h | 275 +++-- .../src/compiler/translator/BuildSPIRV.cpp | 64 +- .../compiler/translator/CollectVariables.cpp | 4 +- .../src/compiler/translator/Compiler.cpp | 1 + .../compiler/translator/ExtensionBehavior.cpp | 1 + .../compiler/translator/ExtensionBehavior.h | 1 + .../src/compiler/translator/Initialize.cpp | 4 + .../compiler/translator/OutputGLSLBase.cpp | 32 + .../src/compiler/translator/OutputHLSL.cpp | 16 +- .../src/compiler/translator/OutputHLSL.h | 2 + .../src/compiler/translator/OutputSPIRV.cpp | 29 +- .../src/compiler/translator/ParseContext.cpp | 92 +- .../src/compiler/translator/ParseContext.h | 2 + .../compiler/translator/QualifierTypes.cpp | 71 +- .../src/compiler/translator/ShaderLang.cpp | 5 + .../compiler/translator/SymbolUniqueId.cpp | 5 + .../src/compiler/translator/SymbolUniqueId.h | 3 +- .../compiler/translator/TranslatorGLSL.cpp | 14 + .../translator/TranslatorMetalDirect.cpp | 21 +- .../translator/TranslatorMetalDirect.h | 4 +- .../TranslatorMetalDirect/EmitMetal.cpp | 37 +- .../TranslatorMetalDirect/Pipeline.cpp | 16 +- .../TranslatorMetalDirect/ToposortStructs.cpp | 28 +- .../src/compiler/translator/UtilsHLSL.cpp | 28 +- .../src/compiler/translator/ValidateAST.cpp | 1 + .../ValidateTypeSizeLimitations.cpp | 23 +- .../ANGLE/src/compiler/translator/glslang.l | 18 +- .../translator/glslang_lex_autogen.cpp | 40 +- .../tree_ops/InitializeVariables.cpp | 31 + .../translator/tree_ops/gl/ClampFragDepth.cpp | 5 +- .../ANGLE/src/compiler/translator/util.cpp | 42 +- .../ANGLE/src/libANGLE/Compiler.cpp | 3 + .../ThirdParty/ANGLE/src/libANGLE/Context.cpp | 54 +- .../ThirdParty/ANGLE/src/libANGLE/Context.h | 15 +- .../ANGLE/src/libANGLE/Context.inl.h | 16 +- .../src/libANGLE/Context_gles_ext_autogen.h | 2 + .../ANGLE/src/libANGLE/ErrorStrings.h | 3 + .../ANGLE/src/libANGLE/Framebuffer.cpp | 1 + .../ANGLE/src/libANGLE/GLES1Shaders.inc | 2 +- .../ANGLE/src/libANGLE/PixelLocalStorage.cpp | 37 + .../ANGLE/src/libANGLE/PixelLocalStorage.h | 6 + .../ThirdParty/ANGLE/src/libANGLE/State.cpp | 25 +- Source/ThirdParty/ANGLE/src/libANGLE/State.h | 18 +- .../ANGLE/src/libANGLE/angletypes.cpp | 3 +- .../ANGLE/src/libANGLE/angletypes.h | 2 + .../src/libANGLE/capture/FrameCapture.cpp | 5 + .../capture/capture_gles_ext_autogen.cpp | 17 + .../capture/capture_gles_ext_autogen.h | 4 + .../ANGLE/src/libANGLE/capture/serialize.cpp | 1 + .../ANGLE/src/libANGLE/queryutils.cpp | 10 + .../ANGLE/src/libANGLE/renderer/ContextImpl.h | 2 + .../src/libANGLE/renderer/d3d/DynamicHLSL.cpp | 29 +- .../src/libANGLE/renderer/d3d/DynamicHLSL.h | 2 +- .../src/libANGLE/renderer/d3d/ProgramD3D.cpp | 14 +- .../src/libANGLE/renderer/d3d/ProgramD3D.h | 4 +- .../src/libANGLE/renderer/d3d/ShaderD3D.cpp | 15 +- .../src/libANGLE/renderer/d3d/ShaderD3D.h | 12 +- .../renderer/d3d/VertexDataManager.cpp | 7 +- .../libANGLE/renderer/d3d/d3d11/Context11.cpp | 4 +- .../libANGLE/renderer/d3d/d3d11/Context11.h | 2 + .../renderer/d3d/d3d11/RenderStateCache.cpp | 2 +- .../renderer/d3d/d3d11/StateManager11.cpp | 15 +- .../renderer/d3d/d3d11/StateManager11.h | 1 + .../renderer/d3d/d3d11/renderer11_utils.cpp | 3 + .../libANGLE/renderer/d3d/d3d9/Context9.cpp | 4 +- .../src/libANGLE/renderer/d3d/d3d9/Context9.h | 2 + .../renderer/d3d/d3d9/StateManager9.cpp | 4 +- .../renderer/d3d/d3d9/StateManager9.h | 4 +- .../ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp | 3 + .../src/libANGLE/renderer/gl/ContextGL.cpp | 5 +- .../src/libANGLE/renderer/gl/ContextGL.h | 2 + .../libANGLE/renderer/gl/StateManagerGL.cpp | 61 +- .../src/libANGLE/renderer/gl/StateManagerGL.h | 8 +- .../libANGLE/renderer/gl/egl/ContextEGL.cpp | 2 +- .../libANGLE/renderer/gl/renderergl_utils.cpp | 24 +- .../src/libANGLE/renderer/metal/ContextMtl.h | 6 +- .../src/libANGLE/renderer/metal/ContextMtl.mm | 50 +- .../src/libANGLE/renderer/metal/DisplayMtl.mm | 9 + .../renderer/metal/mtl_command_buffer.h | 3 + .../renderer/metal/mtl_command_buffer.mm | 22 + .../src/libANGLE/renderer/metal/mtl_utils.h | 2 +- .../src/libANGLE/renderer/metal/mtl_utils.mm | 8 +- .../libANGLE/renderer/null/ContextNULL.cpp | 2 + .../src/libANGLE/renderer/null/ContextNULL.h | 2 + .../renderer/vulkan/AllocatorHelperRing.h | 3 +- .../src/libANGLE/renderer/vulkan/BUILD.gn | 6 +- .../renderer/vulkan/CommandProcessor.cpp | 160 ++- .../renderer/vulkan/CommandProcessor.h | 48 +- .../libANGLE/renderer/vulkan/ContextVk.cpp | 100 +- .../src/libANGLE/renderer/vulkan/ContextVk.h | 17 +- .../src/libANGLE/renderer/vulkan/DisplayVk.h | 2 + .../renderer/vulkan/FramebufferVk.cpp | 34 +- .../libANGLE/renderer/vulkan/FramebufferVk.h | 5 +- .../libANGLE/renderer/vulkan/RendererVk.cpp | 78 +- .../src/libANGLE/renderer/vulkan/RendererVk.h | 34 +- .../renderer/vulkan/SecondaryCommandBuffer.h | 5 +- .../renderer/vulkan/SecondaryCommandPool.cpp | 126 ++ .../renderer/vulkan/SecondaryCommandPool.h | 69 ++ .../src/libANGLE/renderer/vulkan/ShaderVk.cpp | 5 + .../libANGLE/renderer/vulkan/TextureVk.cpp | 3 +- .../src/libANGLE/renderer/vulkan/UtilsVk.cpp | 19 +- .../vulkan/VulkanSecondaryCommandBuffer.cpp | 40 +- .../vulkan/VulkanSecondaryCommandBuffer.h | 23 +- .../shaders/gen/EtcToBc.comp.00000000.inc | 1010 +++++++++-------- .../shaders/gen/EtcToBc.comp.00000001.inc | 514 ++++----- .../renderer/vulkan/shaders/src/EtcToBc.comp | 119 +- .../libANGLE/renderer/vulkan/spv_utils.cpp | 16 +- .../renderer/vulkan/vk_cache_utils.cpp | 5 +- .../renderer/vulkan/vk_caps_utils.cpp | 91 +- .../libANGLE/renderer/vulkan/vk_helpers.cpp | 404 +++++-- .../src/libANGLE/renderer/vulkan/vk_helpers.h | 100 +- .../src/libANGLE/renderer/vulkan/vk_utils.cpp | 4 +- .../src/libANGLE/renderer/vulkan/vk_utils.h | 13 +- .../renderer/vulkan/vulkan_backend.gni | 2 + Source/ThirdParty/ANGLE/src/libANGLE/trace.h | 31 +- .../ANGLE/src/libANGLE/validationES2.cpp | 52 +- .../ANGLE/src/libANGLE/validationES2.h | 9 + .../ANGLE/src/libANGLE/validationES32.cpp | 6 +- .../ANGLE/src/libANGLE/validationESEXT.cpp | 90 +- .../src/libANGLE/validationESEXT_autogen.h | 4 + .../ANGLE/src/libGLESv2/egl_ext_stubs.cpp | 15 +- .../entry_points_gles_ext_autogen.cpp | 50 + .../libGLESv2/entry_points_gles_ext_autogen.h | 2 + .../ANGLE/src/libGLESv2/libGLESv2_autogen.cpp | 10 + .../ANGLE/src/libGLESv2/libGLESv2_autogen.def | 2 + .../libGLESv2_no_capture_autogen.def | 2 + .../libGLESv2_vulkan_secondaries_autogen.def | 2 + .../libGLESv2_with_capture_autogen.def | 2 + .../ANGLE/src/libGLESv2/opengl32_autogen.def | 2 + .../libGLESv2/opengl32_with_wgl_autogen.def | 2 + .../src/libGLESv2/proc_table_egl_autogen.cpp | 2 + .../src/libGLESv2/proc_table_glx_autogen.cpp | 2 + .../src/libGLESv2/proc_table_wgl_autogen.cpp | 2 + .../ANGLE/src/tests/angle_end2end_tests.gni | 1 + .../angle_end2end_tests_expectations.txt | 72 ++ .../capture_replay_expectations.txt | 5 + .../deqp_egl_test_expectations.txt | 5 +- .../deqp_gles2_test_expectations.txt | 4 + .../deqp_gles3_test_expectations.txt | 21 +- .../egl_tests/EGLContextCompatibilityTest.cpp | 30 +- .../gl_tests/BlitFramebufferANGLETest.cpp | 162 +++ .../src/tests/gl_tests/ClipControlTest.cpp | 422 +++++++ .../src/tests/gl_tests/ComputeShaderTest.cpp | 126 ++ .../ANGLE/src/tests/gl_tests/DebugTest.cpp | 26 + .../src/tests/gl_tests/DepthWriteTest.cpp | 409 +++++++ .../src/tests/gl_tests/FormatPrintTest.cpp | 3 - .../src/tests/gl_tests/FragDepthTest.cpp | 123 ++ .../ANGLE/src/tests/gl_tests/GLSLTest.cpp | 158 +++ .../src/tests/gl_tests/InstancingTest.cpp | 39 + .../src/tests/gl_tests/MultisampleTest.cpp | 10 +- .../src/tests/gl_tests/MultithreadingTest.cpp | 300 ++++- .../tests/gl_tests/PixelLocalStorageTest.cpp | 252 +++- .../tests/gl_tests/SimpleOperationTest.cpp | 60 + .../src/tests/gl_tests/StateChangeTest.cpp | 3 +- .../ANGLE/src/tests/gl_tests/TextureTest.cpp | 15 +- .../gl_tests/VulkanPerformanceCounterTest.cpp | 31 + .../tests/gl_tests/WebGLCompatibilityTest.cpp | 27 +- .../ConformanceTests.cpp | 3 - .../gles1_conformance_tests/CovglTests.cpp | 3 - .../gles1_conformance_tests/PrimtestTests.cpp | 3 - .../src/tests/perf_tests/TracePerfTest.cpp | 3 +- .../src/tests/restricted_traces/README.md | 35 +- .../restricted_trace_perf.py | 16 +- .../restricted_traces/restricted_traces.json | 8 +- .../ANGLE/util/angle_features_autogen.cpp | 3 + .../ANGLE/util/angle_features_autogen.h | 3 + .../capture/frame_capture_replay_autogen.cpp | 6 + .../capture/trace_gles_loader_autogen.cpp | 10 + .../util/capture/trace_gles_loader_autogen.h | 6 + .../capture/trace_interpreter_autogen.cpp | 16 + .../ANGLE/util/gles_loader_autogen.cpp | 10 + .../ANGLE/util/gles_loader_autogen.h | 6 + 212 files changed, 6335 insertions(+), 1958 deletions(-) create mode 100644 Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.cpp create mode 100644 Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.h create mode 100644 Source/ThirdParty/ANGLE/src/tests/gl_tests/DepthWriteTest.cpp diff --git a/Source/ThirdParty/ANGLE/.gn b/Source/ThirdParty/ANGLE/.gn index b2c4b545134b..d43e5ae6395e 100644 --- a/Source/ThirdParty/ANGLE/.gn +++ b/Source/ThirdParty/ANGLE/.gn @@ -44,6 +44,9 @@ default_args = { # Saves on importing extra dependencies and ANGLE doesn't use JS. enable_js_protobuf = false + # Saves on importing extra dependencies and ANGLE doesn't use Rust. + enable_rust = false + # Disable location tags in isolates. tests_have_location_tags = false diff --git a/Source/ThirdParty/ANGLE/ANGLE.plist b/Source/ThirdParty/ANGLE/ANGLE.plist index 3584b83b33fa..de18d2da09ab 100644 --- a/Source/ThirdParty/ANGLE/ANGLE.plist +++ b/Source/ThirdParty/ANGLE/ANGLE.plist @@ -6,13 +6,13 @@ OpenSourceProject ANGLE OpenSourceVersion - 12aefbc0dbfb8942723c061f6727638f0739fe02 + 5fcd027edec5ae756c4484a7d6e32f8aad147984 OpenSourceWebsiteURL http://code.google.com/p/angleproject/ OpenSourceSCM - git clone https://chromium.googlesource.com/angle/angle && cd angle && git checkout 12aefbc0dbfb8942723c061f6727638f0739fe02 + git clone https://chromium.googlesource.com/angle/angle && cd angle && git checkout 5fcd027edec5ae756c4484a7d6e32f8aad147984 OpenSourceImportDate - 2023-03-17 + 2023-03-31 OpenSourceLicense BSD OpenSourceLicenseFile diff --git a/Source/ThirdParty/ANGLE/DEPS b/Source/ThirdParty/ANGLE/DEPS index 896877f6db78..012801643c32 100644 --- a/Source/ThirdParty/ANGLE/DEPS +++ b/Source/ThirdParty/ANGLE/DEPS @@ -43,13 +43,13 @@ vars = { 'checkout_angle_mesa': False, # Version of Chromium our Chromium-based DEPS are mirrored from. - 'chromium_revision': '0abde2e3b92a23d09931c9268b3ffd4db30730f9', + 'chromium_revision': 'f7c2a70f23b1ed371b860092ad62177148c94b18', # 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': '20d674342f008624b82e08f26ed5572c176ba7bd', + 'vk_gl_cts_revision': 'e873c6862868cf97b892317731669ec419cd313e', # 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': '5bda427934f1067bfe795199b6466828062b99ac', + 'catapult_revision': 'e838386fa052bd38ad2f7f46fd04e451ce110324', # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:12.20230316.0.1', + 'fuchsia_version': 'version:12.20230327.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:320bf3ed60cd4d24549d0ea9ee3a94394f2665ce', + 'luci_go': 'git_revision:3569ebf36f17a991aa4d26fd6e228cdf6e664d13', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_build-tools_version @@ -140,12 +140,12 @@ vars = { deps = { 'build': { - 'url': '{chromium_git}/chromium/src/build.git@a3aa92a8aba5f0764fa79275e034d660a57ac773', + 'url': '{chromium_git}/chromium/src/build.git@052437a6e1026cdd12607e3c5b4438ed90546d09', 'condition': 'not build_with_chromium', }, 'buildtools': { - 'url': '{chromium_git}/chromium/src/buildtools.git@6f568a60b072eb2ad1bf0c3813e0f106673c7359', + 'url': '{chromium_git}/chromium/src/buildtools.git@c97a3b8902379b6e6f705202db03d415d790ebac', 'condition': 'not build_with_chromium', }, @@ -158,7 +158,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/linux-${{arch}}', - 'version': 'git_revision:fe330c0ae1ec29db30b6f830e50771a335e071fb', + 'version': 'git_revision:41fef642de70ecdcaaa26be96d56a0398f95abd4', } ], 'dep_type': 'cipd', @@ -169,7 +169,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/mac-${{arch}}', - 'version': 'git_revision:fe330c0ae1ec29db30b6f830e50771a335e071fb', + 'version': 'git_revision:41fef642de70ecdcaaa26be96d56a0398f95abd4', } ], 'dep_type': 'cipd', @@ -177,17 +177,17 @@ deps = { }, 'buildtools/third_party/libc++/trunk': { - 'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxx.git@124c7ee3fcfeb8b31c8cb0e78a967ad9d58c86e8', + 'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxx.git@26ace673c4b9c7a352fa9db182256bb341b6c44f', 'condition': 'not build_with_chromium', }, 'buildtools/third_party/libc++abi/trunk': { - 'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxxabi.git@10804337f26a94fbffb3fff7b76695c080173653', + 'url': '{chromium_git}/external/github.com/llvm/llvm-project/libcxxabi.git@9643f2cf13d6935a84a30b7da7de53327733e190', 'condition': 'not build_with_chromium', }, 'buildtools/third_party/libunwind/trunk': { - 'url': '{chromium_git}/external/github.com/llvm/llvm-project/libunwind.git@6289a2147a31827f21a58e451d4ad140562ddf31', + 'url': '{chromium_git}/external/github.com/llvm/llvm-project/libunwind.git@29a6dda8c6588ba4abeafdb21be531e757983e31', 'condition': 'not build_with_chromium', }, @@ -195,7 +195,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/windows-amd64', - 'version': 'git_revision:fe330c0ae1ec29db30b6f830e50771a335e071fb', + 'version': 'git_revision:41fef642de70ecdcaaa26be96d56a0398f95abd4', } ], 'dep_type': 'cipd', @@ -203,12 +203,12 @@ deps = { }, 'testing': { - 'url': '{chromium_git}/chromium/src/testing@fb89ba8b5659f653c7dab37f14e98939a4b31d3a', + 'url': '{chromium_git}/chromium/src/testing@df3b0c9f14ea0966edb997afa8aba3ec14929752', 'condition': 'not build_with_chromium', }, 'third_party/abseil-cpp': { - 'url': '{chromium_git}/chromium/src/third_party/abseil-cpp@5a920a24ca475f64ff9200e600948593351718a0', + 'url': '{chromium_git}/chromium/src/third_party/abseil-cpp@b5b8912f720edf7240d4eb93410ff7edf0c753fa', 'condition': 'not build_with_chromium', }, @@ -254,7 +254,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/lint', - 'version': 'UwgKmRuzPgo_NJFKTlrK_7OSgm2s-sVVb7Uz4jER_soC', + 'version': 'E86vFKi4re9HwIfUW9yq_Ig_hc7Vr0lcl-bO3BtPQLYC', }, ], 'condition': 'checkout_android and not build_with_chromium', @@ -265,7 +265,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': 'lC0-JZAP05FMcCXlQn9Oej4oD6ytlLkFQEnExeLuAWkC', + 'version': '_aoHU11YhUwqKZXVXsn5otnhI-ZVGFT7h1Z9eCcAZM0C', }, ], 'condition': 'checkout_android and not build_with_chromium', @@ -273,7 +273,7 @@ deps = { }, 'third_party/android_deps': { - 'url': '{chromium_git}/chromium/src/third_party/android_deps@34499ffdd4298f90d14fa464ddff949a8937b173', + 'url': '{chromium_git}/chromium/src/third_party/android_deps@115fe1141d2bfc481e95000528ef6a9bd563c025', 'condition': 'checkout_android and not build_with_chromium', }, @@ -329,7 +329,7 @@ deps = { }, { 'package': 'chromium/third_party/android_sdk/public/cmdline-tools', - 'version': '3Yn5Sn7BMObm8gsoZCF0loJMKg9_PpgU07G9DObCLdQC', + 'version': 'EWnL2r7oV5GtE9Ef7GyohyFam42wtMtEKYU4dCb3U1YC', }, ], 'condition': 'checkout_android_native_support and not build_with_chromium', @@ -380,7 +380,7 @@ deps = { }, 'third_party/depot_tools': { - 'url': '{chromium_git}/chromium/tools/depot_tools.git@3408652be0f95743987e9bbd0cdb033ebfcf8642', + 'url': '{chromium_git}/chromium/tools/depot_tools.git@df528a9d7a40d52f0cf0b61cf21e1e298f67860a', 'condition': 'not build_with_chromium', }, @@ -437,7 +437,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/kotlin_stdlib', - 'version': 'zeFlVAEGvnpaj3JJujWHzRlUiBEm4XeeaMQzVsdW6D4C', + 'version': 'XON2v801ZWS7FjApXO8Ev7Me7cOsIAnmqzyCXJuMwJ0C', }, ], 'condition': 'checkout_android and not build_with_chromium', @@ -588,7 +588,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'BSk2ZOJgKl80RawP4WlbE938iWkJnsZmJ-6RzW6u2IsC', + 'version': 'BTs9W6pUBDK8YTePjjF3Q0-ZQo1snO7GBCT6frWMIj8C', }, ], 'condition': 'checkout_android and not build_with_chromium', @@ -624,7 +624,7 @@ deps = { }, 'third_party/SwiftShader': { - 'url': '{swiftshader_git}/SwiftShader@fa0e42592666aa58b401c68792477e5b9df9a01d', + 'url': '{swiftshader_git}/SwiftShader@c85d70d97009a264fc5e7747316743a1abac5f67', 'condition': 'not build_with_chromium', }, @@ -644,7 +644,7 @@ deps = { }, 'third_party/vulkan-deps': { - 'url': '{chromium_git}/vulkan-deps@88a74be445b7d7e91142bb24b0bde903530cf7d0', + 'url': '{chromium_git}/vulkan-deps@e13e8828cf66cdb9b8d6e0bfb6e05f8b1e2c01b0', 'condition': 'not build_with_chromium', }, @@ -669,7 +669,7 @@ deps = { }, 'tools/clang': { - 'url': '{chromium_git}/chromium/src/tools/clang.git@998617f817d50216e4e31c6d90692555573f717d', + 'url': '{chromium_git}/chromium/src/tools/clang.git@04d87bfe25c1c57fd9d7b52479329cede1e5e8e7', 'condition': 'not build_with_chromium', }, @@ -700,7 +700,7 @@ deps = { }, 'tools/mb': { - 'url': '{chromium_git}/chromium/src/tools/mb@605d18db44102c8b0667892f0261f022f6fbe423', + 'url': '{chromium_git}/chromium/src/tools/mb@993b50afdeed64b2c785d96c094c7bb2eeaf1225', 'condition': 'not build_with_chromium', }, @@ -710,12 +710,12 @@ deps = { }, 'tools/memory': { - 'url': '{chromium_git}/chromium/src/tools/memory@b55593f4dc40ec73d72be2d82de64294e98dd342', + 'url': '{chromium_git}/chromium/src/tools/memory@13f0b81ce581364c5f0f2e9e16d6120073dc56a6', 'condition': 'not build_with_chromium', }, 'tools/perf': { - 'url': '{chromium_git}/chromium/src/tools/perf@7424e47c9dd8ca630b38e38bb782bca80356fdd4', + 'url': '{chromium_git}/chromium/src/tools/perf@892ad5cc9432112d5810a89c1113bc227bec58df', 'condition': 'not build_with_chromium', }, @@ -733,7 +733,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': 'iQ7zKud-gha6r9hEdwqYWRdOpeAs6gFfDxnviDUt4FQC', + 'version': 'CHIKK9YvBNPOM_lAlqkfs4dTTbM6I-AKggA94sfc5PoC', }, ], 'dep_type': 'cipd', @@ -744,7 +744,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'we56UJIWxJJ2GkQ_ne0o3oGAr7FBJa5T5Jr1xguLn-gC', + 'version': 'pUOVquC14y84RkNMzEAPw_7tztey-kvH7KBwGsFViuIC', }, ], 'dep_type': 'cipd', @@ -755,7 +755,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': '9Wfje1bt82IO9pJokAt9lboy59X_Pe-s0b4EpmH7RT4C', + 'version': 'Gwb7laBBhkBhwP1nIoAb1EwklQ5sEon7g7r76v7jAasC', }, ], 'dep_type': 'cipd', @@ -766,7 +766,7 @@ deps = { 'packages': [ { 'package': 'skia/tools/goldctl/mac-arm64', - 'version': 'zihT2Lk2afg0XzIZozuGcZXWv7RJujaDEi_6q7QL4DgC', + 'version': 'Jh19SHnigVXYxpk7Fp4ZDMF_ZvLpQUie2NMaK5aEISMC', }, ], 'dep_type': 'cipd', @@ -1569,6 +1569,16 @@ deps = { 'dep_type': 'cipd', 'condition': 'checkout_angle_restricted_traces', }, + 'src/tests/restricted_traces/fishdom': { + 'packages': [ + { + 'package': 'angle/traces/fishdom', + 'version': 'version:1', + }, + ], + 'dep_type': 'cipd', + 'condition': 'checkout_angle_restricted_traces', + }, 'src/tests/restricted_traces/five_nights_at_freddys': { 'packages': [ { @@ -1629,6 +1639,16 @@ deps = { 'dep_type': 'cipd', 'condition': 'checkout_angle_restricted_traces', }, + 'src/tests/restricted_traces/geometry_dash': { + 'packages': [ + { + 'package': 'angle/traces/geometry_dash', + 'version': 'version:1', + }, + ], + 'dep_type': 'cipd', + 'condition': 'checkout_angle_restricted_traces', + }, 'src/tests/restricted_traces/goddess_of_victory_nikke': { 'packages': [ { @@ -2013,7 +2033,17 @@ deps = { 'packages': [ { 'package': 'angle/traces/minecraft', - 'version': 'version:5', + 'version': 'version:7', + }, + ], + 'dep_type': 'cipd', + 'condition': 'checkout_angle_restricted_traces', + }, + 'src/tests/restricted_traces/minecraft_bedrock': { + 'packages': [ + { + 'package': 'angle/traces/minecraft_bedrock', + 'version': 'version:1', }, ], 'dep_type': 'cipd', @@ -2139,6 +2169,16 @@ deps = { 'dep_type': 'cipd', 'condition': 'checkout_angle_restricted_traces', }, + 'src/tests/restricted_traces/new_legend_of_the_condor_heroes': { + 'packages': [ + { + 'package': 'angle/traces/new_legend_of_the_condor_heroes', + 'version': 'version:1', + }, + ], + 'dep_type': 'cipd', + 'condition': 'checkout_angle_restricted_traces', + }, 'src/tests/restricted_traces/ni_no_kuni': { 'packages': [ { @@ -2369,6 +2409,16 @@ deps = { 'dep_type': 'cipd', 'condition': 'checkout_angle_restricted_traces', }, + 'src/tests/restricted_traces/rise_of_empires': { + 'packages': [ + { + 'package': 'angle/traces/rise_of_empires', + 'version': 'version:1', + }, + ], + 'dep_type': 'cipd', + 'condition': 'checkout_angle_restricted_traces', + }, 'src/tests/restricted_traces/rise_of_kingdoms': { 'packages': [ { @@ -2829,6 +2879,16 @@ deps = { 'dep_type': 'cipd', 'condition': 'checkout_angle_restricted_traces', }, + 'src/tests/restricted_traces/vainglory': { + 'packages': [ + { + 'package': 'angle/traces/vainglory', + 'version': 'version:1', + }, + ], + 'dep_type': 'cipd', + 'condition': 'checkout_angle_restricted_traces', + }, 'src/tests/restricted_traces/war_planet_online': { 'packages': [ { @@ -4369,17 +4429,6 @@ deps = { 'dep_type': 'cipd', }, - 'third_party/android_deps/libs/net_sf_kxml_kxml2': { - 'packages': [ - { - 'package': 'chromium/third_party/android_deps/libs/net_sf_kxml_kxml2', - 'version': 'version:2@2.3.0.cr1', - }, - ], - 'condition': 'checkout_android and not build_with_chromium', - 'dep_type': 'cipd', - }, - 'third_party/android_deps/libs/org_bouncycastle_bcprov_jdk15on': { 'packages': [ { diff --git a/Source/ThirdParty/ANGLE/changes.diff b/Source/ThirdParty/ANGLE/changes.diff index b37759bcf9d5..8c22e9135908 100644 --- a/Source/ThirdParty/ANGLE/changes.diff +++ b/Source/ThirdParty/ANGLE/changes.diff @@ -1,10 +1,10 @@ diff --git a/src/common/ANGLEShaderProgramVersion.h b/src/common/ANGLEShaderProgramVersion.h new file mode 100644 -index 0000000000000000000000000000000000000000..e55905bf3c9a0ff338c7c970c4e6ac0b0403818d +index 0000000000000000000000000000000000000000..624a3e99589c4e5f9c057c8da9f14614cea72719 --- /dev/null +++ b/src/common/ANGLEShaderProgramVersion.h @@ -0,0 +1,2 @@ -+#define ANGLE_PROGRAM_VERSION "fc7c14cde1fc55b40d84cc05829a365a" ++#define ANGLE_PROGRAM_VERSION "c91f5dc227af66608b352090f9dcfa1c" +#define ANGLE_PROGRAM_VERSION_HASH_SIZE 16 diff --git a/src/common/utilities.cpp b/src/common/utilities.cpp index 7a0a706519887e596a18e2dbd3489051c78c7ba0..f11469503fd488b856e448c8ed8385d01cc522f1 100644 @@ -94,7 +94,7 @@ index 101e04ccdc4a7217be38960dd372878ad4c15472..9ddc681d320550b171a2916cac8e9a4b { diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp -index 46987ac1bb7ecad90214c33195c3a8f6bd0b59de..a14357ee88fa76f4d675d5463210cb8b17db65b4 100644 +index 19ce708bea32d0ff14670c7af369061c48258b3b..b68b61ee6df8fa58536a5296284709bb7b4dbffb 100644 --- a/src/libANGLE/State.cpp +++ b/src/libANGLE/State.cpp @@ -6,6 +6,9 @@ @@ -121,10 +121,10 @@ index e261e90255c6de20704e79b01a6575fc120e6f84..dc5a3613d1532a9c6e3162c9fdce9963 } diff --git a/src/libANGLE/renderer/metal/ContextMtl.mm b/src/libANGLE/renderer/metal/ContextMtl.mm -index df9dadabc57d29d0ee96617827f5f6e837578af2..dbedfa11ddbf6a4c6180a0438e37d0f2c8088c38 100644 +index 64952d92ffc289bdca8d074e13dcc295fe9daad4..7eee61f7cac71801934f0b44aa486cead862b1d3 100644 --- a/src/libANGLE/renderer/metal/ContextMtl.mm +++ b/src/libANGLE/renderer/metal/ContextMtl.mm -@@ -2439,8 +2439,21 @@ angle::Result ContextMtl::setupDraw(const gl::Context *context, +@@ -2457,8 +2457,21 @@ angle::Result ContextMtl::setupDraw(const gl::Context *context, return angle::Result::Continue; } // Setup with flushed state should either produce a working encoder or fail with an error @@ -149,10 +149,10 @@ index df9dadabc57d29d0ee96617827f5f6e837578af2..dbedfa11ddbf6a4c6180a0438e37d0f2 return angle::Result::Continue; } diff --git a/src/libANGLE/renderer/metal/DisplayMtl.mm b/src/libANGLE/renderer/metal/DisplayMtl.mm -index ea9a09f233bd2fd3ff2531600a4796c6ade8b2f7..35e9b788ef2662e5a0549efa022c38f96fcc88ac 100644 +index 5033366c2d53433992fa92505e15137db615ea19..ece4e06e3432dfe369c9b0f62e633170683c9656 100644 --- a/src/libANGLE/renderer/metal/DisplayMtl.mm +++ b/src/libANGLE/renderer/metal/DisplayMtl.mm -@@ -1359,8 +1359,7 @@ bool DisplayMtl::supportsEitherGPUFamily(uint8_t iOSFamily, uint8_t macFamily) c +@@ -1370,8 +1370,7 @@ bool DisplayMtl::supportsEitherGPUFamily(uint8_t iOSFamily, uint8_t macFamily) c bool DisplayMtl::supports32BitFloatFiltering() const { #if (defined(__MAC_11_0) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_11_0) || \ @@ -221,10 +221,10 @@ index 30f2faac716e9ac4e1a2005cccdaff61faa06233..f66c831fc00fe645206fb0b9b5341abd params.srcDefaultAlphaData = convertedFormat.defaultAlpha; diff --git a/src/libANGLE/renderer/metal/mtl_command_buffer.h b/src/libANGLE/renderer/metal/mtl_command_buffer.h -index aa42b9fe58729ab74699e0e638b94d577b8cc3e6..c7df3484536d9656e6f8aa7c0914a4cc3ef3d7c6 100644 +index 828d62123b29d3a9f61a4f760f7a2a6e3e0406f5..0ee583621fedff68e532d144903a9ca3328958b4 100644 --- a/src/libANGLE/renderer/metal/mtl_command_buffer.h +++ b/src/libANGLE/renderer/metal/mtl_command_buffer.h -@@ -533,6 +533,7 @@ class RenderCommandEncoder final : public CommandEncoder +@@ -536,6 +536,7 @@ class RenderCommandEncoder final : public CommandEncoder const RenderPassDesc &renderPassDesc() const { return mRenderPassDesc; } bool hasDrawCalls() const { return mHasDrawCalls; } @@ -233,10 +233,10 @@ index aa42b9fe58729ab74699e0e638b94d577b8cc3e6..c7df3484536d9656e6f8aa7c0914a4cc private: // Override CommandEncoder diff --git a/src/libANGLE/renderer/metal/mtl_command_buffer.mm b/src/libANGLE/renderer/metal/mtl_command_buffer.mm -index bcbe2a6303d2eda2ff7550da0b274b725ff32c6e..ffefdf656c8ce494629319804b17526b9dc56179 100644 +index 3247043cb4ca7c52ee9f79f3a7dd27cac8cbb2cd..5afc2f3c3c7f7df5bc2b9ec9ddc41baf99e4432a 100644 --- a/src/libANGLE/renderer/metal/mtl_command_buffer.mm +++ b/src/libANGLE/renderer/metal/mtl_command_buffer.mm -@@ -364,24 +364,38 @@ inline void SetVisibilityResultModeCmd(id encoder, +@@ -372,24 +372,38 @@ inline void SetVisibilityResultModeCmd(id encoder, [encoder setVisibilityResultMode:mode offset:offset]; } @@ -479,10 +479,10 @@ index 558075b21cdcdcac0b9cd4ab8fc915bc032f57f7..b3990a828944bab60e692cdd16019ac2 if (!ValidateRenderPipelineState(objCDesc, context, metalDevice)) { diff --git a/src/libANGLE/renderer/metal/mtl_utils.mm b/src/libANGLE/renderer/metal/mtl_utils.mm -index 169b89dd2922f559a4f1831086fbe3a2bfb4030e..a0396f8c88e6502c4df0c8f13384c86d9168394c 100644 +index 555c891f80f36b1824da1a91cd13db80828f3eae..07f27d7a886db9066153aa00b1870e6b6f6e051a 100644 --- a/src/libANGLE/renderer/metal/mtl_utils.mm +++ b/src/libANGLE/renderer/metal/mtl_utils.mm -@@ -1355,6 +1355,24 @@ bool SupportsAppleGPUFamily(id device, uint8_t appleFamily) +@@ -1357,6 +1357,24 @@ bool SupportsAppleGPUFamily(id device, uint8_t appleFamily) #endif // TARGET_OS_IOS || TARGET_OS_TV } @@ -507,7 +507,7 @@ index 169b89dd2922f559a4f1831086fbe3a2bfb4030e..a0396f8c88e6502c4df0c8f13384c86d bool SupportsMacGPUFamily(id device, uint8_t macFamily) { #if TARGET_OS_OSX || TARGET_OS_MACCATALYST -@@ -1369,10 +1387,10 @@ bool SupportsMacGPUFamily(id device, uint8_t macFamily) +@@ -1371,10 +1389,10 @@ bool SupportsMacGPUFamily(id device, uint8_t macFamily) # if TARGET_OS_MACCATALYST ANGLE_APPLE_ALLOW_DEPRECATED_BEGIN case 1: @@ -520,7 +520,7 @@ index 169b89dd2922f559a4f1831086fbe3a2bfb4030e..a0396f8c88e6502c4df0c8f13384c86d break; ANGLE_APPLE_ALLOW_DEPRECATED_END # else // TARGET_OS_MACCATALYST -@@ -1395,7 +1413,7 @@ bool SupportsMacGPUFamily(id device, uint8_t macFamily) +@@ -1397,7 +1415,7 @@ bool SupportsMacGPUFamily(id device, uint8_t macFamily) // If device doesn't support [MTLDevice supportsFamily:], then use // [MTLDevice supportsFeatureSet:]. diff --git a/Source/ThirdParty/ANGLE/extensions/ANGLE_shader_pixel_local_storage.txt b/Source/ThirdParty/ANGLE/extensions/ANGLE_shader_pixel_local_storage.txt index 55e5cb394339..5d95ebf3b47e 100644 --- a/Source/ThirdParty/ANGLE/extensions/ANGLE_shader_pixel_local_storage.txt +++ b/Source/ThirdParty/ANGLE/extensions/ANGLE_shader_pixel_local_storage.txt @@ -144,6 +144,10 @@ New Procedures and Functions void PixelLocalStorageBarrierANGLE() + void FramebufferPixelLocalStorageInterruptANGLE() + + void FramebufferPixelLocalStorageRestoreANGLE() + void GetFramebufferPixelLocalStorageParameter{f,i}vANGLE(int plane, enum pname, T *params) @@ -302,6 +306,10 @@ Additions to the OpenGL ES Specification, Version 3.0.6 * INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound to DRAW_FRAMEBUFFER. + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is in an interrupted state. (See section 2.X.2 + "Interrupting Pixel Local Storage") + * INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero. @@ -367,6 +375,10 @@ Additions to the OpenGL ES Specification, Version 3.0.6 Errors generated by EndPixelLocalStorageANGLE(): + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is in an interrupted state. (See section 2.X.2 + "Interrupting Pixel Local Storage") + * INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero. @@ -390,24 +402,59 @@ Additions to the OpenGL ES Specification, Version 3.0.6 nonzero. All other commands generate INVALID_OPERATION. Valid commands while pixel local storage is active are listed in Table X.3. - ActiveTexture DepthMask MapBufferRange - BindBuffer DepthRangef PixelLocalStorageBarrierANGLE - BindBufferBase Disable SamplerParameter* - BindBufferRange DisableVertexAttribArray Scissor - BindSampler Disablei* StencilFunc - BindTexture DispatchComputeIndirect StencilFuncSeparate - BindVertexArray DrawArrays* StencilMask - BlendEquationSeparatei* DrawElements* StencilMaskSeparate - BlendEquationi* DrawRangeElements* StencilOp - BlendFuncSeparatei* Enable StencilOpSeparate - BlendFunci* EnableClientState TexParameter* - BufferData EnableVertexAttribArray Uniform* - BufferSubData Enablei* UnmapBuffer - CheckFramebufferStatus EndPixelLocalStorageANGLE UseProgram - ClearBuffer* FrontFace ValidateProgram - ColorMaski* Get* VertexAttrib* - CullFace Is* - DepthFunc Viewport + ActiveTexture + BindBuffer + BindBufferBase + BindBufferRange + BindSampler + BindTexture + BindVertexArray + BlendEquationSeparatei* + BlendEquationi* + BlendFuncSeparatei* + BlendFunci* + BufferData + BufferSubData + CheckFramebufferStatus + ClearBuffer* + ColorMaski* + CullFace + DepthFunc + DepthMask + DepthRangef + Disable + DisableVertexAttribArray + Disablei* + DispatchComputeIndirect + DrawArrays* + DrawElements* + DrawRangeElements* + Enable + EnableClientState + EnableVertexAttribArray + Enablei* + EndPixelLocalStorageANGLE + FramebufferPixelLocalStorageInterruptANGLE + FrontFace + Get* + Is* + MapBufferRange + PixelLocalStorageBarrierANGLE + SamplerParameter* + Scissor + StencilFunc + StencilFuncSeparate + StencilMask + StencilMaskSeparate + StencilOp + StencilOpSeparate + TexParameter* + Uniform* + UnmapBuffer + UseProgram + ValidateProgram + VertexAttrib* + Viewport Table X.3: Valid commands while PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero. @@ -492,6 +539,10 @@ Additions to the OpenGL ES Specification, Version 3.0.6 Errors: + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is in an interrupted state. (See section 2.X.2 + "Interrupting Pixel Local Storage") + * INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero. @@ -507,6 +558,45 @@ Additions to the OpenGL ES Specification, Version 3.0.6 conditions between overlapping fragment invocations involved in the current rendering pass. + Section 2.X.2 "Interrupting Pixel Local Storage" + + An application may need to interrupt a pixel local storage rendering pass. + One example of this may be a browser implementing WebGL. The command: + + void FramebufferPixelLocalStorageInterruptANGLE() + + Errors: + + * INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt + count on the draw framebuffer is greater than or equal to 255. + + Increments an interrupt counter on the current draw framebuffer. When the + counter increments from 0 to 1, and PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE + is nonzero, this command also ends pixel local storage using + STORE_OP_STORE_ANGLE for every plane. The contents of any memoryless planes + are lost. This command is ignored when the default framebuffer object name 0 + is bound. When a framebuffer's pixel local storage interupt counter is + nonzero, it is considered to be in an "interrupted" state. + + The command: + + void FramebufferPixelLocalStorageRestoreANGLE() + + Errors: + + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is not in an interrupted state. + + Decrements the pixel local storage interrupt counter on the current draw + framebuffer. When the counter decrements from 1 to 0, and + PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE was nonzero at the time this + framebuffer entered an interrupted state, the command also begins pixel + local storage using LOAD_OP_LOAD_ANGLE for texture backed planes and + DONT_CARE for memoryless planes. The number of planes activated is equal to + the value of PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE at the time this + framebuffer entered an interrupted state. This command is ignored when the + default framebuffer object name 0 is bound. + Modify Section 4.4.2 "Attaching Images to Framebuffer Objects" (Insert two new numbered section after 4.4.2.3 "Attaching Texture Images to a @@ -557,6 +647,10 @@ Additions to the OpenGL ES Specification, Version 3.0.6 * INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound to DRAW_FRAMEBUFFER. + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is in an interrupted state. (See section 2.X.2 + "Interrupting Pixel Local Storage") + * INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero. @@ -635,6 +729,10 @@ Additions to the OpenGL ES Specification, Version 3.0.6 * INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound to DRAW_FRAMEBUFFER. + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is in an interrupted state. (See section 2.X.2 + "Interrupting Pixel Local Storage") + * INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero. @@ -706,6 +804,10 @@ Additions to the OpenGL ES Specification, Version 3.0.6 * INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound to DRAW_FRAMEBUFFER. + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is in an interrupted state. (See section 2.X.2 + "Interrupting Pixel Local Storage") + * INVALID_VALUE is generated if < 0 or >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE. @@ -772,6 +874,10 @@ Additions to the OpenGL ES Specification, Version 3.0.6 * INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is bound to DRAW_FRAMEBUFFER. + * INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the + draw framebuffer is in an interrupted state. (See section 2.X.2 + "Interrupting Pixel Local Storage") + * INVALID_VALUE is generated if < 0 or >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE. @@ -1079,9 +1185,9 @@ Issues Additionally, if the browser uses virtual contexts and wishes to interrupt a PLS render pass, it must be sure to internally call - EndPixelLocalStorageANGLE() before handing off control to the other - virtual context, and BeginPixelLocalStorageANGLE() again before returning - control. + FramebufferPixelLocalStorageInterruptANGLE() before handing off control to + the other virtual context, and FramebufferPixelLocalStorageRestoreANGLE() + again before returning control. (2) Depending on the implementation, of LOAD_OP_ZERO_ANGLE and LOAD_OP_LOAD_ANGLE can have very different performance characteristics. diff --git a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext_angle.h b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext_angle.h index 27e14795191c..09a312a5850f 100644 --- a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext_angle.h +++ b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext_angle.h @@ -628,6 +628,8 @@ typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC) (GL typedef void (GL_APIENTRYP PFNGLBEGINPIXELLOCALSTORAGEANGLEPROC) (GLsizei n, const GLenum loadops[]); typedef void (GL_APIENTRYP PFNGLENDPIXELLOCALSTORAGEANGLEPROC) (GLsizei n, const GLenum storeops[]); typedef void (GL_APIENTRYP PFNGLPIXELLOCALSTORAGEBARRIERANGLEPROC) (void); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALSTORAGEINTERRUPTANGLEPROC) (void); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALSTORAGERESTOREANGLEPROC) (void); typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC) (GLint plane, GLenum pname, GLfloat *params); typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERIVANGLEPROC) (GLint plane, GLenum pname, GLint *params); typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVROBUSTANGLEPROC) (GLint plane, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); @@ -641,6 +643,8 @@ GL_APICALL void GL_APIENTRY glFramebufferPixelLocalClearValueuivANGLE (GLint pla GL_APICALL void GL_APIENTRY glBeginPixelLocalStorageANGLE (GLsizei n, const GLenum loadops[]); GL_APICALL void GL_APIENTRY glEndPixelLocalStorageANGLE (GLsizei n, const GLenum storeops[]); GL_APICALL void GL_APIENTRY glPixelLocalStorageBarrierANGLE (void); +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageInterruptANGLE (void); +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageRestoreANGLE (void); GL_APICALL void GL_APIENTRY glGetFramebufferPixelLocalStorageParameterfvANGLE (GLint plane, GLenum pname, GLfloat *params); GL_APICALL void GL_APIENTRY glGetFramebufferPixelLocalStorageParameterivANGLE (GLint plane, GLenum pname, GLint *params); GL_APICALL void GL_APIENTRY glGetFramebufferPixelLocalStorageParameterfvRobustANGLE (GLint plane, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h index 93b227a64731..4332cd499d37 100644 --- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h +++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h @@ -26,7 +26,7 @@ // Version number for shader translation API. // It is incremented every time the API changes. -#define ANGLE_SH_VERSION 320 +#define ANGLE_SH_VERSION 323 enum ShShaderSpec { @@ -417,6 +417,10 @@ struct ShCompileOptions // Use an integer uniform to pass a bitset of enabled clip distances. uint64_t emulateClipDistanceState : 1; + // issuetracker.google.com/266235549 add aliased memory decoration to ssbo if the variable is + // not declared with "restrict" memory qualifier in GLSL + uint64_t aliasedSSBOUnlessRestrict : 1; + ShCompileOptionsMetal metal; ShPixelLocalStorageOptions pls; }; @@ -453,6 +457,7 @@ struct ShBuiltInResources int NV_EGL_stream_consumer_external; int ARB_texture_rectangle; int EXT_blend_func_extended; + int EXT_conservative_depth; int EXT_draw_buffers; int EXT_frag_depth; int EXT_shader_texture_lod; diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h index ec7bda372f30..c46de76e4ac3 100644 --- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h +++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h @@ -25,10 +25,12 @@ typedef unsigned int GLenum; enum InterpolationType { INTERPOLATION_SMOOTH, + INTERPOLATION_FLAT, + INTERPOLATION_NOPERSPECTIVE, INTERPOLATION_CENTROID, INTERPOLATION_SAMPLE, - INTERPOLATION_FLAT, - INTERPOLATION_NOPERSPECTIVE + INTERPOLATION_NOPERSPECTIVE_CENTROID, + INTERPOLATION_NOPERSPECTIVE_SAMPLE }; const char *InterpolationTypeToString(InterpolationType type); diff --git a/Source/ThirdParty/ANGLE/include/platform/FeaturesGL_autogen.h b/Source/ThirdParty/ANGLE/include/platform/FeaturesGL_autogen.h index dbbaa068d94f..3f82aa6ff89a 100644 --- a/Source/ThirdParty/ANGLE/include/platform/FeaturesGL_autogen.h +++ b/Source/ThirdParty/ANGLE/include/platform/FeaturesGL_autogen.h @@ -474,6 +474,12 @@ struct FeaturesGL : FeatureSetBase &members, }; + FeatureInfo bindFramebufferForTimerQueries = { + "bindFramebufferForTimerQueries", FeatureCategory::OpenGLWorkarounds, + "Some drivers require a non-zero framebuffer when beginQuery for TimeElapsed or" + "Timestampis called.", + &members, "https://crbug.com/1356053"}; + FeatureInfo supportsFragmentShaderInterlockNV = { "supportsFragmentShaderInterlockNV", FeatureCategory::OpenGLFeatures, "Backend GL context supports NV_fragment_shader_interlock extension", &members, diff --git a/Source/ThirdParty/ANGLE/include/platform/FeaturesVk_autogen.h b/Source/ThirdParty/ANGLE/include/platform/FeaturesVk_autogen.h index 25b452c4e02f..09b287207d8f 100644 --- a/Source/ThirdParty/ANGLE/include/platform/FeaturesVk_autogen.h +++ b/Source/ThirdParty/ANGLE/include/platform/FeaturesVk_autogen.h @@ -20,6 +20,12 @@ struct FeaturesVk : FeatureSetBase FeaturesVk(); ~FeaturesVk(); + FeatureInfo appendAliasedMemoryDecorationsToSsbo = { + "appendAliasedMemoryDecorationsToSsbo", FeatureCategory::VulkanWorkarounds, + "Append aliased memory decoration to ssbo in SpirV if the ssbo in GLSL is not declared " + "with restrict memory qualifier", + &members, "b/266235549"}; + FeatureInfo bresenhamLineRasterization = { "bresenhamLineRasterization", FeatureCategory::VulkanFeatures, @@ -660,6 +666,12 @@ struct FeaturesVk : FeatureSetBase "driver bugs", &members, "https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=107106"}; + FeatureInfo forceStaticPrimitiveRestartState = { + "forceStaticPrimitiveRestartState", FeatureCategory::VulkanWorkarounds, + "Force static state for VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE due to " + "driver bugs", + &members, "https://issuetracker.google.com/275210062"}; + FeatureInfo supportsExtendedDynamicState = { "supportsExtendedDynamicState", FeatureCategory::VulkanFeatures, "VkDevice supports VK_EXT_extended_dynamic_state extension", &members, diff --git a/Source/ThirdParty/ANGLE/include/platform/gl_features.json b/Source/ThirdParty/ANGLE/include/platform/gl_features.json index 761387459af5..0b85f8144ffd 100644 --- a/Source/ThirdParty/ANGLE/include/platform/gl_features.json +++ b/Source/ThirdParty/ANGLE/include/platform/gl_features.json @@ -651,6 +651,15 @@ "Some drivers ignore GL_CLIP_DISTANCEi_EXT state." ] }, + { + "name": "bind_framebuffer_for_timer_queries", + "category": "Workarounds", + "description": [ + "Some drivers require a non-zero framebuffer when beginQuery for TimeElapsed or", + "Timestampis called." + ], + "issue": "https://crbug.com/1356053" + }, { "name": "supports_fragment_shader_interlock_NV", "category": "Features", diff --git a/Source/ThirdParty/ANGLE/include/platform/vk_features.json b/Source/ThirdParty/ANGLE/include/platform/vk_features.json index f8b56fe4e932..122037d88369 100644 --- a/Source/ThirdParty/ANGLE/include/platform/vk_features.json +++ b/Source/ThirdParty/ANGLE/include/platform/vk_features.json @@ -7,6 +7,14 @@ "vk_features.json: Optional features for the Vulkan renderer." ], "features": [ + { + "name": "append_aliased_memory_decorations_to_ssbo", + "category": "Workarounds", + "description": [ + "Append aliased memory decoration to ssbo in SpirV if the ssbo in GLSL is not declared with restrict memory qualifier" + ], + "issue": "b/266235549" + }, { "name": "bresenham_line_rasterization", "category": "Features", @@ -878,6 +886,15 @@ ], "issue": "https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=107106" }, + { + "name": "force_static_primitive_restart_state", + "category": "Workarounds", + "description": [ + "Force static state for VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE due to ", + "driver bugs" + ], + "issue": "https://issuetracker.google.com/275210062" + }, { "name": "supports_extended_dynamic_state", "category": "Features", diff --git a/Source/ThirdParty/ANGLE/infra/specs/angle.json b/Source/ThirdParty/ANGLE/infra/specs/angle.json index 8d7afe97b879..efe6822312f9 100644 --- a/Source/ThirdParty/ANGLE/infra/specs/angle.json +++ b/Source/ThirdParty/ANGLE/infra/specs/angle.json @@ -3971,7 +3971,231 @@ } ] }, - "mac-exp-amd": {}, + "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": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.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": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.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": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.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" + ], + "merge": { + "script": "//scripts/angle_deqp_test_merge.py" + }, + "name": "angle_deqp_gles2_metal_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.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": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.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": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.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": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.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": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "cpu": "x86-64", + "display_attached": "1", + "gpu": "1002:67ef", + "hidpi": "1", + "os": "Mac-13.2.1", + "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-intel": {}, "mac-intel": { "gtest_tests": [ diff --git a/Source/ThirdParty/ANGLE/infra/specs/waterfalls.pyl b/Source/ThirdParty/ANGLE/infra/specs/waterfalls.pyl index 4c930dd62591..0a4de1bc2cb0 100644 --- a/Source/ThirdParty/ANGLE/infra/specs/waterfalls.pyl +++ b/Source/ThirdParty/ANGLE/infra/specs/waterfalls.pyl @@ -191,6 +191,7 @@ 'mac_retina_amd_gpu_experimental', ], 'test_suites': { + 'gtest_tests': 'mac_amd_and_intel_gtests', }, }, 'mac-exp-intel': { diff --git a/Source/ThirdParty/ANGLE/samples/sample_util/texture_utils.cpp b/Source/ThirdParty/ANGLE/samples/sample_util/texture_utils.cpp index 71ffc39fc6a7..b1a4f95ec19b 100644 --- a/Source/ThirdParty/ANGLE/samples/sample_util/texture_utils.cpp +++ b/Source/ThirdParty/ANGLE/samples/sample_util/texture_utils.cpp @@ -6,6 +6,7 @@ #include "texture_utils.h" #include +#include GLuint CreateSimpleTexture2D() { diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_features.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_features.json index a60a92c8c28c..cdd925783e77 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_features.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_features.json @@ -2,11 +2,11 @@ "include/platform/FeaturesD3D_autogen.h": "bdce5cac5c70e04fd39e9cf8c6969292", "include/platform/FeaturesGL_autogen.h": - "38325ab28fca006d06f46d1ad4ad2d63", + "331b1660b3982f6540e362764df26021", "include/platform/FeaturesMtl_autogen.h": "d67e2035dabd6e495737da385d5dbe94", "include/platform/FeaturesVk_autogen.h": - "497621280ce1941774876592358a85d4", + "5ab2618c7c158a4af52342eed3114e5f", "include/platform/FrontendFeatures_autogen.h": "be41034e621326dd51e86b139705ea39", "include/platform/d3d_features.json": @@ -16,13 +16,13 @@ "include/platform/gen_features.py": "062989f7a8f3ff3b383f98fc8908dc33", "include/platform/gl_features.json": - "83005189979f62258c7799ec6a6a7572", + "cef92e7ede4c824b8bae37123401d354", "include/platform/mtl_features.json": "cd4de616ed3d18620f8c5b16cb076e66", "include/platform/vk_features.json": - "f871458b67decd588bcfed4b0381bdcb", + "0bc86b174a5f2ec7d1efcf396453693a", "util/angle_features_autogen.cpp": - "2eac5da5a58249c9ad201c26666a0ff7", + "8cb93987ff50d8fb12e117421b904001", "util/angle_features_autogen.h": - "3da81e7b0093659f06fc1cc0137ed977" + "0f74a51d5cfe16fb2a2087467f1e9362" } \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_shader_translator.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_shader_translator.json index c136b8e113bf..e14d38e4c0b0 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_shader_translator.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/ANGLE_shader_translator.json @@ -4,11 +4,11 @@ "src/compiler/translator/generate_parser.py": "ad919972a040d9b3b4aa5dc547fadc75", "src/compiler/translator/glslang.l": - "2385aa23afc3f04500771e3c6bba1a39", + "c47eb888a67462feb27aaab02414ae27", "src/compiler/translator/glslang.y": "b3b3edb114fdd4000c2b78e0bfc7e93d", "src/compiler/translator/glslang_lex_autogen.cpp": - "94ed3b75055979bf788b407932cdee19", + "e8b1dcb576768e279a226f3c072d32d7", "src/compiler/translator/glslang_tab_autogen.cpp": "9719a04ebc96f86619ef474678c6a878", "src/compiler/translator/glslang_tab_autogen.h": diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Extension_files.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Extension_files.json index 74908bcf0f3f..cbfb0cdbbae5 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Extension_files.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Extension_files.json @@ -20,7 +20,7 @@ "scripts/extension_data/swiftshader_win10_gles1.json": "bea8e2106d62e1ea0e8938f150865a37", "scripts/gl_angle_ext.xml": - "a529bc9810e3c3d23e47944465d849f4", + "796894fd74d141b88000669104a663ea", "scripts/registry_xml.py": "8dc1bcf2e8324094c19c41613897b212", "src/libANGLE/gen_extensions.py": diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json index f0d7ae1593dc..728e8c4eb5fd 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json @@ -6,15 +6,15 @@ "src/tests/deqp_support/deqp_data_autogen.gni": "66f7f626b3f33cd2aaaceb0592680be9", "third_party/VK-GL-CTS/src/CMakeLists.txt": - "71f9843d9e42f2f0706d57428d2566fb", + "4cfaeeebac2b56f7b250944973b03532", "third_party/VK-GL-CTS/src/execserver/CMakeLists.txt": "38aa187592e6ef9a331fc1ea313fc68d", "third_party/VK-GL-CTS/src/executor/CMakeLists.txt": "3c256f00625f67d2a8d9ead5f21faddf", + "third_party/VK-GL-CTS/src/external/ESExtractor/CMakeLists.txt": + "3e181d621e0f81fa921bdcc7cd22714e", "third_party/VK-GL-CTS/src/external/amber/CMakeLists.txt": "8871068a2efa10bdce22d5a8588db7ab", - "third_party/VK-GL-CTS/src/external/ffmpeg/CMakeLists.txt": - "fa64b6260091bf72e96bf19ef3bfe89d", "third_party/VK-GL-CTS/src/external/glslang/CMakeLists.txt": "323b44bb52b08f5a937d6e7827667d34", "third_party/VK-GL-CTS/src/external/jsoncpp/CMakeLists.txt": @@ -48,7 +48,7 @@ "third_party/VK-GL-CTS/src/external/vulkancts/framework/vulkan/CMakeLists.txt": "3fcbc0dfe88f724d014494f5ce265549", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/CMakeLists.txt": - "160b413b0f6e174db19584ed5c1e48e2", + "653a663470afe0041afde4605d0c743d", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/amber/CMakeLists.txt": "51aed6000e6c76f2e4a5922e48841885", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/api/CMakeLists.txt": @@ -94,7 +94,7 @@ "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/multiview/CMakeLists.txt": "89402152309427b3117d640994c9a54c", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt": - "3e109072d5aad7c3216e8c5f52d33eb3", + "7c7c34c6f7944e79015304727dd9b009", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/postmortem/CMakeLists.txt": "072d7e38fa574e5b52e4eb6939988f74", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/protected_memory/CMakeLists.txt": @@ -140,7 +140,7 @@ "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/util/CMakeLists.txt": "45b7009c88cbfaf2d27499c41e089c3f", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/video/CMakeLists.txt": - "7e2f9308d3da9669d35903db47784d11", + "cf9d6bf8f5abd3981565004883d08dd5", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/wsi/CMakeLists.txt": "4b9b02f3fab98243826e777c3e71e340", "third_party/VK-GL-CTS/src/external/vulkancts/modules/vulkan/ycbcr/CMakeLists.txt": diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_WGL_loader.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_WGL_loader.json index 8050291f34e9..fe93960965f3 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_WGL_loader.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_WGL_loader.json @@ -4,7 +4,7 @@ "scripts/generate_loader.py": "93c78a8d11323fa311fed5118fbcf083", "scripts/gl_angle_ext.xml": - "a529bc9810e3c3d23e47944465d849f4", + "796894fd74d141b88000669104a663ea", "scripts/registry_xml.py": "8dc1bcf2e8324094c19c41613897b212", "src/libEGL/egl_loader_autogen.cpp": @@ -26,17 +26,17 @@ "util/capture/trace_egl_loader_autogen.h": "b16a510534ee9ee49152fca12b97bd9a", "util/capture/trace_gles_loader_autogen.cpp": - "1cb4deba2a534fde269ad3bc97853939", + "84d1e3209568b054d535ef606cd7f1b1", "util/capture/trace_gles_loader_autogen.h": - "fd7217bbbbce239d581f10dffa2c25b0", + "1ab2170486f56c8a0b989b23d9ff95ab", "util/egl_loader_autogen.cpp": "f98a6cfc104fc468efc90ae3789ddba5", "util/egl_loader_autogen.h": "84247f7f49720e169703fbeffc267023", "util/gles_loader_autogen.cpp": - "f83b9040aefb2a38c8b1bb7c591e16c1", + "92c84905065185a17350f45f14701b44", "util/gles_loader_autogen.h": - "bc23a28f63f3d25269537ae127ea0d43", + "7950f1ae7c39337c843d4f4a1237a4eb", "util/windows/wgl_loader_autogen.cpp": "373b062587eab8a163121255f54597dc", "util/windows/wgl_loader_autogen.h": diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_entry_points.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_entry_points.json index 7fc4f97d6e4e..95651ec901c1 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_entry_points.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_entry_points.json @@ -6,15 +6,15 @@ "scripts/entry_point_packed_gl_enums.json": "97f26215e343436faaa33345e9ce897b", "scripts/generate_entry_points.py": - "9938b48a9bbf813dd245e453ff2fc0cc", + "d2d80730b699b071d6cf58de5130a6d2", "scripts/gl_angle_ext.xml": - "a529bc9810e3c3d23e47944465d849f4", + "796894fd74d141b88000669104a663ea", "scripts/registry_xml.py": "8dc1bcf2e8324094c19c41613897b212", "src/common/entry_points_enum_autogen.cpp": - "a3485618a9f2b4d43c534ee26947f005", + "73d3025dc640d30a49cd504fb7235e63", "src/common/entry_points_enum_autogen.h": - "14c10126610715d4980eee0256a526e3", + "3883bb7c3142554443e06abf81b1ecac", "src/common/frame_capture_utils_autogen.cpp": "abfea27ee4c458bcd0de8c79e17fb70c", "src/common/frame_capture_utils_autogen.h": @@ -38,7 +38,7 @@ "src/libANGLE/Context_gles_3_2_autogen.h": "48567dca16fd881dfe6d61fee0e3106f", "src/libANGLE/Context_gles_ext_autogen.h": - "fa436644f856d4ccc85eff7bacb99040", + "3f9faf6e143186b859a5e1b90dcce498", "src/libANGLE/capture/capture_egl_autogen.cpp": "a5b8f710309de8deab29f2e9d6414cd5", "src/libANGLE/capture/capture_egl_autogen.h": @@ -80,9 +80,9 @@ "src/libANGLE/capture/capture_gles_3_2_autogen.h": "74ed7366af3a46c0661397cfa29ec6fc", "src/libANGLE/capture/capture_gles_ext_autogen.cpp": - "4c3c24e42c4b11e5fda14849f31a6027", + "db8c61a153f0c6c0d5fff7fc8847e834", "src/libANGLE/capture/capture_gles_ext_autogen.h": - "5d41f931a43c4d958d05c677fa5409aa", + "b5e2424ccd014b8890ce38f4e90033ce", "src/libANGLE/validationCL_autogen.h": "0022d0cdb6a9e2ef4a59b71164f62333", "src/libANGLE/validationEGL_autogen.h": @@ -98,7 +98,7 @@ "src/libANGLE/validationES3_autogen.h": "ffffaca63434b2b419614ddb25a57149", "src/libANGLE/validationESEXT_autogen.h": - "b9bac8b7ce3798075fbbcf74e7bcbef4", + "97074a6a51c02855649f64088038218f", "src/libANGLE/validationGL1_autogen.h": "a247dddc40418180d4b2dbefeb75f233", "src/libANGLE/validationGL2_autogen.h": @@ -168,17 +168,17 @@ "src/libGLESv2/entry_points_gles_3_2_autogen.h": "647f932a299cdb4726b60bbba059f0d2", "src/libGLESv2/entry_points_gles_ext_autogen.cpp": - "94c0df149eb8ec3c4bc1b56f66905732", + "16f605670e63f9c8bd9cd63cc834868e", "src/libGLESv2/entry_points_gles_ext_autogen.h": - "374c5d9c2aba33e1586113a84edbca9c", + "d92af68d596f38233ad4d405ff768602", "src/libGLESv2/libGLESv2_autogen.cpp": - "7dd45f5fd7e709a66b4278a13454d23f", + "4c9709f0941129ab32f756982857eb18", "src/libGLESv2/libGLESv2_autogen.def": - "de8c9ebbe5568444e774c889fde255ec", + "5570b88cba60a26c3501b2c98166663d", "src/libGLESv2/libGLESv2_no_capture_autogen.def": - "d9a29cfd4b9655d1a1f2b17040c8c120", + "faf99ff497aba83ea9918d0edc167ddc", "src/libGLESv2/libGLESv2_with_capture_autogen.def": - "9af40fd332a11b7ae6d8d60fa5b15a04", + "d340f7f78f7f87d1b9de00664e52b7ca", "src/libOpenCL/libOpenCL_autogen.cpp": "10849978c910dc1af5dd4f0c815d1581", "third_party/EGL-Registry/src/api/egl.xml": @@ -192,5 +192,5 @@ "third_party/OpenGL-Registry/src/xml/wgl.xml": "eae784bf4d1b983a42af5671b140b7c4", "util/capture/frame_capture_replay_autogen.cpp": - "f0759d49c9ecd8eea14233b9cdbbfbd0" + "4e4e17258787189952d963ef1e0bc5d9" } \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GLenum_value_to_string_map.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GLenum_value_to_string_map.json index 67642f85c118..d015a7108e55 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GLenum_value_to_string_map.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GLenum_value_to_string_map.json @@ -2,7 +2,7 @@ "scripts/gen_gl_enum_utils.py": "3bab69a4a3555ab1551a6e5008534cec", "scripts/gl_angle_ext.xml": - "a529bc9810e3c3d23e47944465d849f4", + "796894fd74d141b88000669104a663ea", "scripts/registry_xml.py": "8dc1bcf2e8324094c19c41613897b212", "src/common/gl_enum_utils_autogen.cpp": diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Test_spec_JSON.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Test_spec_JSON.json index 290ab7358488..8f5b715b0634 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Test_spec_JSON.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Test_spec_JSON.json @@ -1,6 +1,6 @@ { "infra/specs/angle.json": - "11199ab1fd2c2c86e85948cdb49455f0", + "68b70acef9e114d858e15071d470041b", "infra/specs/generate_test_spec_json.py": "b8dbb50c814b7fe05eb77cf6e376cee4", "infra/specs/mixins.pyl": @@ -12,9 +12,9 @@ "infra/specs/variants.pyl": "8cfcaa99fa07ad2a2d5d14f220fd5037", "infra/specs/waterfalls.pyl": - "47cb97b7a7f0e61140d4ff869b14c815", + "72ba42dd8fd2f06633f00dd1aba28ef4", "testing/buildbot/generate_buildbot_json.py": "55e41e1e8f931bdcba3518521567b2b5", "testing/buildbot/mixins.pyl": - "add29e9f8f300729cff8ca191613b8b6" + "a6a4d9ca73a132f7e74d18c867a195ea" } \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_internal_shader_programs.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_internal_shader_programs.json index cd15bc5513e9..318631a01a3a 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_internal_shader_programs.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_internal_shader_programs.json @@ -90,9 +90,9 @@ "src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000007.inc": "105331ec6b8d657fc30ff93f73258baa", "src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000000.inc": - "122d01d1628da2071d835c55095911b1", + "435329724f5ff414203f06cc8512d232", "src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000001.inc": - "515531e181b5b92ebe2bbc6cba39367f", + "8fb53423a3f2feecacfc0d170a33ff3a", "src/libANGLE/renderer/vulkan/shaders/gen/ExportStencil.frag.00000000.inc": "4a68fcf26f60d54745325f79d3eaf219", "src/libANGLE/renderer/vulkan/shaders/gen/FullScreenTri.vert.00000000.inc": @@ -296,7 +296,7 @@ "src/libANGLE/renderer/vulkan/shaders/src/ConvertVertex.comp.json": "5186e223d98092a54dc3ce23677039c1", "src/libANGLE/renderer/vulkan/shaders/src/EtcToBc.comp": - "808257085591ef68f2f64d29ecf813d9", + "03acbcc8abd31c280fd1b9781a765f47", "src/libANGLE/renderer/vulkan/shaders/src/EtcToBc.comp.json": "59e43d52460e98e6f9992ec8c93e2eb5", "src/libANGLE/renderer/vulkan/shaders/src/ExportStencil.frag": diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json index a2c381849acd..ea9a741d0da3 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Vulkan_mandatory_format_support_table.json @@ -10,5 +10,5 @@ "src/libANGLE/renderer/vulkan/vk_mandatory_format_support_table_autogen.cpp": "a726ee791eb4964c406f3921d9b73346", "third_party/vulkan-deps/vulkan-headers/src/registry/vk.xml": - "948ee57f212862e34eee2ecaeb8efc0e" + "b97c5f631e47f9d6c8d4cea4f7fa0e9b" } \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/interpreter_utils.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/interpreter_utils.json index f49e137ad91b..49e7217e3b8a 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/interpreter_utils.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/interpreter_utils.json @@ -4,7 +4,7 @@ "scripts/gen_interpreter_utils.py": "10ba16ee78604763fc883525dd275de8", "scripts/gl_angle_ext.xml": - "a529bc9810e3c3d23e47944465d849f4", + "796894fd74d141b88000669104a663ea", "scripts/registry_xml.py": "8dc1bcf2e8324094c19c41613897b212", "third_party/EGL-Registry/src/api/egl.xml": @@ -20,5 +20,5 @@ "util/capture/trace_fixture.h": "7eebdec11ef0719cf3fb46d6218eae7f", "util/capture/trace_interpreter_autogen.cpp": - "b8666163e3fec8bff10a71e4db7c7990" + "d89b2766ca28ffe273a72f5e9d22c46b" } \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/proc_table.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/proc_table.json index 98f7b4fc569c..e11384dd7b09 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/proc_table.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/proc_table.json @@ -4,17 +4,17 @@ "scripts/gen_proc_table.py": "073351265b085943f816498cecaa281c", "scripts/gl_angle_ext.xml": - "a529bc9810e3c3d23e47944465d849f4", + "796894fd74d141b88000669104a663ea", "scripts/registry_xml.py": "8dc1bcf2e8324094c19c41613897b212", "src/libGLESv2/proc_table_cl_autogen.cpp": "ed003b0f041aaaa35b67d3fe07e61f91", "src/libGLESv2/proc_table_egl_autogen.cpp": - "3c8e273c7d52c66fb752d99f8b2f6014", + "d1fed5143e181eadef448e55e4bb1b69", "src/libGLESv2/proc_table_glx_autogen.cpp": - "88337654fe75030ccbd833eaebdd1c20", + "982300e551154e773513b15684f7ac6f", "src/libGLESv2/proc_table_wgl_autogen.cpp": - "eaa8b5c343b2091b4f596dfa509a7979", + "48d87037a02d5ea93dd58171b51a39cc", "src/libOpenCL/libOpenCL_autogen.map": "bc5f5cf48227149ed321258a16eff1d7", "third_party/EGL-Registry/src/api/egl.xml": diff --git a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/restricted_traces.json b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/restricted_traces.json index e5be5222fd8e..dff13d5f6a07 100644 --- a/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/restricted_traces.json +++ b/Source/ThirdParty/ANGLE/scripts/code_generation_hashes/restricted_traces.json @@ -4,5 +4,5 @@ "src/tests/restricted_traces/gen_restricted_traces.py": "e2fdeb9840527e3d0dc959a67bafdd0e", "src/tests/restricted_traces/restricted_traces.json": - "a485da354a62b94b888f303d23600d58" + "1712db15c19e2f152cab25d9d4ea6791" } \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/scripts/generate_entry_points.py b/Source/ThirdParty/ANGLE/scripts/generate_entry_points.py index d1693dd86a0a..9af88d923a92 100755 --- a/Source/ThirdParty/ANGLE/scripts/generate_entry_points.py +++ b/Source/ThirdParty/ANGLE/scripts/generate_entry_points.py @@ -75,6 +75,7 @@ "EnableClientState", "EnableVertexAttribArray", "EndPixelLocalStorageANGLE", + "FramebufferPixelLocalStorageInterruptANGLE", "FrontFace", "MapBufferRange", "PixelLocalStorageBarrierANGLE", diff --git a/Source/ThirdParty/ANGLE/scripts/gl_angle_ext.xml b/Source/ThirdParty/ANGLE/scripts/gl_angle_ext.xml index 778d31a7b222..b021e5549ae5 100644 --- a/Source/ThirdParty/ANGLE/scripts/gl_angle_ext.xml +++ b/Source/ThirdParty/ANGLE/scripts/gl_angle_ext.xml @@ -993,6 +993,12 @@ void glPixelLocalStorageBarrierANGLE + + void glFramebufferPixelLocalStorageInterruptANGLE + + + void glFramebufferPixelLocalStorageRestoreANGLE + void glGetFramebufferPixelLocalStorageParameterfvANGLE GLint plane @@ -1292,6 +1298,8 @@ + + diff --git a/Source/ThirdParty/ANGLE/scripts/update_chrome_angle.py b/Source/ThirdParty/ANGLE/scripts/update_chrome_angle.py index 422c2a56b79f..7d3b093c4c62 100755 --- a/Source/ThirdParty/ANGLE/scripts/update_chrome_angle.py +++ b/Source/ThirdParty/ANGLE/scripts/update_chrome_angle.py @@ -36,7 +36,10 @@ chrome_folder = '/Applications/Google Chrome Canary.app/Contents/Frameworks/Google Chrome Framework.framework/Libraries' libs_to_copy = ['libGLESv2.dylib', 'libEGL.dylib'] optional_libs_to_copy = [ - 'libvk_swiftshader.dylib', 'libchrome_zlib.dylib', 'libabsl.dylib', 'libc++_chrome.dylib' + 'libc++_chrome.dylib', + 'libchrome_zlib.dylib', + 'libthird_party_abseil-cpp_absl.dylib', + 'libvk_swiftshader.dylib', ] else: diff --git a/Source/ThirdParty/ANGLE/src/angle_commit.h b/Source/ThirdParty/ANGLE/src/angle_commit.h index 608b6892b8a0..91f8caf93a7f 100644 --- a/Source/ThirdParty/ANGLE/src/angle_commit.h +++ b/Source/ThirdParty/ANGLE/src/angle_commit.h @@ -1,4 +1,4 @@ -#define ANGLE_COMMIT_HASH "12aefbc0dbfb" +#define ANGLE_COMMIT_HASH "5fcd027edec5" #define ANGLE_COMMIT_HASH_SIZE 12 -#define ANGLE_COMMIT_DATE "2023-03-16 21:03:51 +0000" -#define ANGLE_COMMIT_POSITION 20741 +#define ANGLE_COMMIT_DATE "2023-03-30 23:52:04 +0000" +#define ANGLE_COMMIT_POSITION 20832 diff --git a/Source/ThirdParty/ANGLE/src/common/ANGLEShaderProgramVersion.h b/Source/ThirdParty/ANGLE/src/common/ANGLEShaderProgramVersion.h index 56af66411529..624a3e99589c 100644 --- a/Source/ThirdParty/ANGLE/src/common/ANGLEShaderProgramVersion.h +++ b/Source/ThirdParty/ANGLE/src/common/ANGLEShaderProgramVersion.h @@ -1,2 +1,2 @@ -#define ANGLE_PROGRAM_VERSION "04aaab59a833345418c7917ae2c77abc" +#define ANGLE_PROGRAM_VERSION "c91f5dc227af66608b352090f9dcfa1c" #define ANGLE_PROGRAM_VERSION_HASH_SIZE 16 diff --git a/Source/ThirdParty/ANGLE/src/common/FastVector.h b/Source/ThirdParty/ANGLE/src/common/FastVector.h index b2f403da6801..ecabf4ab83e9 100644 --- a/Source/ThirdParty/ANGLE/src/common/FastVector.h +++ b/Source/ThirdParty/ANGLE/src/common/FastVector.h @@ -96,6 +96,9 @@ class FastVector final using iterator = WrapIter; using const_iterator = WrapIter; + // This class does not call destructors when resizing down (for performance reasons). + static_assert(std::is_trivially_destructible_v); + FastVector(); FastVector(size_type count, const value_type &value); FastVector(size_type count); @@ -152,6 +155,15 @@ class FastVector final void resize(size_type count); void resize(size_type count, const value_type &value); + // Only for use with non trivially constructible types. + // When increasing size, new elements may have previous values. Use with caution in cases when + // initialization of new elements is not required (will be explicitly initialized later), or + // is never resizing down (not possible to reuse previous values). + void resize_maybe_value_reuse(size_type count); + // Only for use with non trivially constructible types. + // No new elements added, so this function is safe to use. Generates ASSERT() if try resize up. + void resize_down(size_type count); + void reserve(size_type count); // Specialty function that removes a known element and might shuffle the list. @@ -162,6 +174,7 @@ class FastVector final void assign_from_initializer_list(std::initializer_list init); void ensure_capacity(size_t capacity); bool uses_fixed_storage() const; + void resize_impl(size_type count); Storage mFixedStorage; pointer mData = mFixedStorage.data(); @@ -353,7 +366,7 @@ ANGLE_INLINE typename FastVector::size_type FastVector void FastVector::clear() { - resize(0); + resize_impl(0); } template @@ -437,7 +450,37 @@ void FastVector::swap(FastVector &other) } template -void FastVector::resize(size_type count) +ANGLE_INLINE void FastVector::resize(size_type count) +{ + // Trivially constructible types will have undefined values when created therefore reusing + // previous values after resize should not be a problem.. + static_assert(std::is_trivially_constructible_v, + "For non trivially constructible types please use: resize(count, value), " + "resize_maybe_value_reuse(count), or resize_down(count) methods."); + resize_impl(count); +} + +template +ANGLE_INLINE void FastVector::resize_maybe_value_reuse(size_type count) +{ + static_assert(!std::is_trivially_constructible_v, + "This is a special method for non trivially constructible types. " + "Please use regular resize(count) method."); + resize_impl(count); +} + +template +ANGLE_INLINE void FastVector::resize_down(size_type count) +{ + static_assert(!std::is_trivially_constructible_v, + "This is a special method for non trivially constructible types. " + "Please use regular resize(count) method."); + ASSERT(count <= mSize); + resize_impl(count); +} + +template +void FastVector::resize_impl(size_type count) { if (count > mSize) { diff --git a/Source/ThirdParty/ANGLE/src/common/FixedQueue.h b/Source/ThirdParty/ANGLE/src/common/FixedQueue.h index da61761a369e..025efa72eac2 100644 --- a/Source/ThirdParty/ANGLE/src/common/FixedQueue.h +++ b/Source/ThirdParty/ANGLE/src/common/FixedQueue.h @@ -14,6 +14,7 @@ #include #include +#include namespace angle { diff --git a/Source/ThirdParty/ANGLE/src/common/FixedVector.h b/Source/ThirdParty/ANGLE/src/common/FixedVector.h index bff87fc969f0..1a0304118fa0 100644 --- a/Source/ThirdParty/ANGLE/src/common/FixedVector.h +++ b/Source/ThirdParty/ANGLE/src/common/FixedVector.h @@ -45,7 +45,8 @@ class FixedVector final FixedVector &operator=(FixedVector &&other); FixedVector &operator=(std::initializer_list init); - ~FixedVector(); + // Makes class trivially destructible. + ~FixedVector() = default; reference at(size_type pos); const_reference at(size_type pos) const; @@ -72,7 +73,7 @@ class FixedVector final void push_back(value_type &&value); template - void emplace_back(Args &&... args); + void emplace_back(Args &&...args); void pop_back(); reference back(); @@ -151,12 +152,6 @@ FixedVector &FixedVector::operator=( return this; } -template -FixedVector::~FixedVector() -{ - clear(); -} - template typename FixedVector::reference FixedVector::at(size_type pos) { @@ -265,7 +260,7 @@ void FixedVector::push_back(value_type &&value) template template -void FixedVector::emplace_back(Args &&... args) +void FixedVector::emplace_back(Args &&...args) { ASSERT(mSize < N); new (&mStorage[mSize]) T{std::forward(args)...}; diff --git a/Source/ThirdParty/ANGLE/src/common/base/anglebase/trace_event/trace_event.h b/Source/ThirdParty/ANGLE/src/common/base/anglebase/trace_event/trace_event.h index 53b52771452b..66d0a4012aaf 100644 --- a/Source/ThirdParty/ANGLE/src/common/base/anglebase/trace_event/trace_event.h +++ b/Source/ThirdParty/ANGLE/src/common/base/anglebase/trace_event/trace_event.h @@ -10,12 +10,12 @@ // Events are issued against categories. Whereas LOG's // categories are statically defined, TRACE categories are created // implicitly with a string. For example: -// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") +// TRACE_EVENT_INSTANT("MY_SUBSYSTEM", "SomeImportantEvent") // // Events can be INSTANT, or can be pairs of BEGIN and END in the same scope: -// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly") +// TRACE_EVENT_BEGIN("MY_SUBSYSTEM", "SomethingCostly") // doSomethingCostly() -// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly") +// TRACE_EVENT_END("MY_SUBSYSTEM", "SomethingCostly") // Note: our tools can't always determine the correct BEGIN/END pairs unless // these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you need them // to be in separate scopes. @@ -23,14 +23,13 @@ // A common use case is to trace entire function scopes. This // issues a trace BEGIN and END automatically: // void doSomethingCostly() { -// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly"); +// TRACE_EVENT("MY_SUBSYSTEM", "doSomethingCostly"); // ... // } // // Additional parameters can be associated with an event: // void doSomethingCostly2(int howMuch) { -// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", -// "howMuch", howMuch); +// TRACE_EVENT("MY_SUBSYSTEM", "doSomethingCostly", "howMuch", howMuch); // ... // } // @@ -42,11 +41,11 @@ // [single threaded sender code] // static int send_count = 0; // ++send_count; -// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count); +// TRACE_EVENT_ASYNC_BEGIN("ipc", "message", send_count); // Send(new MyMessage(send_count)); // [receive code] // void OnMyMessage(send_count) { -// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count); +// TRACE_EVENT_ASYNC_END("ipc", "message", send_count); // } // The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs. // ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. Pointers can @@ -55,10 +54,10 @@ // class MyTracedClass { // public: // MyTracedClass() { -// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this); +// TRACE_EVENT_ASYNC_BEGIN("category", "MyTracedClass", this); // } // ~MyTracedClass() { -// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this); +// TRACE_EVENT_ASYNC_END("category", "MyTracedClass", this); // } // } // @@ -80,7 +79,7 @@ // This indicates to the tracing UI that these counters should be displayed // in a single graph, as a summed area chart. // -// Since counters are in a global namespace, you may want to disembiguate with a +// Since counters are in a global namespace, you may want to disambiguate with a // unique ID, by using the TRACE_COUNTER_ID* variations. // // By default, trace collection is compiled in, but turned off at runtime. @@ -94,7 +93,7 @@ // in for category, name, and arg_names. Thus, the following code will // cause problems: // char* str = strdup("impprtantName"); -// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD! +// TRACE_EVENT_INSTANT("SUBSYSTEM", str); // BAD! // free(str); // Trace system now has dangling pointer // // To avoid this issue with the |name| and |arg_name| parameters, use the @@ -105,13 +104,13 @@ // // When are string argument values copied: // const char* arg_values are only referenced by default: -// TRACE_EVENT1("category", "name", +// TRACE_EVENT("category", "name", // "arg1", "literal string is only referenced"); // Use TRACE_STR_COPY to force copying of a const char*: -// TRACE_EVENT1("category", "name", +// TRACE_EVENT("category", "name", // "arg1", TRACE_STR_COPY("string will be copied")); // std::string arg_values are always copied: -// TRACE_EVENT1("category", "name", +// TRACE_EVENT("category", "name", // "arg1", std::string("string will be copied")); // // @@ -151,88 +150,106 @@ #define TRACE_STR_COPY(str) WebCore::TraceEvent::TraceStringWithCopy(str) // Records a pair of begin and end events called "name" for the current -// scope, with 0, 1 or 2 associated arguments. If the category is not -// enabled, then this does nothing. +// scope, optionally with associated arguments. +// Each argument must have a name and a value. +// If the category is not enabled, then this does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT0(platform, category, name) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name) +#define TRACE_EVENT(platform, category, name, ...) \ + INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name, ##__VA_ARGS__) + +// Deprecated, use `TRACE_EVENT` instead +#define TRACE_EVENT0(platform, category, name) TRACE_EVENT(platform, category, name) #define TRACE_EVENT1(platform, category, name, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name, arg1_name, arg1_val) -#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name, arg1_name, arg1_val, arg2_name, \ - arg2_val) + TRACE_EVENT(platform, category, name, arg1_name, arg1_val) +#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ + TRACE_EVENT(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) -// Records a single event called "name" immediately, with 0, 1 or 2 -// associated arguments. If the category is not enabled, then this -// does nothing. +// Records a single event called "name" immediately, optionally with associated arguments. +// Each argument must have a name and a value. +// If the category is not enabled, then this does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT_INSTANT0(platform, category, name) \ +#define TRACE_EVENT_INSTANT(platform, category, name, ...) \ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \ - TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_INSTANT1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__) +#define TRACE_EVENT_COPY_INSTANT(platform, category, name, ...) \ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) + TRACE_EVENT_FLAG_COPY, ##__VA_ARGS__) + +// Deprecated, use `TRACE_EVENT_INSTANT` instead +#define TRACE_EVENT_INSTANT0(platform, category, name) TRACE_EVENT_INSTANT(platform, category, name) +#define TRACE_EVENT_INSTANT1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_INSTANT(platform, category, name, arg1_name, arg1_val) #define TRACE_EVENT_INSTANT2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_INSTANT0(platform, category, name) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \ - TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_INSTANT1(platform, category, name, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) + TRACE_EVENT_INSTANT(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) + +// Deprecated, use `TRACE_EVENT_COPY_INSTANT` instead +#define TRACE_EVENT_COPY_INSTANT0(platform, category, name) \ + TRACE_EVENT_COPY_INSTANT(platform, category, name) +#define TRACE_EVENT_COPY_INSTANT1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_COPY_INSTANT(platform, category, name, arg1_name, arg1_val) #define TRACE_EVENT_COPY_INSTANT2(platform, category, name, arg1_name, arg1_val, arg2_name, \ arg2_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) + TRACE_EVENT_COPY_INSTANT(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) -// Records a single BEGIN event called "name" immediately, with 0, 1 or 2 -// associated arguments. If the category is not enabled, then this -// does nothing. +// Records a single BEGIN event called "name" immediately, optionally with associated arguments. +// Each argument must have a name and a value. +// If the category is not enabled, then this does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT_BEGIN0(platform, category, name) \ +#define TRACE_EVENT_BEGIN(platform, category, name, ...) \ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \ - TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_BEGIN1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__) +#define TRACE_EVENT_COPY_BEGIN(platform, category, name, ...) \ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) + TRACE_EVENT_FLAG_COPY, ##__VA_ARGS__) + +// Deprecated, use TRACE_EVENT_BEGIN +#define TRACE_EVENT_BEGIN0(platform, category, name) TRACE_EVENT_BEGIN(platform, category, name) +#define TRACE_EVENT_BEGIN1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_BEGIN(platform, category, name, arg1_name, arg1_val) #define TRACE_EVENT_BEGIN2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_BEGIN0(platform, category, name) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \ - TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_BEGIN1(platform, category, name, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) -#define TRACE_EVENT_COPY_BEGIN2(platform, category, name, arg1_name, arg1_val, arg2_name, \ - arg2_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) + TRACE_EVENT_BEGIN(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) + +// Deprecated, use TRACE_EVENT_COPY_BEGIN +#define TRACE_EVENT_COPY_BEGIN0(platform, category, name) \ + TRACE_EVENT_COPY_BEGIN(platform, category, name) +#define TRACE_EVENT_COPY_BEGIN1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_COPY_BEGIN(platform, category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +#define TRACE_EVENT_COPY_BEGIN2(platform, category, name, arg1_name, arg1_val, arg2_name, \ + arg2_val) \ + TRACE_EVENT_COPY_BEGIN(platform, category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ + arg2_name, arg2_val) // Records a single END event for "name" immediately. If the category // is not enabled, then this does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT_END0(platform, category, name) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_END1(platform, category, name, arg1_name, arg1_val) \ +#define TRACE_EVENT_END(platform, category, name, ...) \ + INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \ + TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__) +#define TRACE_EVENT_COPY_END(platform, category, name, ...) \ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) + TRACE_EVENT_FLAG_COPY, ##__VA_ARGS__) + +// Deprecated, use TRACE_EVENT_END +#define TRACE_EVENT_END0(platform, category, name) \ + TRACE_EVENT_END(platform, TRACE_EVENT_PHASE_END, category, name) +#define TRACE_EVENT_END1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_END(platform, TRACE_EVENT_PHASE_END, category, name, arg1_name, arg1_val) #define TRACE_EVENT_END2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \ - TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val) + TRACE_EVENT_END(platform, TRACE_EVENT_PHASE_END, category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) + +// Deprecated, use TRACE_EVENT_COPY_END #define TRACE_EVENT_COPY_END0(platform, category, name) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_END1(platform, category, name, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) + TRACE_EVENT_COPY_END(platform, TRACE_EVENT_PHASE_END, category, name) +#define TRACE_EVENT_COPY_END1(platform, category, name, arg1_name, arg1_val) \ + TRACE_EVENT_COPY_END(platform, TRACE_EVENT_PHASE_END, category, name, arg1_name, arg1_val) #define TRACE_EVENT_COPY_END2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \ - TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val) + TRACE_EVENT_COPY_END(platform, TRACE_EVENT_PHASE_END, category, name, arg1_name, arg1_val, \ + arg2_name, arg2_val) // Records the value of a counter called "name" immediately. Value // must be representable as a 32 bit integer. @@ -664,60 +681,54 @@ static inline void setTraceValue(const std::string &arg, *value = typeValue.m_uint; } -// These addTraceEvent template functions are defined here instead of in the -// macro, because the arg values could be temporary string objects. In order to -// store pointers to the internal c_str and pass through to the tracing API, the -// arg values must live throughout these procedures. - -static inline angle::TraceEventHandle addTraceEvent(angle::PlatformMethods *platform, - char phase, - const unsigned char *categoryEnabled, - const char *name, - unsigned long long id, - unsigned char flags) +static inline void unpackArguments(const char **names, + unsigned char *types, + unsigned long long *values) +{} + +template +static inline void unpackArguments(const char **names, + unsigned char *types, + unsigned long long *values, + const char *argName, + const ArgType &argVal, + const Args... args) { - return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, zeroNumArgs, - 0, 0, 0, flags); + *names = argName; + setTraceValue(argVal, types, values); + unpackArguments(++names, ++types, ++values, args...); } -template -static inline angle::TraceEventHandle addTraceEvent(angle::PlatformMethods *platform, - char phase, - const unsigned char *categoryEnabled, - const char *name, - unsigned long long id, - unsigned char flags, - const char *arg1Name, - const ARG1_TYPE &arg1Val) -{ - const int numArgs = 1; - unsigned char argTypes[1]; - unsigned long long argValues[1]; - setTraceValue(arg1Val, &argTypes[0], &argValues[0]); - return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, numArgs, - &arg1Name, argTypes, argValues, flags); -} +// The addTraceEvent template function is defined here instead of in the +// macro, because the arg values could be temporary string objects. In order to +// store pointers to the internal c_str and pass through to the tracing API, the +// arg values must live throughout these procedures. -template +template static inline angle::TraceEventHandle addTraceEvent(angle::PlatformMethods *platform, char phase, const unsigned char *categoryEnabled, const char *name, unsigned long long id, unsigned char flags, - const char *arg1Name, - const ARG1_TYPE &arg1Val, - const char *arg2Name, - const ARG2_TYPE &arg2Val) + const Args... args) { - const int numArgs = 2; - const char *argNames[2] = {arg1Name, arg2Name}; - unsigned char argTypes[2]; - unsigned long long argValues[2]; - setTraceValue(arg1Val, &argTypes[0], &argValues[0]); - setTraceValue(arg2Val, &argTypes[1], &argValues[1]); - return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, numArgs, - argNames, argTypes, argValues, flags); + if constexpr (sizeof...(Args) == 0) + { + return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, + zeroNumArgs, 0, 0, 0, flags); + } + else + { + constexpr std::size_t numArgs = sizeof...(Args) / 2; + const char *argNames[numArgs]; + unsigned char argTypes[numArgs]; + unsigned long long argValues[numArgs]; + unpackArguments(argNames, argTypes, argValues, args...); + + return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, numArgs, + argNames, argTypes, argValues, flags); + } } // Used by TRACE_EVENTx macro. Do not use directly. diff --git a/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.cpp b/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.cpp index 282b5d63a2ca..22be2a20beeb 100644 --- a/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.cpp @@ -1192,6 +1192,10 @@ const char *GetEntryPointName(EntryPoint ep) return "glFramebufferPixelLocalClearValueivANGLE"; case EntryPoint::GLFramebufferPixelLocalClearValueuivANGLE: return "glFramebufferPixelLocalClearValueuivANGLE"; + case EntryPoint::GLFramebufferPixelLocalStorageInterruptANGLE: + return "glFramebufferPixelLocalStorageInterruptANGLE"; + case EntryPoint::GLFramebufferPixelLocalStorageRestoreANGLE: + return "glFramebufferPixelLocalStorageRestoreANGLE"; case EntryPoint::GLFramebufferRenderbuffer: return "glFramebufferRenderbuffer"; case EntryPoint::GLFramebufferRenderbufferOES: diff --git a/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.h b/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.h index a2343870a09d..abfdff30f638 100644 --- a/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.h +++ b/Source/ThirdParty/ANGLE/src/common/entry_points_enum_autogen.h @@ -602,6 +602,8 @@ enum class EntryPoint GLFramebufferPixelLocalClearValuefvANGLE, GLFramebufferPixelLocalClearValueivANGLE, GLFramebufferPixelLocalClearValueuivANGLE, + GLFramebufferPixelLocalStorageInterruptANGLE, + GLFramebufferPixelLocalStorageRestoreANGLE, GLFramebufferRenderbuffer, GLFramebufferRenderbufferOES, GLFramebufferTexture, diff --git a/Source/ThirdParty/ANGLE/src/compiler/fuzz/translator_fuzzer.cpp b/Source/ThirdParty/ANGLE/src/compiler/fuzz/translator_fuzzer.cpp index 266aba3bce32..fe2f3e6b46fb 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/fuzz/translator_fuzzer.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/fuzz/translator_fuzzer.cpp @@ -199,6 +199,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) resources.NV_EGL_stream_consumer_external = 1; resources.ARB_texture_rectangle = 1; resources.EXT_blend_func_extended = 1; + resources.EXT_conservative_depth = 1; resources.EXT_draw_buffers = 1; resources.EXT_frag_depth = 1; resources.EXT_shader_texture_lod = 1; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h b/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h index e3e4e4f24b07..7e167d143705 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h @@ -1084,21 +1084,53 @@ enum TQualifier EvqLastFragData, // GLSL ES 3.0 vertex output and fragment input - EvqSmooth, // Incomplete qualifier, smooth is the default - EvqFlat, // Incomplete qualifier - EvqNoPerspective, // Incomplete qualifier - EvqCentroid, // Incomplete qualifier - EvqSample, + + // This section combines + // * storage (in/out), + // * auxiliary storage (/centroid/sample), and + // * interpolation (/smooth/flat/noperspective) + // qualifiers into a flat list. + + // Qualifiers not ending with 'In' or 'Out' are considered incomplete + // and are used only internally. Some combinations are redundant + // because they represent the same effective qualifiers. Specifically: + // * 'smooth' is implied when an interpolation qualifier is omitted + // * 'flat' makes 'centroid' and 'sample' irrelevant + + // -> original storage qualifier, e.g., EvqFragmentIn, implies smooth + // centroid -> EvqCentroid + // sample -> EvqSample + // smooth -> EvqSmooth + // smooth centroid -> EvqCentroid + // smooth sample -> EvqSample + // flat -> EvqFlat + // flat centroid -> EvqFlat + // flat sample -> EvqFlat + // noperspective -> EvqNoPerspective + // noperspective centroid -> EvqNoPerspectiveCentroid + // noperspective sample -> EvqNoPerspectiveSample + + EvqSmooth, // Incomplete + EvqFlat, // Incomplete + EvqNoPerspective, // Incomplete + EvqCentroid, // Incomplete + EvqSample, // Incomplete + EvqNoPerspectiveCentroid, // Incomplete + EvqNoPerspectiveSample, // Incomplete EvqSmoothOut, EvqFlatOut, EvqNoPerspectiveOut, EvqCentroidOut, // Implies smooth - EvqSampleOut, + EvqSampleOut, // Implies smooth + EvqNoPerspectiveCentroidOut, + EvqNoPerspectiveSampleOut, EvqSmoothIn, EvqFlatIn, EvqNoPerspectiveIn, EvqCentroidIn, // Implies smooth - EvqSampleIn, + EvqSampleIn, // Implies smooth + EvqNoPerspectiveCentroidIn, + EvqNoPerspectiveSampleIn, // GLSL ES 3.0 extension OES_sample_variables EvqSampleID, @@ -1194,6 +1226,8 @@ inline bool IsShaderIn(TQualifier qualifier) case EvqNoPerspectiveIn: case EvqCentroidIn: case EvqSampleIn: + case EvqNoPerspectiveCentroidIn: + case EvqNoPerspectiveSampleIn: case EvqPatchIn: return true; default: @@ -1217,6 +1251,8 @@ inline bool IsShaderOut(TQualifier qualifier) case EvqNoPerspectiveOut: case EvqCentroidOut: case EvqSampleOut: + case EvqNoPerspectiveCentroidOut: + case EvqNoPerspectiveSampleOut: case EvqPatchOut: case EvqFragmentInOut: return true; @@ -1287,6 +1323,15 @@ enum TLayoutBlockStorage EbsLast = EbsStd430, }; +enum TLayoutDepth +{ + EdUnspecified, + EdAny, + EdGreater, + EdLess, + EdUnchanged, +}; + enum TYuvCscStandardEXT { EycsUndefined, @@ -1364,7 +1409,7 @@ struct TLayoutQualifier earlyFragmentTests == false && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified && !localSize.isAnyValueSet() && imageInternalFormat == EiifUnspecified && primitiveType == EptUndefined && - invocations == 0 && maxVertices == -1 && vertices == 0 && + invocations == 0 && maxVertices == -1 && vertices == 0 && depth == EdUnspecified && tesPrimitiveType == EtetUndefined && tesVertexSpacingType == EtetUndefined && tesOrderingType == EtetUndefined && tesPointType == EtetUndefined && index == -1 && inputAttachmentIndex == -1 && noncoherent == false && @@ -1411,6 +1456,9 @@ struct TLayoutQualifier bool pushConstant; + // Depth layout qualifier + TLayoutDepth depth; + // Image format layout qualifier TLayoutImageInternalFormat imageInternalFormat; @@ -1459,6 +1507,7 @@ struct TLayoutQualifier binding(-1), offset(-1), pushConstant(false), + depth(EdUnspecified), imageInternalFormat(EiifUnspecified), numViews(-1), yuv(false), @@ -1534,98 +1583,104 @@ inline const char *getQualifierString(TQualifier q) // clang-format off switch(q) { - case EvqTemporary: return "Temporary"; - case EvqGlobal: return "Global"; - case EvqConst: return "const"; - case EvqAttribute: return "attribute"; - case EvqVaryingIn: return "varying"; - case EvqVaryingOut: return "varying"; - case EvqUniform: return "uniform"; - case EvqBuffer: return "buffer"; - case EvqPatch: return "patch"; - case EvqVertexIn: return "in"; - case EvqFragmentOut: return "out"; - case EvqVertexOut: return "out"; - case EvqFragmentIn: return "in"; - case EvqParamIn: return "in"; - case EvqParamOut: return "out"; - case EvqParamInOut: return "inout"; - case EvqParamConst: return "const"; - case EvqInstanceID: return "InstanceID"; - case EvqVertexID: return "VertexID"; - case EvqPosition: return "Position"; - case EvqPointSize: return "PointSize"; - case EvqDrawID: return "DrawID"; - case EvqFragCoord: return "FragCoord"; - case EvqFrontFacing: return "FrontFacing"; - case EvqHelperInvocation: return "HelperInvocation"; - case EvqPointCoord: return "PointCoord"; - case EvqFragColor: return "FragColor"; - case EvqFragData: return "FragData"; - case EvqFragDepth: return "FragDepth"; - case EvqSecondaryFragColorEXT: return "SecondaryFragColorEXT"; - case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT"; - case EvqViewIDOVR: return "ViewIDOVR"; - case EvqViewportIndex: return "ViewportIndex"; - case EvqLayerOut: return "LayerOut"; - case EvqLayerIn: return "LayerIn"; - case EvqLastFragColor: return "LastFragColor"; - case EvqLastFragData: return "LastFragData"; - case EvqFragmentInOut: return "inout"; - case EvqSmoothOut: return "smooth out"; - case EvqCentroidOut: return "smooth centroid out"; - case EvqFlatOut: return "flat out"; - case EvqNoPerspectiveOut: return "noperspective out"; - case EvqSmoothIn: return "smooth in"; - case EvqFlatIn: return "flat in"; - case EvqNoPerspectiveIn: return "noperspective in"; - case EvqCentroidIn: return "smooth centroid in"; - case EvqCentroid: return "centroid"; - case EvqFlat: return "flat"; - case EvqNoPerspective: return "noperspective"; - case EvqSmooth: return "smooth"; - case EvqShared: return "shared"; - case EvqComputeIn: return "in"; - case EvqNumWorkGroups: return "NumWorkGroups"; - case EvqWorkGroupSize: return "WorkGroupSize"; - case EvqWorkGroupID: return "WorkGroupID"; - case EvqLocalInvocationID: return "LocalInvocationID"; - case EvqGlobalInvocationID: return "GlobalInvocationID"; - case EvqLocalInvocationIndex: return "LocalInvocationIndex"; - case EvqReadOnly: return "readonly"; - case EvqWriteOnly: return "writeonly"; - case EvqGeometryIn: return "in"; - case EvqGeometryOut: return "out"; - case EvqPerVertexIn: return "gl_in"; - case EvqPrimitiveIDIn: return "gl_PrimitiveIDIn"; - case EvqInvocationID: return "gl_InvocationID"; - case EvqPrimitiveID: return "gl_PrimitiveID"; - case EvqPrecise: return "precise"; - case EvqClipDistance: return "ClipDistance"; - case EvqCullDistance: return "CullDistance"; - case EvqSample: return "sample"; - case EvqSampleIn: return "sample in"; - case EvqSampleOut: return "sample out"; - case EvqSampleID: return "SampleID"; - case EvqSamplePosition: return "SamplePosition"; - case EvqSampleMaskIn: return "SampleMaskIn"; - case EvqSampleMask: return "SampleMask"; - case EvqNumSamples: return "NumSamples"; - case EvqPatchIn: return "patch in"; - case EvqPatchOut: return "patch out"; - case EvqTessControlIn: return "in"; - case EvqTessControlOut: return "out"; - case EvqPerVertexOut: return "out"; - case EvqPatchVerticesIn: return "PatchVerticesIn"; - case EvqTessLevelOuter: return "TessLevelOuter"; - case EvqTessLevelInner: return "TessLevelInner"; - case EvqBoundingBox: return "BoundingBox"; - case EvqTessEvaluationIn: return "in"; - case EvqTessEvaluationOut: return "out"; - case EvqTessCoord: return "TessCoord"; - case EvqSpecConst: return "const"; - case EvqPixelLocalEXT: return "__pixel_localEXT"; - default: UNREACHABLE(); return "unknown qualifier"; + case EvqTemporary: return "Temporary"; + case EvqGlobal: return "Global"; + case EvqConst: return "const"; + case EvqAttribute: return "attribute"; + case EvqVaryingIn: return "varying"; + case EvqVaryingOut: return "varying"; + case EvqUniform: return "uniform"; + case EvqBuffer: return "buffer"; + case EvqPatch: return "patch"; + case EvqVertexIn: return "in"; + case EvqFragmentOut: return "out"; + case EvqVertexOut: return "out"; + case EvqFragmentIn: return "in"; + case EvqParamIn: return "in"; + case EvqParamOut: return "out"; + case EvqParamInOut: return "inout"; + case EvqParamConst: return "const"; + case EvqInstanceID: return "InstanceID"; + case EvqVertexID: return "VertexID"; + case EvqPosition: return "Position"; + case EvqPointSize: return "PointSize"; + case EvqDrawID: return "DrawID"; + case EvqFragCoord: return "FragCoord"; + case EvqFrontFacing: return "FrontFacing"; + case EvqHelperInvocation: return "HelperInvocation"; + case EvqPointCoord: return "PointCoord"; + case EvqFragColor: return "FragColor"; + case EvqFragData: return "FragData"; + case EvqFragDepth: return "FragDepth"; + case EvqSecondaryFragColorEXT: return "SecondaryFragColorEXT"; + case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT"; + case EvqViewIDOVR: return "ViewIDOVR"; + case EvqViewportIndex: return "ViewportIndex"; + case EvqLayerOut: return "LayerOut"; + case EvqLayerIn: return "LayerIn"; + case EvqLastFragColor: return "LastFragColor"; + case EvqLastFragData: return "LastFragData"; + case EvqFragmentInOut: return "inout"; + case EvqSmoothOut: return "smooth out"; + case EvqCentroidOut: return "smooth centroid out"; + case EvqFlatOut: return "flat out"; + case EvqNoPerspectiveOut: return "noperspective out"; + case EvqNoPerspectiveCentroidOut: return "noperspective centroid out"; + case EvqNoPerspectiveSampleOut: return "noperspective sample out"; + case EvqSmoothIn: return "smooth in"; + case EvqFlatIn: return "flat in"; + case EvqNoPerspectiveIn: return "noperspective in"; + case EvqNoPerspectiveCentroidIn: return "noperspective centroid in"; + case EvqNoPerspectiveSampleIn: return "noperspective sample in"; + case EvqCentroidIn: return "smooth centroid in"; + case EvqCentroid: return "centroid"; + case EvqFlat: return "flat"; + case EvqNoPerspective: return "noperspective"; + case EvqNoPerspectiveCentroid: return "noperspective centroid"; + case EvqNoPerspectiveSample: return "noperspective sample"; + case EvqSmooth: return "smooth"; + case EvqShared: return "shared"; + case EvqComputeIn: return "in"; + case EvqNumWorkGroups: return "NumWorkGroups"; + case EvqWorkGroupSize: return "WorkGroupSize"; + case EvqWorkGroupID: return "WorkGroupID"; + case EvqLocalInvocationID: return "LocalInvocationID"; + case EvqGlobalInvocationID: return "GlobalInvocationID"; + case EvqLocalInvocationIndex: return "LocalInvocationIndex"; + case EvqReadOnly: return "readonly"; + case EvqWriteOnly: return "writeonly"; + case EvqGeometryIn: return "in"; + case EvqGeometryOut: return "out"; + case EvqPerVertexIn: return "gl_in"; + case EvqPrimitiveIDIn: return "gl_PrimitiveIDIn"; + case EvqInvocationID: return "gl_InvocationID"; + case EvqPrimitiveID: return "gl_PrimitiveID"; + case EvqPrecise: return "precise"; + case EvqClipDistance: return "ClipDistance"; + case EvqCullDistance: return "CullDistance"; + case EvqSample: return "sample"; + case EvqSampleIn: return "sample in"; + case EvqSampleOut: return "sample out"; + case EvqSampleID: return "SampleID"; + case EvqSamplePosition: return "SamplePosition"; + case EvqSampleMaskIn: return "SampleMaskIn"; + case EvqSampleMask: return "SampleMask"; + case EvqNumSamples: return "NumSamples"; + case EvqPatchIn: return "patch in"; + case EvqPatchOut: return "patch out"; + case EvqTessControlIn: return "in"; + case EvqTessControlOut: return "out"; + case EvqPerVertexOut: return "out"; + case EvqPatchVerticesIn: return "PatchVerticesIn"; + case EvqTessLevelOuter: return "TessLevelOuter"; + case EvqTessLevelInner: return "TessLevelInner"; + case EvqBoundingBox: return "BoundingBox"; + case EvqTessEvaluationIn: return "in"; + case EvqTessEvaluationOut: return "out"; + case EvqTessCoord: return "TessCoord"; + case EvqSpecConst: return "const"; + case EvqPixelLocalEXT: return "__pixel_localEXT"; + default: UNREACHABLE(); return "unknown qualifier"; } // clang-format on } @@ -1702,6 +1757,26 @@ inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq) } } +inline const char *getDepthString(TLayoutDepth depth) +{ + switch (depth) + { + case EdUnspecified: + return "depth_unspecified"; + case EdAny: + return "depth_any"; + case EdGreater: + return "depth_greater"; + case EdLess: + return "depth_less"; + case EdUnchanged: + return "depth_unchanged"; + default: + UNREACHABLE(); + return "unknown depth"; + } +} + inline TYuvCscStandardEXT getYuvCscStandardEXT(const ImmutableString &str) { if (str == "itu_601") diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BuildSPIRV.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/BuildSPIRV.cpp index 479875974984..c9b883564181 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BuildSPIRV.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BuildSPIRV.cpp @@ -349,6 +349,22 @@ spv::ExecutionMode GetTessEvalOrderingExecutionMode(TLayoutTessEvaluationType or return {}; } } + +void WriteInterpolationDecoration(spv::Decoration decoration, + spirv::IdRef id, + uint32_t fieldIndex, + spirv::Blob *decorationsBlob) +{ + if (fieldIndex != std::numeric_limits::max()) + { + spirv::WriteMemberDecorate(decorationsBlob, id, spirv::LiteralInteger(fieldIndex), + decoration, {}); + } + else + { + spirv::WriteDecorate(decorationsBlob, id, decoration, {}); + } +} } // anonymous namespace void SpirvTypeSpec::inferDefaults(const TType &type, TCompiler *compiler) @@ -2038,8 +2054,6 @@ void SPIRVBuilder::writeInterpolationDecoration(TQualifier qualifier, spirv::IdRef id, uint32_t fieldIndex) { - spv::Decoration decoration = spv::DecorationMax; - switch (qualifier) { case EvqSmooth: @@ -2051,40 +2065,50 @@ void SPIRVBuilder::writeInterpolationDecoration(TQualifier qualifier, case EvqFlat: case EvqFlatOut: case EvqFlatIn: - decoration = spv::DecorationFlat; - break; + WriteInterpolationDecoration(spv::DecorationFlat, id, fieldIndex, &mSpirvDecorations); + return; case EvqNoPerspective: case EvqNoPerspectiveOut: case EvqNoPerspectiveIn: - decoration = spv::DecorationNoPerspective; - break; + WriteInterpolationDecoration(spv::DecorationNoPerspective, id, fieldIndex, + &mSpirvDecorations); + return; case EvqCentroid: case EvqCentroidOut: case EvqCentroidIn: - decoration = spv::DecorationCentroid; - break; + WriteInterpolationDecoration(spv::DecorationCentroid, id, fieldIndex, + &mSpirvDecorations); + return; case EvqSample: case EvqSampleOut: case EvqSampleIn: - decoration = spv::DecorationSample; + WriteInterpolationDecoration(spv::DecorationSample, id, fieldIndex, &mSpirvDecorations); addCapability(spv::CapabilitySampleRateShading); - break; + return; - default: + case EvqNoPerspectiveCentroid: + case EvqNoPerspectiveCentroidOut: + case EvqNoPerspectiveCentroidIn: + WriteInterpolationDecoration(spv::DecorationNoPerspective, id, fieldIndex, + &mSpirvDecorations); + WriteInterpolationDecoration(spv::DecorationCentroid, id, fieldIndex, + &mSpirvDecorations); return; - } - if (fieldIndex != std::numeric_limits::max()) - { - spirv::WriteMemberDecorate(&mSpirvDecorations, id, spirv::LiteralInteger(fieldIndex), - decoration, {}); - } - else - { - spirv::WriteDecorate(&mSpirvDecorations, id, decoration, {}); + case EvqNoPerspectiveSample: + case EvqNoPerspectiveSampleOut: + case EvqNoPerspectiveSampleIn: + WriteInterpolationDecoration(spv::DecorationNoPerspective, id, fieldIndex, + &mSpirvDecorations); + WriteInterpolationDecoration(spv::DecorationSample, id, fieldIndex, &mSpirvDecorations); + addCapability(spv::CapabilitySampleRateShading); + return; + + default: + return; } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/CollectVariables.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/CollectVariables.cpp index ff9c03719975..d0c03a74b123 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/CollectVariables.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/CollectVariables.cpp @@ -916,8 +916,10 @@ ShaderVariable CollectVariablesTraverser::recordVarying(const TIntermSymbol &var case EvqFlatOut: case EvqNoPerspectiveOut: case EvqCentroidOut: - case EvqGeometryOut: case EvqSampleOut: + case EvqNoPerspectiveCentroidOut: + case EvqNoPerspectiveSampleOut: + case EvqGeometryOut: if (mSymbolTable->isVaryingInvariant(variable.variable()) || type.isInvariant()) { varying.isInvariant = true; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp index 37ca80a2869e..4b972a575f31 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp @@ -1392,6 +1392,7 @@ void TCompiler::setResourceString() << ":MaxCallStackDepth:" << mResources.MaxCallStackDepth << ":MaxFunctionParameters:" << mResources.MaxFunctionParameters << ":EXT_blend_func_extended:" << mResources.EXT_blend_func_extended + << ":EXT_conservative_depth:" << mResources.EXT_conservative_depth << ":EXT_frag_depth:" << mResources.EXT_frag_depth << ":EXT_primitive_bounding_box:" << mResources.EXT_primitive_bounding_box << ":OES_primitive_bounding_box:" << mResources.OES_primitive_bounding_box diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.cpp index 927272c5e14d..91d20545514f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.cpp @@ -26,6 +26,7 @@ OP(ARM_shader_framebuffer_fetch, 100, 320) \ OP(EXT_blend_func_extended, 100, 320) \ OP(EXT_clip_cull_distance, 300, 320) \ + OP(EXT_conservative_depth, 300, 320) \ OP(EXT_draw_buffers, 100, 100) \ OP(EXT_frag_depth, 100, 100) \ OP(EXT_geometry_shader, 310, 320) \ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h index 70cbef656b48..b2e1a5ff7cef 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h @@ -32,6 +32,7 @@ enum class TExtension : uint8_t EXT_YUV_target, EXT_blend_func_extended, EXT_clip_cull_distance, + EXT_conservative_depth, EXT_draw_buffers, EXT_frag_depth, EXT_geometry_shader, diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp index ccfdcb45b697..1087309a88e6 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp @@ -37,6 +37,10 @@ void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavi { extBehavior[TExtension::EXT_blend_func_extended] = EBhUndefined; } + if (resources.EXT_conservative_depth) + { + extBehavior[TExtension::EXT_conservative_depth] = EBhUndefined; + } if (resources.EXT_draw_buffers) { extBehavior[TExtension::EXT_draw_buffers] = EBhUndefined; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp index 87f5a74a16e7..8f2e3ea65b60 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp @@ -176,6 +176,12 @@ std::string TOutputGLSLBase::getCommonLayoutQualifiers(TIntermSymbol *variable) const TType &type = variable->getType(); const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier(); + if (type.getQualifier() == EvqFragDepth) + { + ASSERT(layoutQualifier.depth != EdUnspecified); + out << listItemPrefix << getDepthString(layoutQualifier.depth); + } + if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqFragmentInOut) { if (layoutQualifier.index >= 0) @@ -360,6 +366,12 @@ const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier) return "smooth in"; case EvqCentroidOut: return "smooth out"; + case EvqNoPerspectiveCentroid: + return "noperspective"; + case EvqNoPerspectiveCentroidIn: + return "noperspective in"; + case EvqNoPerspectiveCentroidOut: + return "noperspective out"; default: break; } @@ -388,6 +400,9 @@ const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier) ? (mShaderType == GL_FRAGMENT_SHADER ? "in" : "out") : "varying"; + case EvqFragDepth: + return "out"; + // gl_LastFragColor / gl_LastFragData have no qualifiers. case EvqLastFragData: case EvqLastFragColor: @@ -1262,6 +1277,12 @@ const char *getVariableInterpolation(TQualifier qualifier) return "noperspective out "; case EvqCentroidOut: return "centroid out "; + case EvqSampleOut: + return "sample out "; + case EvqNoPerspectiveCentroidOut: + return "noperspective centroid out "; + case EvqNoPerspectiveSampleOut: + return "noperspective sample out "; case EvqSmoothIn: return "smooth in "; case EvqFlatIn: @@ -1270,6 +1291,12 @@ const char *getVariableInterpolation(TQualifier qualifier) return "noperspective in "; case EvqCentroidIn: return "centroid in "; + case EvqSampleIn: + return "sample in "; + case EvqNoPerspectiveCentroidIn: + return "noperspective centroid in "; + case EvqNoPerspectiveSampleIn: + return "noperspective sample in "; default: break; } @@ -1441,6 +1468,11 @@ bool TOutputGLSLBase::needsToWriteLayoutQualifier(const TType &type) } } + if (type.getQualifier() == EvqFragDepth && layoutQualifier.depth != EdUnspecified) + { + return true; + } + if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqFragmentInOut) { if (layoutQualifier.index >= 0) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp index a8174e6f13f4..749fd25d0b8d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp @@ -363,6 +363,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, mUseZeroArray = false; mUsesSecondaryColor = false; + mDepthLayout = EdUnspecified; + mUniqueIndex = 0; mOutputLod0Function = false; @@ -1202,7 +1204,18 @@ void OutputHLSL::header(TInfoSinkBase &out, if (mUsesFragDepth) { - out << "#define GL_USES_FRAG_DEPTH\n"; + switch (mDepthLayout) + { + case EdGreater: + out << "#define GL_USES_FRAG_DEPTH_GREATER\n"; + break; + case EdLess: + out << "#define GL_USES_FRAG_DEPTH_LESS\n"; + break; + default: + out << "#define GL_USES_FRAG_DEPTH\n"; + break; + } } if (mUsesDepthRange) @@ -1383,6 +1396,7 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) else if (name == "gl_FragDepthEXT" || name == "gl_FragDepth") { mUsesFragDepth = true; + mDepthLayout = variableType.getLayoutQualifier().depth; out << "gl_Depth"; } else if (qualifier == EvqNumWorkGroups) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h index cd41c1aa9ef8..5ff88ec41be7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h @@ -224,6 +224,8 @@ class OutputHLSL : public TIntermTraverser int mNumRenderTargets; int mMaxDualSourceDrawBuffers; + TLayoutDepth mDepthLayout; + int mUniqueIndex; // For creating unique names CallDAG mCallDag; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputSPIRV.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputSPIRV.cpp index 86a2320c723a..a3d55e257fe6 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputSPIRV.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputSPIRV.cpp @@ -552,6 +552,20 @@ spirv::IdRef OutputSPIRVTraverser::getSymbolIdAndStorageClass(const TSymbol *sym name = "gl_FragDepth"; builtInDecoration = spv::BuiltInFragDepth; mBuilder.addExecutionMode(spv::ExecutionModeDepthReplacing); + switch (type.getLayoutQualifier().depth) + { + case EdGreater: + mBuilder.addExecutionMode(spv::ExecutionModeDepthGreater); + break; + case EdLess: + mBuilder.addExecutionMode(spv::ExecutionModeDepthLess); + break; + case EdUnchanged: + mBuilder.addExecutionMode(spv::ExecutionModeDepthUnchanged); + break; + default: + break; + } break; case EvqSampleMask: name = "gl_SampleMask"; @@ -1759,7 +1773,7 @@ spirv::IdRef OutputSPIRVTraverser::createConstructorMatrixFromMatrix( const bool needsSwizzle = parameterType.getRows() > type.getRows(); spirv::LiteralIntegerList swizzle = {spirv::LiteralInteger(0), spirv::LiteralInteger(1), spirv::LiteralInteger(2), spirv::LiteralInteger(3)}; - swizzle.resize(type.getRows()); + swizzle.resize_down(type.getRows()); for (uint8_t columnIndex = 0; columnIndex < type.getCols(); ++columnIndex) { @@ -5868,7 +5882,8 @@ bool OutputSPIRVTraverser::visitDeclaration(Visit visit, TIntermDeclaration *nod } // Skip redeclaration of builtins. They will correctly declare as built-in on first use. - if (mInGlobalScope && (qualifier == EvqClipDistance || qualifier == EvqCullDistance)) + if (mInGlobalScope && + (qualifier == EvqClipDistance || qualifier == EvqCullDistance || qualifier == EvqFragDepth)) { return false; } @@ -6041,6 +6056,16 @@ bool OutputSPIRVTraverser::visitDeclaration(Visit visit, TIntermDeclaration *nod const spv::Decoration decoration = type.getQualifier() == EvqUniform ? spv::DecorationBlock : spv::DecorationBufferBlock; spirv::WriteDecorate(mBuilder.getSpirvDecorations(), nonArrayTypeId, decoration, {}); + + if (type.getQualifier() == EvqBuffer && !memoryQualifier.restrictQualifier && + mCompileOptions.aliasedSSBOUnlessRestrict) + { + // Temporary workaround for issuetracker.google.com/266235549 + // If GLSL does not specify the SSBO has restrict memory qualifier, assume the memory + // qualifier is aliased + spirv::WriteDecorate(mBuilder.getSpirvDecorations(), variableId, spv::DecorationAliased, + {}); + } } // Write DescriptorSet, Binding, Location etc decorations if necessary. diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp index b3d90a1a2791..1a12c3ba993a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp @@ -618,11 +618,13 @@ bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIn case EvqGeometryIn: case EvqTessControlIn: case EvqTessEvaluationIn: + case EvqSmoothIn: case EvqFlatIn: case EvqNoPerspectiveIn: - case EvqSmoothIn: case EvqCentroidIn: case EvqSampleIn: + case EvqNoPerspectiveCentroidIn: + case EvqNoPerspectiveSampleIn: message = "can't modify an input"; break; case EvqUniform: @@ -1329,6 +1331,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line, { case EvqClipDistance: case EvqCullDistance: + case EvqFragDepth: case EvqLastFragData: case EvqLastFragColor: symbolType = SymbolType::BuiltIn; @@ -1468,6 +1471,17 @@ bool TParseContext::declareVariable(const TSourceLoc &line, return false; } } + else if (isExtensionEnabled(TExtension::EXT_conservative_depth) && + mShaderType == GL_FRAGMENT_SHADER && identifier == "gl_FragDepth") + { + if (type->getBasicType() != EbtFloat || type->getNominalSize() != 1 || + type->getSecondarySize() != 1 || type->isArray()) + { + error(line, "gl_FragDepth can only be redeclared as float", identifier); + return false; + } + needsReservedCheck = false; + } else if (isExtensionEnabled(TExtension::EXT_separate_shader_objects) && mShaderType == GL_VERTEX_SHADER) { @@ -1670,6 +1684,11 @@ void TParseContext::declarationQualifierErrorCheck(const sh::TQualifier qualifie return; } + if (qualifier != EvqFragDepth) + { + checkDepthIsNotSpecified(location, layoutQualifier.depth); + } + if (qualifier == EvqFragmentOut) { if (layoutQualifier.location != -1 && layoutQualifier.yuv == true) @@ -2253,6 +2272,15 @@ void TParseContext::checkAttributeLocationInRange(const TSourceLoc &location, } } +void TParseContext::checkDepthIsNotSpecified(const TSourceLoc &location, TLayoutDepth depth) +{ + if (depth != EdUnspecified) + { + error(location, "invalid layout qualifier: only valid on gl_FragDepth", + getDepthString(depth)); + } +} + void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv) { if (yuv != false) @@ -2911,7 +2939,9 @@ TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &ty checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier.earlyFragmentTests); - if (returnType.qualifier == EvqSampleIn || returnType.qualifier == EvqSampleOut) + if (returnType.qualifier == EvqSampleIn || returnType.qualifier == EvqSampleOut || + returnType.qualifier == EvqNoPerspectiveSampleIn || + returnType.qualifier == EvqNoPerspectiveSampleOut) { mSampleQualifierSpecified = true; } @@ -3187,20 +3217,27 @@ void TParseContext::checkTessellationShaderUnsizedArraysAndSetSize(const TSource { case EvqTessControlIn: case EvqTessEvaluationIn: + case EvqSmoothIn: case EvqFlatIn: + case EvqNoPerspectiveIn: case EvqCentroidIn: - case EvqSmoothIn: case EvqSampleIn: + case EvqNoPerspectiveCentroidIn: + case EvqNoPerspectiveSampleIn: // Declaring an array size is optional. If no size is specified, it will be taken // from the implementation-dependent maximum patch size (gl_MaxPatchVertices). ASSERT(mMaxPatchVertices > 0); type->sizeOutermostUnsizedArray(mMaxPatchVertices); break; case EvqTessControlOut: + case EvqTessEvaluationOut: + case EvqSmoothOut: case EvqFlatOut: + case EvqNoPerspectiveOut: case EvqCentroidOut: - case EvqSmoothOut: case EvqSampleOut: + case EvqNoPerspectiveCentroidOut: + case EvqNoPerspectiveSampleOut: // Declaring an array size is optional. If no size is specified, it will be taken // from output patch size declared in the shader. If the patch size is not yet // declared, this is deferred until such time as it does. @@ -3274,10 +3311,23 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( } } + if (identifier == "gl_FragDepth") + { + if (type->getQualifier() == EvqFragmentOut) + { + type->setQualifier(EvqFragDepth); + } + else + { + error(identifierOrTypeLocation, + "gl_FragDepth can only be redeclared as fragment output", identifier); + } + } + checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier, type); checkTessellationShaderUnsizedArraysAndSetSize(identifierOrTypeLocation, identifier, type); - declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier, + declarationQualifierErrorCheck(type->getQualifier(), publicType.layoutQualifier, identifierOrTypeLocation); bool emptyDeclaration = (identifier == ""); @@ -3975,6 +4025,8 @@ void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &type checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat); + checkDepthIsNotSpecified(typeQualifier.line, layoutQualifier.depth); + checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv); checkOffsetIsNotSpecified(typeQualifier.line, layoutQualifier.offset); @@ -4809,6 +4861,7 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( typeQualifier.layoutQualifier.binding, arraySize); } + checkDepthIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.depth); checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv); checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.earlyFragmentTests); @@ -4884,14 +4937,20 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( } break; // a member variable in io block may have different interpolation. + case EvqSmoothIn: + case EvqSmoothOut: case EvqFlatIn: case EvqFlatOut: case EvqNoPerspectiveIn: case EvqNoPerspectiveOut: - case EvqSmoothIn: - case EvqSmoothOut: case EvqCentroidIn: case EvqCentroidOut: + case EvqSampleIn: + case EvqSampleOut: + case EvqNoPerspectiveCentroidIn: + case EvqNoPerspectiveCentroidOut: + case EvqNoPerspectiveSampleIn: + case EvqNoPerspectiveSampleOut: break; // a member variable can have an incomplete qualifier because shader io block has either // in or out. @@ -4899,6 +4958,9 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( case EvqFlat: case EvqNoPerspective: case EvqCentroid: + case EvqSample: + case EvqNoPerspectiveCentroid: + case EvqNoPerspectiveSample: case EvqGeometryIn: case EvqGeometryOut: if (!IsShaderIoBlock(typeQualifier.qualifier) && @@ -5757,6 +5819,22 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qual { qualifier.advancedBlendEquations.setAll(); } + else if (qualifierType == "depth_any") + { + qualifier.depth = EdAny; + } + else if (qualifierType == "depth_greater") + { + qualifier.depth = EdGreater; + } + else if (qualifierType == "depth_less") + { + qualifier.depth = EdLess; + } + else if (qualifierType == "depth_unchanged") + { + qualifier.depth = EdUnchanged; + } else { error(qualifierTypeLine, "invalid layout qualifier", qualifierType); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h index ee0cebe4f00f..ad92b4dd87de 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h @@ -602,6 +602,8 @@ class TParseContext : angle::NonCopyable int objectLocationCount, const TLayoutQualifier &layoutQualifier); + void checkDepthIsNotSpecified(const TSourceLoc &location, TLayoutDepth depth); + void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv); void checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location, bool earlyFragmentTests); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierTypes.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierTypes.cpp index e524146cd326..60b2b3f333af 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierTypes.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierTypes.cpp @@ -160,9 +160,10 @@ bool HasRepeatingQualifiers(const TTypeQualifierBuilder::QualifierSequence &qual } case QtInterpolation: { - // 'centroid' is treated as a storage qualifier - // 'flat centroid' will be squashed to 'flat' + // 'centroid' and 'sample' are treated as storage qualifiers + // 'flat centroid' and 'flat sample' will be squashed to 'flat' // 'smooth centroid' will be squashed to 'centroid' + // 'smooth sample' will be squashed to 'sample' if (interpolationFound) { *errorMessage = kInterpolationMultipleTimes; @@ -371,6 +372,9 @@ bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storag case EvqCentroid: *joinedQualifier = EvqCentroid; break; + case EvqSample: + *joinedQualifier = EvqSample; + break; case EvqVertexOut: case EvqGeometryOut: case EvqTessControlOut: @@ -393,6 +397,7 @@ bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storag switch (storageQualifier) { case EvqCentroid: + case EvqSample: *joinedQualifier = EvqFlat; break; case EvqVertexOut: @@ -417,7 +422,10 @@ bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storag switch (storageQualifier) { case EvqCentroid: - *joinedQualifier = EvqNoPerspective; + *joinedQualifier = EvqNoPerspectiveCentroid; + break; + case EvqSample: + *joinedQualifier = EvqNoPerspectiveSample; break; case EvqVertexOut: case EvqGeometryOut: @@ -478,6 +486,48 @@ bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storag } break; } + case EvqNoPerspectiveCentroid: + { + switch (storageQualifier) + { + case EvqVertexOut: + case EvqGeometryOut: + case EvqTessControlOut: + case EvqTessEvaluationOut: + *joinedQualifier = EvqNoPerspectiveCentroidOut; + break; + case EvqFragmentIn: + case EvqGeometryIn: + case EvqTessControlIn: + case EvqTessEvaluationIn: + *joinedQualifier = EvqNoPerspectiveCentroidIn; + break; + default: + return false; + } + break; + } + case EvqNoPerspectiveSample: + { + switch (storageQualifier) + { + case EvqVertexOut: + case EvqGeometryOut: + case EvqTessControlOut: + case EvqTessEvaluationOut: + *joinedQualifier = EvqNoPerspectiveSampleOut; + break; + case EvqFragmentIn: + case EvqGeometryIn: + case EvqTessControlIn: + case EvqTessEvaluationIn: + *joinedQualifier = EvqNoPerspectiveSampleIn; + break; + default: + return false; + } + break; + } case EvqPatch: { switch (storageQualifier) @@ -713,6 +763,15 @@ TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier, joinedQualifier.location = rightQualifier.location; ++joinedQualifier.locationsSpecified; } + if (rightQualifier.depth != EdUnspecified) + { + if (joinedQualifier.depth != EdUnspecified) + { + diagnostics->error(rightQualifierLocation, "Cannot have multiple depth qualifiers", + getDepthString(rightQualifier.depth)); + } + joinedQualifier.depth = rightQualifier.depth; + } if (rightQualifier.yuv != false) { joinedQualifier.yuv = rightQualifier.yuv; @@ -886,9 +945,9 @@ unsigned int TLayoutQualifierWrapper::getRank() const unsigned int TStorageQualifierWrapper::getRank() const { - // Force the 'centroid' auxilary storage qualifier to be always first among all storage - // qualifiers. - if (mStorageQualifier == EvqCentroid) + // Force the 'centroid' and 'sample' auxilary storage qualifiers + // to be always first among all storage qualifiers. + if (mStorageQualifier == EvqCentroid || mStorageQualifier == EvqSample) { return 4u; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp index a622cc1924d6..2ab6455d8568 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp @@ -185,6 +185,7 @@ void InitBuiltInResources(ShBuiltInResources *resources) resources->NV_EGL_stream_consumer_external = 0; resources->ARB_texture_rectangle = 0; resources->EXT_blend_func_extended = 0; + resources->EXT_conservative_depth = 0; resources->EXT_draw_buffers = 0; resources->EXT_frag_depth = 0; resources->EXT_shader_texture_lod = 0; @@ -1066,6 +1067,10 @@ const char *InterpolationTypeToString(InterpolationType type) return "flat"; case InterpolationType::INTERPOLATION_NOPERSPECTIVE: return "noperspective"; + case InterpolationType::INTERPOLATION_NOPERSPECTIVE_CENTROID: + return "noperspective centroid"; + case InterpolationType::INTERPOLATION_NOPERSPECTIVE_SAMPLE: + return "noperspective sample"; default: return "invalid"; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.cpp index 2bdf08fa5f0b..94278a004254 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.cpp @@ -24,4 +24,9 @@ bool TSymbolUniqueId::operator==(const TSymbolUniqueId &other) const return mId == other.mId; } +bool TSymbolUniqueId::operator!=(const TSymbolUniqueId &other) const +{ + return !(*this == other); +} + } // namespace sh diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.h b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.h index 7e0312d05499..6f8ecef1ed2e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolUniqueId.h @@ -22,8 +22,9 @@ class TSymbolUniqueId POOL_ALLOCATOR_NEW_DELETE explicit TSymbolUniqueId(const TSymbol &symbol); constexpr TSymbolUniqueId(const TSymbolUniqueId &) = default; - TSymbolUniqueId &operator =(const TSymbolUniqueId &); + TSymbolUniqueId &operator=(const TSymbolUniqueId &); bool operator==(const TSymbolUniqueId &) const; + bool operator!=(const TSymbolUniqueId &) const; constexpr int get() const { return mId; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp index 9738aa3fce6c..9bc78d07827f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp @@ -313,6 +313,20 @@ void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root, sink << "#extension GL_ARB_cull_distance : " << GetBehaviorString(iter.second) << "\n"; } + if (getOutputType() != SH_ESSL_OUTPUT && iter.first == TExtension::EXT_conservative_depth && + getOutputType() < SH_GLSL_420_CORE_OUTPUT) + { + sink << "#extension GL_ARB_conservative_depth : " << GetBehaviorString(iter.second) + << "\n"; + } + + if (getOutputType() != SH_ESSL_OUTPUT && iter.first == TExtension::OES_sample_variables && + getOutputType() < SH_GLSL_420_CORE_OUTPUT) + { + sink << "#extension GL_ARB_sample_shading : " << GetBehaviorString(iter.second) << "\n" + << "#extension GL_ARB_gpu_shader5 : " << GetBehaviorString(iter.second) << "\n"; + } + if ((iter.first == TExtension::OES_texture_cube_map_array || iter.first == TExtension::EXT_texture_cube_map_array) && (iter.second == EBhRequire || iter.second == EBhEnable)) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.cpp index 627a54ba7bd7..8541f74e0021 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.cpp @@ -297,6 +297,13 @@ void AddFragColorDeclaration(TIntermBlock &root, TSymbolTable &symbolTable, cons void AddFragDepthDeclaration(TIntermBlock &root, TSymbolTable &symbolTable) { + // Check if the variable has been already declared. + const TIntermSymbol *fragDepthBuiltIn = new TIntermSymbol(BuiltInVariable::gl_FragDepth()); + const TIntermSymbol *fragDepthSymbol = FindSymbolNode(&root, ImmutableString("gl_FragDepth")); + if (fragDepthSymbol && fragDepthSymbol->uniqueId() != fragDepthBuiltIn->uniqueId()) + { + return; + } root.insertChildNodes(FindMainIndex(&root), TIntermSequence{new TIntermDeclaration{BuiltInVariable::gl_FragDepth()}}); } @@ -633,7 +640,10 @@ bool TranslatorMetalDirect::transformDepthBeforeCorrection(TIntermBlock *root, // z_metal = 0.5 * (w_gl + z_gl) // // where z_metal is the depth output of a Metal vertex shader and z_gl is the same for GL. -bool TranslatorMetalDirect::appendVertexShaderDepthCorrectionToMain(TIntermBlock *root) +// This operation is skipped when GL_CLIP_DEPTH_MODE_EXT is set to GL_ZERO_TO_ONE_EXT. +bool TranslatorMetalDirect::appendVertexShaderDepthCorrectionToMain( + TIntermBlock *root, + const DriverUniformMetal *driverUniforms) { const TVariable *position = BuiltInVariable::gl_Position(); TIntermSymbol *positionRef = new TIntermSymbol(position); @@ -654,8 +664,13 @@ bool TranslatorMetalDirect::appendVertexShaderDepthCorrectionToMain(TIntermBlock TIntermTyped *positionZLHS = positionZ->deepCopy(); TIntermBinary *assignment = new TIntermBinary(TOperator::EOpAssign, positionZLHS, halfZPlusW); + // Apply depth correction if needed + TIntermBlock *block = new TIntermBlock; + block->appendStatement(assignment); + TIntermIfElse *ifCall = new TIntermIfElse(driverUniforms->getTransformDepth(), block, nullptr); + // Append the assignment as a statement at the end of the shader. - return RunAtTheEndOfShader(this, root, assignment, &getSymbolTable()); + return RunAtTheEndOfShader(this, root, ifCall, &getSymbolTable()); } static inline MetalShaderType metalShaderTypeFromGLSL(sh::GLenum shaderType) @@ -1044,7 +1059,7 @@ bool TranslatorMetalDirect::translateImpl(TInfoSinkBase &sink, return false; } - if (!appendVertexShaderDepthCorrectionToMain(root)) + if (!appendVertexShaderDepthCorrectionToMain(root, driverUniforms)) { return false; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.h b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.h index b465860c2762..ddb4f89828ce 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect.h @@ -209,7 +209,9 @@ class TranslatorMetalDirect : public TCompiler [[nodiscard]] bool transformDepthBeforeCorrection(TIntermBlock *root, const DriverUniformMetal *driverUniforms); - [[nodiscard]] bool appendVertexShaderDepthCorrectionToMain(TIntermBlock *root); + [[nodiscard]] bool appendVertexShaderDepthCorrectionToMain( + TIntermBlock *root, + const DriverUniformMetal *driverUniforms); [[nodiscard]] bool insertSampleMaskWritingLogic(TIntermBlock &root, DriverUniformMetal &driverUniforms); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/EmitMetal.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/EmitMetal.cpp index 4257aee0eafd..3e1b095abe79 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/EmitMetal.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/EmitMetal.cpp @@ -1093,6 +1093,27 @@ void GenMetalTraverser::emitFieldDeclaration(const TField &field, } break; + case TQualifier::EvqNoPerspectiveIn: + if (mPipelineStructs.fragmentIn.external == &parent) + { + mOut << " [[center_no_perspective]]"; + } + break; + + case TQualifier::EvqCentroidIn: + if (mPipelineStructs.fragmentIn.external == &parent) + { + mOut << " [[centroid_perspective]]"; + } + break; + + case TQualifier::EvqNoPerspectiveCentroidIn: + if (mPipelineStructs.fragmentIn.external == &parent) + { + mOut << " [[centroid_no_perspective]]"; + } + break; + case TQualifier::EvqFragColor: mOut << " [[color(0)]]"; break; @@ -1152,8 +1173,20 @@ void GenMetalTraverser::emitFieldDeclaration(const TField &field, break; case TQualifier::EvqFragDepth: - mOut << " [[depth(any), function_constant(" << sh::mtl::kDepthWriteEnabledConstName - << ")]]"; + mOut << " [[depth("; + switch (type.getLayoutQualifier().depth) + { + case EdGreater: + mOut << "greater"; + break; + case EdLess: + mOut << "less"; + break; + default: + mOut << "any"; + break; + } + mOut << "), function_constant(" << sh::mtl::kDepthWriteEnabledConstName << ")]]"; break; case TQualifier::EvqSampleMask: diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/Pipeline.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/Pipeline.cpp index b0bc65c388a4..046315db58d2 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/Pipeline.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/Pipeline.cpp @@ -43,15 +43,16 @@ bool Pipeline::uses(const TVariable &var) const case Type::VertexOut: switch (qualifier) { + case TQualifier::EvqVaryingOut: case TQualifier::EvqVertexOut: case TQualifier::EvqPosition: - case TQualifier::EvqClipDistance: - case TQualifier::EvqFlatOut: case TQualifier::EvqPointSize: + case TQualifier::EvqClipDistance: case TQualifier::EvqSmoothOut: - case TQualifier::EvqCentroidOut: + case TQualifier::EvqFlatOut: case TQualifier::EvqNoPerspectiveOut: - case TQualifier::EvqVaryingOut: + case TQualifier::EvqCentroidOut: + case TQualifier::EvqNoPerspectiveCentroidOut: return true; default: return false; @@ -60,12 +61,13 @@ bool Pipeline::uses(const TVariable &var) const case Type::FragmentIn: switch (qualifier) { + case TQualifier::EvqVaryingIn: case TQualifier::EvqFragmentIn: - case TQualifier::EvqFlatIn: case TQualifier::EvqSmoothIn: - case TQualifier::EvqCentroidIn: + case TQualifier::EvqFlatIn: case TQualifier::EvqNoPerspectiveIn: - case TQualifier::EvqVaryingIn: + case TQualifier::EvqCentroidIn: + case TQualifier::EvqNoPerspectiveCentroidIn: return true; default: return false; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/ToposortStructs.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/ToposortStructs.cpp index b56c93c97866..19dfc595449f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/ToposortStructs.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorMetalDirect/ToposortStructs.cpp @@ -4,6 +4,7 @@ // found in the LICENSE file. // +#include #include #include #include @@ -28,6 +29,11 @@ using Edges = std::unordered_set; template using Graph = std::unordered_map>; +struct EdgeComparator +{ + bool operator()(const TStructure *s1, const TStructure *s2) { return s2->name() < s1->name(); } +}; + void BuildGraphImpl(SymbolEnv &symbolEnv, Graph &g, const TStructure *s) { if (g.find(s) != g.end()) @@ -61,7 +67,21 @@ Graph BuildGraph(SymbolEnv &symbolEnv, return g; } +std::vector SortEdges(const std::unordered_set &structs) +{ + std::vector sorted; + sorted.reserve(structs.size()); + sorted.insert(sorted.begin(), structs.begin(), structs.end()); + std::sort(sorted.begin(), sorted.end(), EdgeComparator()); + return sorted; +} + // Algorthm: https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search +// Note that the algorithm is modified to visit nodes in sorted order. This +// ensures consistent results. Without this, the returned order (in so far as +// leaf nodes) is undefined, because iterating over an unordered_set of pointers +// depends upon the actual pointer values. Consistent results is important for +// code that keys off the string of shaders for caching. template std::vector Toposort(const Graph &g) { @@ -99,8 +119,9 @@ std::vector Toposort(const Graph &g) // for each node m with an edge from n to m do auto enIter = g.find(n); ASSERT(enIter != g.end()); - const Edges &en = enIter->second; - for (T m : en) + + std::vector sorted = SortEdges(enIter->second); + for (T m : sorted) { // visit(m) visit(m); @@ -118,7 +139,8 @@ std::vector Toposort(const Graph &g) while (!invPerms.empty()) { // select an unmarked node n - T n = *invPerms.begin(); + std::vector sorted = SortEdges(invPerms); + T n = *sorted.begin(); // visit(n) visit(n); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp index 5d9a573d7b33..0515e3fd7e2b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp @@ -1145,28 +1145,32 @@ const char *InterpolationString(TQualifier qualifier) { switch (qualifier) { - case EvqVaryingIn: - return ""; - case EvqFragmentIn: - return ""; - case EvqSmoothIn: - return "linear"; - case EvqFlatIn: - return "nointerpolation"; - case EvqCentroidIn: - return "centroid"; case EvqVaryingOut: - return ""; + case EvqVaryingIn: case EvqVertexOut: + case EvqFragmentIn: return ""; case EvqSmoothOut: + case EvqSmoothIn: return "linear"; case EvqFlatOut: + case EvqFlatIn: return "nointerpolation"; + case EvqNoPerspectiveOut: + case EvqNoPerspectiveIn: + return "noperspective"; case EvqCentroidOut: + case EvqCentroidIn: return "centroid"; + case EvqSampleOut: case EvqSampleIn: return "sample"; + case EvqNoPerspectiveCentroidOut: + case EvqNoPerspectiveCentroidIn: + return "noperspective centroid"; + case EvqNoPerspectiveSampleOut: + case EvqNoPerspectiveSampleIn: + return "noperspective sample"; default: UNREACHABLE(); } @@ -1187,8 +1191,6 @@ const char *QualifierString(TQualifier qualifier) return "inout"; case EvqParamConst: return "const"; - case EvqSampleOut: - return "sample"; default: UNREACHABLE(); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateAST.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateAST.cpp index bd9389d2a164..b4a75a1c0ad5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateAST.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateAST.cpp @@ -640,6 +640,7 @@ void ValidateAST::visitBuiltInVariable(TIntermSymbol *node) if ((name == "gl_ClipDistance" && qualifier != EvqClipDistance) || (name == "gl_CullDistance" && qualifier != EvqCullDistance) || + (name == "gl_FragDepth" && qualifier != EvqFragDepth) || (name == "gl_LastFragData" && qualifier != EvqLastFragData) || (name == "gl_LastFragColorARM" && qualifier != EvqLastFragColor)) { diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateTypeSizeLimitations.cpp index c9607db74b53..6097b6d236b5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateTypeSizeLimitations.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateTypeSizeLimitations.cpp @@ -20,9 +20,13 @@ namespace sh namespace { -// Arbitrarily enforce that types - even local variables' - declared -// with a size in bytes of over 2 GB will cause compilation failure. -constexpr size_t kMaxTypeSizeInBytes = static_cast(2) * 1024 * 1024 * 1024; +// Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause +// compilation failure. +// +// For local and global variables, the limit is much lower (1MB) as that much memory won't fit in +// the GPU registers anyway. +constexpr size_t kMaxVariableSizeInBytes = static_cast(2) * 1024 * 1024 * 1024; +constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast(1) * 1024 * 1024; // Traverses intermediate tree to ensure that the shader does not // exceed certain implementation-defined limits on the sizes of types. @@ -78,13 +82,24 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser // whether the row-major layout is correctly determined. bool isRowMajorLayout = false; TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor); - if (layoutEncoder.getCurrentOffset() > kMaxTypeSizeInBytes) + if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes) { error(asSymbol->getLine(), "Size of declared variable exceeds implementation-defined limit", asSymbol->getName()); return false; } + + const bool isPrivate = variableType.getQualifier() == EvqTemporary || + variableType.getQualifier() == EvqGlobal || + variableType.getQualifier() == EvqConst; + if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate) + { + error(asSymbol->getLine(), + "Size of declared private variable exceeds implementation-defined limit", + asSymbol->getName()); + return false; + } } return true; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l index 993ca3ed9b29..fa8d1f4dbf2c 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l @@ -300,10 +300,6 @@ O [0-7] "image1DArray" | "iimage1DArray" | "uimage1DArray" | -"image1DShadow" | -"image2DShadow" | -"image1DArrayShadow" | -"image2DArrayShadow" | "sampler1DArray" | "sampler1DArrayShadow" | @@ -331,6 +327,20 @@ O [0-7] return reserved_word(yyscanner); } + /* Reserved keywords in WebGL that not reserved in GL */ +"image1DShadow" | +"image2DShadow" | +"image1DArrayShadow" | +"image2DArrayShadow" { + if(!IsWebGLBasedSpec(context->getShaderSpec())) + { + yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); + return check_type(yyscanner); + } + + return reserved_word(yyscanner); +} + /* Reserved keywords */ "asm" | diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex_autogen.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex_autogen.cpp index 0ac46a6d713d..3d792c6cd5af 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex_autogen.cpp @@ -459,7 +459,7 @@ static const flex_int16_t yy_accept[982] = { 133, 196, 196, 196, 173, 168, 136, 196, 196, 196, 196, 196, 196, 164, 196, 196, 196, 196, 196, 196, 97, 42, 45, 47, 46, 43, 49, 48, 50, 44, 196, 196, - 196, 196, 179, 155, 196, 196, 196, 166, 196, 196, 196, 38, 126, 29, 192, 23, 167, + 196, 196, 179, 151, 196, 196, 196, 166, 196, 196, 196, 38, 126, 29, 192, 23, 167, 96, 196, 177, 18, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 20, 37, 196, 196, 196, 196, 196, 196, 137, 102, 108, 196, 196, 196, 196, 196, 196, 99, 101, 3, 196, 196, 196, 196, 196, 127, 196, 196, 196, 196, @@ -471,27 +471,27 @@ static const flex_int16_t yy_accept[982] = { 124, 196, 196, 196, 196, 6, 196, 196, 196, 196, 196, 196, 196, 196, 196, 113, 170, 1, 196, 196, 196, 196, 196, 196, 196, 194, 196, 134, 196, 5, 189, 63, 66, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 121, 196, 196, - 196, 196, 196, 196, 111, 196, 196, 196, 196, 196, 196, 196, 149, 71, 72, + 196, 196, 196, 196, 111, 196, 196, 196, 196, 196, 196, 196, 145, 71, 72, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 132, - 196, 196, 196, 112, 196, 151, 76, 77, 196, 196, 196, 196, 125, 196, 196, 196, 196, + 196, 196, 196, 112, 196, 147, 76, 77, 196, 196, 196, 196, 125, 196, 196, 196, 196, 196, 196, 196, 196, 117, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 70, 196, 196, 196, 196, 64, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 118, 196, 140, 196, 105, 196, 196, 196, 196, 196, 75, 196, 196, 73, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 119, 196, 196, 196, 196, 80, 196, 196, 78, 196, - 196, 141, 106, 196, 196, 143, 196, 144, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 141, 106, 196, 196, 152, 196, 153, 196, 196, 196, 196, 196, 196, 196, 196, 196, 24, 196, 196, 196, 196, 196, 68, 196, 67, 89, 196, 196, 196, 196, 142, 107, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 114, 196, 196, 196, 196, - 153, 92, 196, 196, 196, 147, 196, 69, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 154, 94, 196, 196, 196, 115, 196, 196, 196, 150, 74, 196, + 149, 92, 196, 196, 196, 143, 196, 69, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 150, 94, 196, 196, 196, 115, 196, 196, 196, 146, 74, 196, - 196, 196, 128, 196, 190, 196, 196, 196, 81, 196, 196, 196, 196, 116, 196, 152, 79, + 196, 196, 128, 196, 190, 196, 196, 196, 81, 196, 196, 196, 196, 116, 196, 148, 79, 196, 196, 196, 196, 196, 196, 129, 196, 196, 196, 196, 196, 85, 196, 88, 196, 196, 196, 130, 196, 196, 196, 196, 196, 196, 86, 91, 196, 196, 196, 196, 196, 82, 196, - 95, 87, 93, 98, 196, 145, 146, 100, 196, 196, 196, 196, 65, 196, 196, 196, 191, - 196, 196, 148, 83, 196, 196, 196, 196, 90, 196, 196, 84, 0}; + 95, 87, 93, 98, 196, 154, 155, 100, 196, 196, 196, 196, 65, 196, 196, 196, 191, + 196, 196, 144, 83, 196, 196, 196, 196, 90, 196, 196, 84, 0}; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, @@ -2180,10 +2180,6 @@ YY_DECL case 148: case 149: case 150: - case 151: - case 152: - case 153: - case 154: YY_RULE_SETUP { if (context->getShaderVersion() < 300) @@ -2195,7 +2191,7 @@ YY_DECL } YY_BREAK /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */ - case 155: + case 151: YY_RULE_SETUP { if (context->getShaderVersion() >= 300) @@ -2207,6 +2203,22 @@ YY_DECL return reserved_word(yyscanner); } YY_BREAK + /* Reserved keywords in WebGL that not reserved in GL */ + case 152: + case 153: + case 154: + case 155: + YY_RULE_SETUP + { + if (!IsWebGLBasedSpec(context->getShaderSpec())) + { + yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); + return check_type(yyscanner); + } + + return reserved_word(yyscanner); + } + YY_BREAK /* Reserved keywords */ case 156: case 157: diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/InitializeVariables.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/InitializeVariables.cpp index f3ac76f31de0..35d38df3322a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/InitializeVariables.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/InitializeVariables.cpp @@ -318,6 +318,37 @@ class InitializeLocalsTraverser : public TIntermTraverser return false; } + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override + { + // Initialize output function arguments as well, the parameter passed in at call time may be + // clobbered if the function doesn't fully write to the argument. + + TIntermSequence initCode; + + const TFunction *function = node->getFunction(); + for (size_t paramIndex = 0; paramIndex < function->getParamCount(); ++paramIndex) + { + const TVariable *paramVariable = function->getParam(paramIndex); + const TType ¶mType = paramVariable->getType(); + + if (paramType.getQualifier() != EvqParamOut) + { + continue; + } + + CreateInitCode(new TIntermSymbol(paramVariable), mCanUseLoopsToInitialize, + mHighPrecisionSupported, &initCode, mSymbolTable); + } + + if (!initCode.empty()) + { + TIntermSequence *body = node->getBody()->getSequence(); + body->insert(body->begin(), initCode.begin(), initCode.end()); + } + + return true; + } + private: int mShaderVersion; bool mCanUseLoopsToInitialize; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp index 309cb14752c4..d933bebaa096 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp @@ -23,12 +23,13 @@ namespace sh bool ClampFragDepth(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable) { // Only clamp gl_FragDepth if it's used in the shader. - if (!FindSymbolNode(root, ImmutableString("gl_FragDepth"))) + const TIntermSymbol *fragDepthSymbol = FindSymbolNode(root, ImmutableString("gl_FragDepth")); + if (!fragDepthSymbol) { return true; } - TIntermSymbol *fragDepthNode = new TIntermSymbol(BuiltInVariable::gl_FragDepth()); + TIntermSymbol *fragDepthNode = new TIntermSymbol(&fragDepthSymbol->variable()); TIntermTyped *minFragDepthNode = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst)); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp index 4eecd2d5ccad..a91f8b0dae55 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp @@ -74,6 +74,8 @@ bool IsInterpolationIn(TQualifier qualifier) case EvqNoPerspectiveIn: case EvqCentroidIn: case EvqSampleIn: + case EvqNoPerspectiveCentroidIn: + case EvqNoPerspectiveSampleIn: return true; default: return false; @@ -89,6 +91,8 @@ bool IsInterpolationOut(TQualifier qualifier) case EvqNoPerspectiveOut: case EvqCentroidOut: case EvqSampleOut: + case EvqNoPerspectiveCentroidOut: + case EvqNoPerspectiveSampleOut: return true; default: return false; @@ -467,15 +471,10 @@ bool IsVaryingOut(TQualifier qualifier) switch (qualifier) { case EvqVaryingOut: - case EvqSmoothOut: - case EvqFlatOut: - case EvqNoPerspectiveOut: - case EvqCentroidOut: case EvqVertexOut: case EvqGeometryOut: case EvqTessControlOut: case EvqTessEvaluationOut: - case EvqSampleOut: case EvqPatchOut: return true; @@ -483,7 +482,7 @@ bool IsVaryingOut(TQualifier qualifier) break; } - return false; + return IsInterpolationOut(qualifier); } bool IsVaryingIn(TQualifier qualifier) @@ -491,15 +490,10 @@ bool IsVaryingIn(TQualifier qualifier) switch (qualifier) { case EvqVaryingIn: - case EvqSmoothIn: - case EvqFlatIn: - case EvqNoPerspectiveIn: - case EvqCentroidIn: case EvqFragmentIn: case EvqGeometryIn: case EvqTessControlIn: case EvqTessEvaluationIn: - case EvqSampleIn: case EvqPatchIn: return true; @@ -507,7 +501,7 @@ bool IsVaryingIn(TQualifier qualifier) break; } - return false; + return IsInterpolationIn(qualifier); } bool IsVarying(TQualifier qualifier) @@ -574,6 +568,14 @@ InterpolationType GetInterpolationType(TQualifier qualifier) case EvqNoPerspectiveOut: return INTERPOLATION_NOPERSPECTIVE; + case EvqNoPerspectiveCentroidIn: + case EvqNoPerspectiveCentroidOut: + return INTERPOLATION_NOPERSPECTIVE_CENTROID; + + case EvqNoPerspectiveSampleIn: + case EvqNoPerspectiveSampleOut: + return INTERPOLATION_NOPERSPECTIVE_SAMPLE; + case EvqSmoothIn: case EvqSmoothOut: case EvqVertexOut: @@ -606,14 +608,20 @@ InterpolationType GetFieldInterpolationType(TQualifier qualifier) { switch (qualifier) { + case EvqSmooth: + return INTERPOLATION_SMOOTH; case EvqFlat: return INTERPOLATION_FLAT; case EvqNoPerspective: return INTERPOLATION_NOPERSPECTIVE; - case EvqSmooth: - return INTERPOLATION_SMOOTH; case EvqCentroid: return INTERPOLATION_CENTROID; + case EvqSample: + return INTERPOLATION_SAMPLE; + case EvqNoPerspectiveCentroid: + return INTERPOLATION_NOPERSPECTIVE_CENTROID; + case EvqNoPerspectiveSample: + return INTERPOLATION_NOPERSPECTIVE_SAMPLE; default: return GetInterpolationType(qualifier); } @@ -1001,9 +1009,9 @@ bool IsPrecisionApplicableToType(TBasicType type) bool IsRedeclarableBuiltIn(const ImmutableString &name) { - return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_LastFragData" || - name == "gl_LastFragColorARM" || name == "gl_PerVertex" || name == "gl_Position" || - name == "gl_PointSize"; + return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_FragDepth" || + name == "gl_LastFragData" || name == "gl_LastFragColorARM" || name == "gl_PerVertex" || + name == "gl_Position" || name == "gl_PointSize"; } size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp index 0eff3418fb50..4859282dd423 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp @@ -148,6 +148,9 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Disp mResources.EXT_blend_func_extended = extensions.blendFuncExtendedEXT; mResources.MaxDualSourceDrawBuffers = caps.maxDualSourceDrawBuffers; + // EXT_conservative_depth + mResources.EXT_conservative_depth = extensions.conservativeDepthEXT; + // APPLE_clip_distance / EXT_clip_cull_distance / ANGLE_clip_cull_distance mResources.MaxClipDistances = caps.maxClipDistances; mResources.MaxCullDistances = caps.maxCullDistances; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp index 5f6fece19342..0b1e9f462ad9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp @@ -685,6 +685,7 @@ void Context::initializeDefaultResources() // Initialize dirty bit masks mAllDirtyBits.set(); + mAllExtendedDirtyBits.set(); mDrawDirtyObjects.set(State::DIRTY_OBJECT_ACTIVE_TEXTURES); mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); @@ -697,7 +698,6 @@ void Context::initializeDefaultResources() mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE); mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING); - mTexImageDirtyBits.set(State::DIRTY_BIT_EXTENDED); // No dirty objects. // Readpixels uses the pack state and read FBO @@ -3675,6 +3675,7 @@ Extensions Context::generateSupportedExtensions() const supportedExtensions.copyTexture3dANGLE = false; supportedExtensions.textureMultisampleANGLE = false; supportedExtensions.textureStencil8OES = false; + supportedExtensions.conservativeDepthEXT = false; supportedExtensions.drawBuffersIndexedEXT = false; supportedExtensions.drawBuffersIndexedOES = false; supportedExtensions.EGLImageArrayEXT = false; @@ -4525,7 +4526,7 @@ angle::Result Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer) ANGLE_INLINE angle::Result Context::prepareForCopyImage() { ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects, Command::CopyImage)); - return syncDirtyBits(mCopyImageDirtyBits, Command::CopyImage); + return syncDirtyBits(mCopyImageDirtyBits, mCopyImageExtendedDirtyBits, Command::CopyImage); } ANGLE_INLINE angle::Result Context::prepareForDispatch() @@ -4547,7 +4548,7 @@ ANGLE_INLINE angle::Result Context::prepareForDispatch() } ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects, Command::Dispatch)); - return syncDirtyBits(mComputeDirtyBits, Command::Dispatch); + return syncDirtyBits(mComputeDirtyBits, mComputeExtendedDirtyBits, Command::Dispatch); } angle::Result Context::prepareForInvalidate(GLenum target) @@ -4560,17 +4561,22 @@ angle::Result Context::prepareForInvalidate(GLenum target) effectiveTarget = GL_DRAW_FRAMEBUFFER; } ANGLE_TRY(mState.syncDirtyObject(this, effectiveTarget)); - return syncDirtyBits(effectiveTarget == GL_READ_FRAMEBUFFER ? mReadInvalidateDirtyBits - : mDrawInvalidateDirtyBits, - Command::Invalidate); + const State::DirtyBits &dirtyBits = effectiveTarget == GL_READ_FRAMEBUFFER + ? mReadInvalidateDirtyBits + : mDrawInvalidateDirtyBits; + const State::ExtendedDirtyBits &extendedDirtyBits = effectiveTarget == GL_READ_FRAMEBUFFER + ? mReadInvalidateExtendedDirtyBits + : mDrawInvalidateExtendedDirtyBits; + return syncDirtyBits(dirtyBits, extendedDirtyBits, Command::Invalidate); } angle::Result Context::syncState(const State::DirtyBits &bitMask, + const State::ExtendedDirtyBits &extendedBitMask, const State::DirtyObjects &objectMask, Command command) { ANGLE_TRY(syncDirtyObjects(objectMask, command)); - ANGLE_TRY(syncDirtyBits(bitMask, command)); + ANGLE_TRY(syncDirtyBits(bitMask, extendedBitMask, command)); return angle::Result::Continue; } @@ -5766,12 +5772,14 @@ void Context::flushMappedBufferRange(BufferBinding /*target*/, angle::Result Context::syncStateForReadPixels() { - return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects, Command::ReadPixels); + return syncState(mReadPixelsDirtyBits, mReadPixelsExtendedDirtyBits, mReadPixelsDirtyObjects, + Command::ReadPixels); } angle::Result Context::syncStateForTexImage() { - return syncState(mTexImageDirtyBits, mTexImageDirtyObjects, Command::TexImage); + return syncState(mTexImageDirtyBits, mTexImageExtendedDirtyBits, mTexImageDirtyObjects, + Command::TexImage); } angle::Result Context::syncStateForBlit(GLbitfield mask) @@ -5792,12 +5800,12 @@ angle::Result Context::syncStateForBlit(GLbitfield mask) Command command = static_cast(static_cast(Command::Blit) + commandMask); - return syncState(mBlitDirtyBits, mBlitDirtyObjects, command); + return syncState(mBlitDirtyBits, mBlitExtendedDirtyBits, mBlitDirtyObjects, command); } angle::Result Context::syncStateForClear() { - return syncState(mClearDirtyBits, mClearDirtyObjects, Command::Clear); + return syncState(mClearDirtyBits, mClearExtendedDirtyBits, mClearDirtyObjects, Command::Clear); } angle::Result Context::syncTextureForCopy(Texture *texture) @@ -9377,6 +9385,28 @@ void Context::pixelLocalStorageBarrier() pls.barrier(this); } +void Context::framebufferPixelLocalStorageInterrupt() +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + if (framebuffer->id().value != 0) + { + PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this); + pls.interrupt(this); + } +} + +void Context::framebufferPixelLocalStorageRestore() +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + if (framebuffer->id().value != 0) + { + PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this); + pls.restore(this); + } +} + void Context::getFramebufferPixelLocalStorageParameterfv(GLint plane, GLenum pname, GLfloat *params) { getFramebufferPixelLocalStorageParameterfvRobust( @@ -10172,6 +10202,7 @@ void Context::drawPixelLocalStorageEXTEnable(GLsizei n, ASSERT(mImplementation->getNativePixelLocalStorageOptions().type == ShPixelLocalStorageType::PixelLocalStorageEXT); ANGLE_CONTEXT_TRY(syncState(mPixelLocalStorageEXTEnableDisableDirtyBits, + mPixelLocalStorageEXTEnableDisableExtendedDirtyBits, mPixelLocalStorageEXTEnableDisableDirtyObjects, Command::Draw)); ANGLE_CONTEXT_TRY(mImplementation->drawPixelLocalStorageEXTEnable(this, n, planes, loadops)); } @@ -10182,6 +10213,7 @@ void Context::drawPixelLocalStorageEXTDisable(const PixelLocalStoragePlane plane ASSERT(mImplementation->getNativePixelLocalStorageOptions().type == ShPixelLocalStorageType::PixelLocalStorageEXT); ANGLE_CONTEXT_TRY(syncState(mPixelLocalStorageEXTEnableDisableDirtyBits, + mPixelLocalStorageEXTEnableDisableExtendedDirtyBits, mPixelLocalStorageEXTEnableDisableDirtyObjects, Command::Draw)); ANGLE_CONTEXT_TRY(mImplementation->drawPixelLocalStorageEXTDisable(this, planes, storeops)); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Context.h b/Source/ThirdParty/ANGLE/src/libANGLE/Context.h index 9350bda23585..b83977c56bc5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Context.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Context.h @@ -697,10 +697,13 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl angle::Result prepareForClear(GLbitfield mask); angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer); angle::Result syncState(const State::DirtyBits &bitMask, + const State::ExtendedDirtyBits &extendedBitMask, const State::DirtyObjects &objectMask, Command command); angle::Result syncDirtyBits(Command command); - angle::Result syncDirtyBits(const State::DirtyBits &bitMask, Command command); + angle::Result syncDirtyBits(const State::DirtyBits &bitMask, + const State::ExtendedDirtyBits &extendedBitMask, + Command command); angle::Result syncDirtyObjects(const State::DirtyObjects &objectMask, Command command); angle::Result syncStateForReadPixels(); angle::Result syncStateForTexImage(); @@ -818,21 +821,31 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl StateCache mStateCache; State::DirtyBits mAllDirtyBits; + State::ExtendedDirtyBits mAllExtendedDirtyBits; State::DirtyBits mTexImageDirtyBits; + State::ExtendedDirtyBits mTexImageExtendedDirtyBits; State::DirtyObjects mTexImageDirtyObjects; State::DirtyBits mReadPixelsDirtyBits; + State::ExtendedDirtyBits mReadPixelsExtendedDirtyBits; State::DirtyObjects mReadPixelsDirtyObjects; State::DirtyBits mClearDirtyBits; + State::ExtendedDirtyBits mClearExtendedDirtyBits; State::DirtyObjects mClearDirtyObjects; State::DirtyBits mBlitDirtyBits; + State::ExtendedDirtyBits mBlitExtendedDirtyBits; State::DirtyObjects mBlitDirtyObjects; State::DirtyBits mComputeDirtyBits; + State::ExtendedDirtyBits mComputeExtendedDirtyBits; State::DirtyObjects mComputeDirtyObjects; State::DirtyBits mCopyImageDirtyBits; + State::ExtendedDirtyBits mCopyImageExtendedDirtyBits; State::DirtyObjects mCopyImageDirtyObjects; State::DirtyBits mReadInvalidateDirtyBits; + State::ExtendedDirtyBits mReadInvalidateExtendedDirtyBits; State::DirtyBits mDrawInvalidateDirtyBits; + State::ExtendedDirtyBits mDrawInvalidateExtendedDirtyBits; State::DirtyBits mPixelLocalStorageEXTEnableDisableDirtyBits; + State::ExtendedDirtyBits mPixelLocalStorageEXTEnableDisableExtendedDirtyBits; State::DirtyObjects mPixelLocalStorageEXTEnableDisableDirtyObjects; // Binding to container objects that use dependent state updates. diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Context.inl.h b/Source/ThirdParty/ANGLE/src/libANGLE/Context.inl.h index b7c8ed931d25..f43cb2383881 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Context.inl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Context.inl.h @@ -92,17 +92,25 @@ ANGLE_INLINE bool Context::noopMultiDraw(GLsizei drawcount) const ANGLE_INLINE angle::Result Context::syncDirtyBits(Command command) { - const State::DirtyBits &dirtyBits = mState.getDirtyBits(); - ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits, command)); + const State::DirtyBits &dirtyBits = mState.getDirtyBits(); + const State::ExtendedDirtyBits &extendedDirtyBits = mState.getExtendedDirtyBits(); + ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits, extendedDirtyBits, + mAllExtendedDirtyBits, command)); mState.clearDirtyBits(); return angle::Result::Continue; } -ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask, Command command) +ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask, + const State::ExtendedDirtyBits &extendedBitMask, + Command command) { const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask); - ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask, command)); + const State::ExtendedDirtyBits &extendedDirtyBits = + (mState.getExtendedDirtyBits() & extendedBitMask); + ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask, extendedDirtyBits, + extendedBitMask, command)); mState.clearDirtyBits(dirtyBits); + mState.clearExtendedDirtyBits(extendedDirtyBits); return angle::Result::Continue; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Context_gles_ext_autogen.h b/Source/ThirdParty/ANGLE/src/libANGLE/Context_gles_ext_autogen.h index 1dc2322ed5b3..53c347886f2a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Context_gles_ext_autogen.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Context_gles_ext_autogen.h @@ -587,6 +587,8 @@ void beginPixelLocalStorage(GLsizei n, const GLenum *loadops); \ void endPixelLocalStorage(GLsizei n, const GLenum *storeops); \ void pixelLocalStorageBarrier(); \ + void framebufferPixelLocalStorageInterrupt(); \ + void framebufferPixelLocalStorageRestore(); \ void getFramebufferPixelLocalStorageParameterfv(GLint plane, GLenum pname, GLfloat *params); \ void getFramebufferPixelLocalStorageParameteriv(GLint plane, GLenum pname, GLint *params); \ void getFramebufferPixelLocalStorageParameterfvRobust( \ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/ErrorStrings.h b/Source/ThirdParty/ANGLE/src/libANGLE/ErrorStrings.h index aad2fb31f7ce..db8561f51867 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/ErrorStrings.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/ErrorStrings.h @@ -509,6 +509,9 @@ MSG kPLSMismatchedBackingTextureSizes = "Mismatched pixel local storage backing MSG kPLSMultisamplingEnabled = "Attempted to begin pixel local storage with a multisampled framebuffer."; MSG kPLSNNotEqualActivePlanes = " != ACTIVE_PIXEL_LOCAL_STORAGE_PLANES_ANGLE"; MSG kPLSNoAttachmentsNoTextureBacked = "Draw framebuffer has no attachments and no enabled, texture-backed pixel local storage planes."; +MSG kPLSInterruptOverflow = "Pixel local storage does not support more than 255 nested interruptions."; +MSG kPLSInterrupted = "Pixel local storage on the draw framebuffer is interrupted."; +MSG kPLSNotInterrupted = "Pixel local storage on the draw framebuffer is not interrupted."; MSG kPLSParamsNULL = " cannot be null."; MSG kPLSPlaneLessThanZero = "Plane cannot be less than 0."; MSG kPLSPlaneOutOfRange = "Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE."; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp index 5ecdab2a9451..f990c2e06c95 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp @@ -2713,6 +2713,7 @@ bool Framebuffer::partialBufferClearNeedsInit(const Context *context, GLenum buf PixelLocalStorage &Framebuffer::getPixelLocalStorage(const Context *context) { + ASSERT(id().value != 0); if (!mPixelLocalStorage) { mPixelLocalStorage = PixelLocalStorage::Make(context); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/GLES1Shaders.inc b/Source/ThirdParty/ANGLE/src/libANGLE/GLES1Shaders.inc index 6a70b77d4d79..cbc988fde26c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/GLES1Shaders.inc +++ b/Source/ThirdParty/ANGLE/src/libANGLE/GLES1Shaders.inc @@ -16,7 +16,7 @@ // magnitude for all other floating-point values must be at least 2^32 . // // Internal computations can use either fixed-point or floating-point arithmetic. Fixed-point -// computations must be accurate to within ±2^−15. The maximum representable magnitude for a +// computations must be accurate to within ±2^-15. The maximum representable magnitude for a // fixed-point number used to represent positional or normal coordinates must be at least 2^15; the // maximum representable magnitude for colors or texture coordinates must be at least 2^10. The // maximum representable magnitude for all other fixed-point values must be at least 2^15 diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.cpp index 30625ca3d206..da919cf7b812 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.cpp @@ -11,6 +11,7 @@ #include "libANGLE/PixelLocalStorage.h" #include +#include "common/FixedVector.h" #include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/Texture.h" @@ -520,6 +521,42 @@ void PixelLocalStorage::barrier(Context *context) onBarrier(context); } +void PixelLocalStorage::interrupt(Context *context) +{ + if (mInterruptCount == 0) + { + mActivePlanesAtInterrupt = context->getState().getPixelLocalStorageActivePlanes(); + ASSERT(0 <= mActivePlanesAtInterrupt && + mActivePlanesAtInterrupt <= IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES); + if (mActivePlanesAtInterrupt >= 1) + { + angle::FixedVector storeops( + mActivePlanesAtInterrupt, GL_STORE_OP_STORE_ANGLE); + context->endPixelLocalStorage(mActivePlanesAtInterrupt, storeops.data()); + } + } + ++mInterruptCount; + ASSERT(mInterruptCount > 0); +} + +void PixelLocalStorage::restore(Context *context) +{ + ASSERT(mInterruptCount > 0); + --mInterruptCount; + ASSERT(0 <= mActivePlanesAtInterrupt && + mActivePlanesAtInterrupt <= IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES); + if (mInterruptCount == 0 && mActivePlanesAtInterrupt >= 1) + { + angle::FixedVector loadops( + mActivePlanesAtInterrupt); + for (GLsizei i = 0; i < mActivePlanesAtInterrupt; ++i) + { + loadops[i] = mPlanes[i].isMemoryless() ? GL_DONT_CARE : GL_LOAD_OP_LOAD_ANGLE; + } + context->beginPixelLocalStorage(mActivePlanesAtInterrupt, loadops.data()); + } +} + namespace { // Implements pixel local storage with image load/store shader operations. diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.h b/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.h index 2d8392352f63..255bbe23be7f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/PixelLocalStorage.h @@ -157,6 +157,8 @@ class PixelLocalStorage const PixelLocalStoragePlane *getPlanes() { return mPlanes.data(); } + size_t interruptCount() const { return mInterruptCount; } + // ANGLE_shader_pixel_local_storage API. void deinitialize(Context *context, GLint plane) { mPlanes[plane].deinitialize(context); } void setMemoryless(Context *context, GLint plane, GLenum internalformat) @@ -173,6 +175,8 @@ class PixelLocalStorage void begin(Context *, GLsizei n, const GLenum loadops[]); void end(Context *, const GLenum storeops[]); void barrier(Context *); + void interrupt(Context *); + void restore(Context *); protected: PixelLocalStorage(const ShPixelLocalStorageOptions &); @@ -194,6 +198,8 @@ class PixelLocalStorage private: std::array mPlanes; + size_t mInterruptCount = 0; + GLsizei mActivePlanesAtInterrupt = 0; }; } // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp index a14357ee88fa..b68b61ee6df8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp @@ -870,6 +870,16 @@ void State::setFrontFace(GLenum front) } } +void State::setDepthClamp(bool enabled) +{ + if (mRasterizer.depthClamp != enabled) + { + mRasterizer.depthClamp = enabled; + mDirtyBits.set(DIRTY_BIT_EXTENDED); + mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED); + } +} + void State::setDepthTest(bool enabled) { if (mDepthStencil.depthTest != enabled) @@ -1297,6 +1307,9 @@ void State::setEnableFeature(GLenum feature, bool enabled) case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); return; + case GL_DEPTH_CLAMP_EXT: + setDepthClamp(enabled); + return; case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); return; @@ -1465,6 +1478,8 @@ bool State::getEnableFeature(GLenum feature) const return isCullFaceEnabled(); case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled(); + case GL_DEPTH_CLAMP_EXT: + return isDepthClampEnabled(); case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled(); case GL_SAMPLE_COVERAGE: @@ -2458,6 +2473,9 @@ void State::getBooleanv(GLenum pname, GLboolean *params) const case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break; + case GL_DEPTH_CLAMP_EXT: + *params = mRasterizer.depthClamp; + break; case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mSampleAlphaToCoverage; break; @@ -3848,13 +3866,6 @@ AttributesMask State::getAndResetDirtyCurrentValues() const return retVal; } -State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const -{ - ExtendedDirtyBits retVal = mExtendedDirtyBits; - mExtendedDirtyBits.reset(); - return retVal; -} - void State::initializeForCapture(const Context *context) { mCaps = context->getCaps(); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/State.h b/Source/ThirdParty/ANGLE/src/libANGLE/State.h index ed9a781a5411..3bf46b838c9e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/State.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/State.h @@ -172,6 +172,10 @@ class State : angle::NonCopyable void setCullMode(CullFaceMode mode); void setFrontFace(GLenum front); + // EXT_depth_clamp + bool isDepthClampEnabled() const { return mRasterizer.depthClamp; } + void setDepthClamp(bool enabled); + // Depth test state manipulation bool isDepthTestEnabled() const { return mDepthStencil.depthTest; } bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; } @@ -486,13 +490,13 @@ class State : angle::NonCopyable { return mBoundUniformBuffersMask; } - const angle::BitSet - &getAtomicCounterBuffersMask() const + const angle::BitSet & + getAtomicCounterBuffersMask() const { return mBoundAtomicCounterBuffersMask; } - const angle::BitSet - &getShaderStorageBuffersMask() const + const angle::BitSet & + getShaderStorageBuffersMask() const { return mBoundShaderStorageBuffersMask; } @@ -713,7 +717,7 @@ class State : angle::NonCopyable DIRTY_BIT_SAMPLE_SHADING, DIRTY_BIT_PATCH_VERTICES, DIRTY_BIT_EXTENDED, // clip distances, mipmap generation hint, derivative hint, - // EXT_clip_control + // EXT_clip_control, EXT_depth_clamp DIRTY_BIT_INVALID, DIRTY_BIT_MAX = DIRTY_BIT_INVALID, }; @@ -724,6 +728,7 @@ class State : angle::NonCopyable { EXTENDED_DIRTY_BIT_CLIP_CONTROL, // EXT_clip_control EXTENDED_DIRTY_BIT_CLIP_DISTANCES, // clip distances + EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED, // EXT_depth_clamp EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT, // mipmap generation hint EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT, // shader derivative hint EXTENDED_DIRTY_BIT_SHADING_RATE, // QCOM_shading_rate @@ -768,9 +773,8 @@ class State : angle::NonCopyable using ExtendedDirtyBits = angle::BitSet32; const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; } - // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends - ExtendedDirtyBits getAndResetExtendedDirtyBits() const; void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); } + void clearExtendedDirtyBits(const ExtendedDirtyBits &bitset) { mExtendedDirtyBits &= ~bitset; } using DirtyObjects = angle::BitSet; void clearDirtyObjects() { mDirtyObjects.reset(); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp index 95f9c9501b6b..7ecad40e3241 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp @@ -48,7 +48,6 @@ RasterizerState::RasterizerState() { memset(this, 0, sizeof(RasterizerState)); - rasterizerDiscard = false; cullFace = false; cullMode = CullFaceMode::Back; frontFace = GL_CCW; @@ -56,8 +55,10 @@ RasterizerState::RasterizerState() polygonOffsetFactor = 0.0f; polygonOffsetUnits = 0.0f; polygonOffsetClamp = 0.0f; + depthClamp = false; pointDrawMode = false; multiSample = false; + rasterizerDiscard = false; dither = true; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h index 222f337d0d58..25fbf68b02c0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h @@ -238,6 +238,8 @@ struct RasterizerState final GLfloat polygonOffsetUnits; GLfloat polygonOffsetClamp; + bool depthClamp; + // pointDrawMode/multiSample are only used in the D3D back-end right now. bool pointDrawMode; bool multiSample; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/capture/FrameCapture.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/capture/FrameCapture.cpp index f8db6078fb51..3a742bdaf870 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/capture/FrameCapture.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/capture/FrameCapture.cpp @@ -4958,6 +4958,11 @@ void CaptureMidExecutionSetup(const gl::Context *context, } } + if (currentRasterState.depthClamp != defaultRasterState.depthClamp) + { + capCap(GL_DEPTH_CLAMP_EXT, currentRasterState.depthClamp); + } + // pointDrawMode/multiSample are only used in the D3D back-end right now. if (currentRasterState.rasterizerDiscard != defaultRasterState.rasterizerDiscard) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.cpp index 54ddc8e4863e..9f3e0f75fb02 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.cpp @@ -4827,6 +4827,23 @@ CallCapture CapturePixelLocalStorageBarrierANGLE(const State &glState, bool isCa return CallCapture(angle::EntryPoint::GLPixelLocalStorageBarrierANGLE, std::move(paramBuffer)); } +CallCapture CaptureFramebufferPixelLocalStorageInterruptANGLE(const State &glState, + bool isCallValid) +{ + ParamBuffer paramBuffer; + + return CallCapture(angle::EntryPoint::GLFramebufferPixelLocalStorageInterruptANGLE, + std::move(paramBuffer)); +} + +CallCapture CaptureFramebufferPixelLocalStorageRestoreANGLE(const State &glState, bool isCallValid) +{ + ParamBuffer paramBuffer; + + return CallCapture(angle::EntryPoint::GLFramebufferPixelLocalStorageRestoreANGLE, + std::move(paramBuffer)); +} + CallCapture CaptureGetFramebufferPixelLocalStorageParameterfvANGLE(const State &glState, bool isCallValid, GLint plane, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.h b/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.h index b2b0e9e7402a..4468aa404a04 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.h @@ -886,6 +886,10 @@ angle::CallCapture CaptureEndPixelLocalStorageANGLE(const State &glState, GLsizei n, const GLenum *storeops); angle::CallCapture CapturePixelLocalStorageBarrierANGLE(const State &glState, bool isCallValid); +angle::CallCapture CaptureFramebufferPixelLocalStorageInterruptANGLE(const State &glState, + bool isCallValid); +angle::CallCapture CaptureFramebufferPixelLocalStorageRestoreANGLE(const State &glState, + bool isCallValid); angle::CallCapture CaptureGetFramebufferPixelLocalStorageParameterfvANGLE(const State &glState, bool isCallValid, GLint plane, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/capture/serialize.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/capture/serialize.cpp index 20b7711389aa..59c3fe90bf61 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/capture/serialize.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/capture/serialize.cpp @@ -409,6 +409,7 @@ void SerializeRasterizerState(JsonSerializer *json, const gl::RasterizerState &r json->addScalar("PolygonOffsetFactor", rasterizerState.polygonOffsetFactor); json->addScalar("PolygonOffsetUnits", rasterizerState.polygonOffsetUnits); json->addScalar("PolygonOffsetClamp", rasterizerState.polygonOffsetClamp); + json->addScalar("DepthClamp", rasterizerState.depthClamp); json->addScalar("PointDrawMode", rasterizerState.pointDrawMode); json->addScalar("MultiSample", rasterizerState.multiSample); json->addScalar("RasterizerDiscard", rasterizerState.rasterizerDiscard); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/queryutils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/queryutils.cpp index 7b4a0fbc799c..db601eefc96b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/queryutils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/queryutils.cpp @@ -3244,6 +3244,16 @@ bool GetQueryParameterInfo(const State &glState, *numParams = 1; return true; } + case GL_DEPTH_CLAMP_EXT: + { + if (!extensions.depthClampEXT) + { + return false; + } + *type = GL_BOOL; + *numParams = 1; + return true; + } case GL_COLOR_LOGIC_OP: { if (!extensions.logicOpANGLE) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ContextImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ContextImpl.h index 825ea294e758..5b7976016461 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ContextImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ContextImpl.h @@ -202,6 +202,8 @@ class ContextImpl : public GLImplFactory virtual angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) = 0; // Disjoint timer queries diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp index 81bf7a4c5723..26c36b0efe68 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp @@ -318,14 +318,28 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout( std::string DynamicHLSL::generatePixelShaderForOutputSignature( const std::string &sourceShader, const std::vector &outputVariables, - bool usesFragDepth, + FragDepthUsage fragDepthUsage, const std::vector &outputLayout, const std::vector &shaderStorageBlocks, size_t baseUAVRegister) const { const int shaderModel = mRenderer->getMajorShaderModel(); std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR"; - std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; + std::string depthSemantic = [shaderModel, fragDepthUsage]() { + if (shaderModel < 4) + { + return "DEPTH"; + } + switch (fragDepthUsage) + { + case FragDepthUsage::Less: + return "SV_DepthLessEqual"; + case FragDepthUsage::Greater: + return "SV_DepthGreaterEqual"; + default: + return "SV_Depth"; + } + }(); std::ostringstream declarationStream; std::ostringstream copyStream; @@ -374,7 +388,7 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( } } - if (usesFragDepth) + if (fragDepthUsage != FragDepthUsage::Unused) { declarationStream << " float gl_Depth : " << depthSemantic << ";\n"; copyStream << " output.gl_Depth = gl_Depth; \n"; @@ -503,12 +517,21 @@ void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking, case sh::INTERPOLATION_FLAT: hlslStream << " nointerpolation "; break; + case sh::INTERPOLATION_NOPERSPECTIVE: + hlslStream << " noperspective "; + break; case sh::INTERPOLATION_CENTROID: hlslStream << " centroid "; break; case sh::INTERPOLATION_SAMPLE: hlslStream << " sample "; break; + case sh::INTERPOLATION_NOPERSPECTIVE_CENTROID: + hlslStream << " noperspective centroid "; + break; + case sh::INTERPOLATION_NOPERSPECTIVE_SAMPLE: + hlslStream << " noperspective sample "; + break; default: UNREACHABLE(); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h index ac852e1d91a9..37266cd7c8e9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h @@ -158,7 +158,7 @@ class DynamicHLSL : angle::NonCopyable std::string generatePixelShaderForOutputSignature( const std::string &sourceShader, const std::vector &outputVariables, - bool usesFragDepth, + FragDepthUsage fragDepthUsage, const std::vector &outputLayout, const std::vector &shaderStorageBlocks, size_t baseUAVRegister) const; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp index d8b4c6d5d0ec..18987abfaf34 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp @@ -433,10 +433,10 @@ bool ProgramD3DMetadata::usesSecondaryColor() const return (shader && shader->usesSecondaryColor()); } -bool ProgramD3DMetadata::usesFragDepth() const +FragDepthUsage ProgramD3DMetadata::getFragDepthUsage() const { const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment]; - return (shader && shader->usesFragDepth()); + return shader ? shader->getFragDepthUsage() : FragDepthUsage::Unused; } bool ProgramD3DMetadata::usesPointCoord() const @@ -1146,7 +1146,7 @@ std::unique_ptr ProgramD3D::load(const gl::Context *context, sizeof(CompilerWorkaroundsD3D)); } - stream->readBool(&mUsesFragDepth); + stream->readEnum(&mFragDepthUsage); stream->readBool(&mHasANGLEMultiviewEnabled); stream->readBool(&mUsesVertexID); stream->readBool(&mUsesViewID); @@ -1442,7 +1442,7 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream sizeof(CompilerWorkaroundsD3D)); } - stream->writeBool(mUsesFragDepth); + stream->writeEnum(mFragDepthUsage); stream->writeBool(mHasANGLEMultiviewEnabled); stream->writeBool(mUsesVertexID); stream->writeBool(mUsesViewID); @@ -1565,7 +1565,7 @@ angle::Result ProgramD3D::getPixelExecutableForCachedOutputLayout( } std::string pixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature( - mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mUsesFragDepth, + mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mFragDepthUsage, mPixelShaderOutputLayoutCache, mShaderStorageBlocks[gl::ShaderType::Fragment], mPixelShaderKey.size()); @@ -2170,7 +2170,7 @@ std::unique_ptr ProgramD3D::link(const gl::Context *context, const ShaderD3D *vertexShader = shadersD3D[gl::ShaderType::Vertex]; mUsesPointSize = vertexShader && vertexShader->usesPointSize(); mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey); - mUsesFragDepth = metadata.usesFragDepth(); + mFragDepthUsage = metadata.getFragDepthUsage(); mUsesVertexID = metadata.usesVertexID(); mUsesViewID = metadata.usesViewID(); mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled(); @@ -3066,7 +3066,7 @@ void ProgramD3D::reset() mShaderHLSL[shaderType].clear(); } - mUsesFragDepth = false; + mFragDepthUsage = FragDepthUsage::Unused; mHasANGLEMultiviewEnabled = false; mUsesVertexID = false; mUsesViewID = false; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h index ed2796898df1..74987537ba5c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h @@ -153,7 +153,6 @@ class ProgramD3DMetadata final : angle::NonCopyable int getRendererMajorShaderModel() const; bool usesBroadcast(const gl::State &data) const; bool usesSecondaryColor() const; - bool usesFragDepth() const; bool usesPointCoord() const; bool usesFragCoord() const; bool usesPointSize() const; @@ -169,6 +168,7 @@ class ProgramD3DMetadata final : angle::NonCopyable bool usesMultipleFragmentOuts() const; bool usesCustomOutVars() const; const ShaderD3D *getFragmentShader() const; + FragDepthUsage getFragDepthUsage() const; uint8_t getClipDistanceArraySize() const; uint8_t getCullDistanceArraySize() const; @@ -549,7 +549,7 @@ class ProgramD3D : public ProgramImpl gl::ShaderMap mShaderHLSL; gl::ShaderMap mShaderWorkarounds; - bool mUsesFragDepth; + FragDepthUsage mFragDepthUsage; bool mHasANGLEMultiviewEnabled; bool mUsesVertexID; bool mUsesViewID; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp index 1037aff2adae..fe144addd2c2 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp @@ -124,13 +124,13 @@ void ShaderD3D::uncompile() mUsesPointSize = false; mUsesPointCoord = false; mUsesDepthRange = false; - mUsesFragDepth = false; mHasANGLEMultiviewEnabled = false; mUsesVertexID = false; mUsesViewID = false; mUsesDiscardRewriting = false; mUsesNestedBreak = false; mRequiresIEEEStrictCompiling = false; + mFragDepthUsage = FragDepthUsage::Unused; mClipDistanceSize = 0; mCullDistanceSize = 0; @@ -311,7 +311,6 @@ std::shared_ptr ShaderD3D::compile(const gl::Context *cont mUsesPointSize = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos; mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos; mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos; - mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos; mHasANGLEMultiviewEnabled = translatedSource.find("GL_ANGLE_MULTIVIEW_ENABLED") != std::string::npos; mUsesVertexID = translatedSource.find("GL_USES_VERTEX_ID") != std::string::npos; @@ -324,6 +323,18 @@ std::shared_ptr ShaderD3D::compile(const gl::Context *cont ShHandle compilerHandle = compiler->getHandle(); + if (translatedSource.find("GL_USES_FRAG_DEPTH_GREATER") != std::string::npos) + { + mFragDepthUsage = FragDepthUsage::Greater; + } + else if (translatedSource.find("GL_USES_FRAG_DEPTH_LESS") != std::string::npos) + { + mFragDepthUsage = FragDepthUsage::Less; + } + else if (translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos) + { + mFragDepthUsage = FragDepthUsage::Any; + } mClipDistanceSize = sh::GetClipDistanceArraySize(compilerHandle); mCullDistanceSize = sh::GetCullDistanceArraySize(compilerHandle); mUniformRegisterMap = GetUniformRegisterMap(sh::GetUniformRegisterMap(compilerHandle)); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h index 15ead3a08db4..a0e5aded5284 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h @@ -41,6 +41,14 @@ struct CompilerWorkaroundsD3D bool enableIEEEStrictness = false; }; +enum class FragDepthUsage +{ + Unused, + Any, + Greater, + Less +}; + class ShaderD3D : public ShaderImpl { public: @@ -83,10 +91,10 @@ class ShaderD3D : public ShaderImpl bool usesPointSize() const { return mUsesPointSize; } bool usesPointCoord() const { return mUsesPointCoord; } bool usesDepthRange() const { return mUsesDepthRange; } - bool usesFragDepth() const { return mUsesFragDepth; } bool usesVertexID() const { return mUsesVertexID; } bool usesViewID() const { return mUsesViewID; } bool hasANGLEMultiviewEnabled() const { return mHasANGLEMultiviewEnabled; } + FragDepthUsage getFragDepthUsage() const { return mFragDepthUsage; } uint8_t getClipDistanceArraySize() const { return mClipDistanceSize; } uint8_t getCullDistanceArraySize() const { return mCullDistanceSize; } @@ -103,13 +111,13 @@ class ShaderD3D : public ShaderImpl bool mUsesPointSize; bool mUsesPointCoord; bool mUsesDepthRange; - bool mUsesFragDepth; bool mHasANGLEMultiviewEnabled; bool mUsesVertexID; bool mUsesViewID; bool mUsesDiscardRewriting; bool mUsesNestedBreak; bool mRequiresIEEEStrictCompiling; + FragDepthUsage mFragDepthUsage; uint8_t mClipDistanceSize; uint8_t mCullDistanceSize; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp index 6b989c9e80da..753a5f4cec99 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp @@ -498,8 +498,11 @@ angle::Result VertexDataManager::reserveSpaceForAttrib(const gl::Context *contex BufferD3D *bufferD3D = buffer ? GetImplAs(buffer) : nullptr; ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib, binding) == nullptr); - size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count, - static_cast(instances)); + // Make sure we always pass at least one instance count to gl::ComputeVertexBindingElementCount. + // Even if this is not an instanced draw call, some attributes can still be instanced if they + // have a non-zero divisor. + size_t totalCount = gl::ComputeVertexBindingElementCount( + binding.getDivisor(), count, static_cast(std::max(instances, 1))); // TODO(jiajia.qin@intel.com): force the index buffer to clamp any out of range indices instead // of invalid operation here. if (bufferD3D) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.cpp index ad36489b2e10..dc112f5b5fd1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.cpp @@ -798,9 +798,11 @@ angle::Result Context11::popDebugGroup(const gl::Context *context) angle::Result Context11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) { - mRenderer->getStateManager()->syncState(context, dirtyBits, command); + mRenderer->getStateManager()->syncState(context, dirtyBits, extendedDirtyBits, command); return angle::Result::Continue; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.h index 9bbcd11dc7d3..776cac274ae0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Context11.h @@ -219,6 +219,8 @@ class Context11 : public ContextD3D, public MultisampleTextureInitializer angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) override; // Disjoint timer queries diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp index df8e6f6ffce5..245dab7c632e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp @@ -193,7 +193,7 @@ angle::Result RenderStateCache::getRasterizerState(const gl::Context *context, rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.CullMode = cullMode; rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE : TRUE; - rasterDesc.DepthClipEnable = TRUE; + rasterDesc.DepthClipEnable = !rasterState.depthClamp; rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; rasterDesc.MultisampleEnable = rasterState.multiSample; rasterDesc.AntialiasedLineEnable = FALSE; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp index 0679947cdb09..484182caed5d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp @@ -707,7 +707,6 @@ StateManager11::StateManager11(Renderer11 *renderer) mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP; mCurDepthStencilState.stencilBackWritemask = static_cast(-1); - mCurRasterState.rasterizerDiscard = false; mCurRasterState.cullFace = false; mCurRasterState.cullMode = gl::CullFaceMode::Back; mCurRasterState.frontFace = GL_CCW; @@ -715,8 +714,10 @@ StateManager11::StateManager11(Renderer11 *renderer) mCurRasterState.polygonOffsetFactor = 0.0f; mCurRasterState.polygonOffsetUnits = 0.0f; mCurRasterState.polygonOffsetClamp = 0.0f; + mCurRasterState.depthClamp = false; mCurRasterState.pointDrawMode = false; mCurRasterState.multiSample = false; + mCurRasterState.rasterizerDiscard = false; mCurRasterState.dither = false; // Start with all internal dirty bits set except the SRV and UAV bits. @@ -926,6 +927,7 @@ angle::Result StateManager11::updateStateForCompute(const gl::Context *context, void StateManager11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, gl::Command command) { if (!dirtyBits.any()) @@ -1193,9 +1195,6 @@ void StateManager11::syncState(const gl::Context *context, break; case gl::State::DIRTY_BIT_EXTENDED: { - gl::State::ExtendedDirtyBits extendedDirtyBits = - state.getAndResetExtendedDirtyBits(); - for (size_t extendedDirtyBit : extendedDirtyBits) { switch (extendedDirtyBit) @@ -1210,6 +1209,12 @@ void StateManager11::syncState(const gl::Context *context, mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS); } break; + case gl::State::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED: + if (state.getRasterizerState().depthClamp != mCurRasterState.depthClamp) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + } + break; } } break; @@ -1393,7 +1398,7 @@ void StateManager11::syncScissorRectangle(const gl::Context *context) int scissorX = scissor.x + mCurScissorOffset.x; int scissorY = scissor.y + mCurScissorOffset.y; - if (mCurPresentPathFastEnabled) + if (mCurPresentPathFastEnabled && glState.getClipOrigin() == gl::ClipOrigin::LowerLeft) { scissorY = mCurPresentPathFastColorBufferHeight - scissor.height - scissor.y; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.h index e3bb56c1093a..bfb5c41e5eb5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.h @@ -195,6 +195,7 @@ class StateManager11 final : angle::NonCopyable void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, gl::Command command); angle::Result updateStateForCompute(const gl::Context *context, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp index 35a911b7cc7d..f5c72c62b7e5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp @@ -1648,7 +1648,9 @@ void GenerateCaps(ID3D11Device *device, extensions->standardDerivativesOES = GetDerivativeInstructionSupport(featureLevel); extensions->shaderTextureLodEXT = GetShaderTextureLODSupport(featureLevel); extensions->fragDepthEXT = true; + extensions->conservativeDepthEXT = (featureLevel >= D3D_FEATURE_LEVEL_11_0); extensions->polygonOffsetClampEXT = (featureLevel >= D3D_FEATURE_LEVEL_10_0); + extensions->depthClampEXT = true; extensions->stencilTexturingANGLE = (featureLevel >= D3D_FEATURE_LEVEL_10_1); extensions->multiviewOVR = IsMultiviewSupported(featureLevel); extensions->multiview2OVR = IsMultiviewSupported(featureLevel); @@ -1675,6 +1677,7 @@ void GenerateCaps(ID3D11Device *device, extensions->copyCompressedTextureCHROMIUM = true; extensions->textureStorageMultisample2dArrayOES = true; extensions->textureMirrorClampToEdgeEXT = true; + extensions->shaderNoperspectiveInterpolationNV = (featureLevel >= D3D_FEATURE_LEVEL_10_0); extensions->multiviewMultisampleANGLE = ((extensions->multiviewOVR || extensions->multiview2OVR) && extensions->textureStorageMultisample2dArrayOES); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.cpp index 50719b762535..dbf046c08c1c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.cpp @@ -425,9 +425,11 @@ angle::Result Context9::popDebugGroup(const gl::Context *context) angle::Result Context9::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) { - mRenderer->getStateManager()->syncState(mState, dirtyBits); + mRenderer->getStateManager()->syncState(mState, dirtyBits, extendedDirtyBits); return angle::Result::Continue; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.h index 008e84a9a3fd..058dd38a6268 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Context9.h @@ -217,6 +217,8 @@ class Context9 : public ContextD3D angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) override; // Disjoint timer queries diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp index cad011b25a8e..f215acd75d72 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp @@ -112,7 +112,9 @@ void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized, } } -void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) +void StateManager9::syncState(const gl::State &state, + const gl::State::DirtyBits &dirtyBits, + const gl::State::ExtendedDirtyBits &extendedDirtyBits) { if (!dirtyBits.any()) { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.h index b047b69cdde2..2fc7cb2b339d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.h @@ -40,7 +40,9 @@ class StateManager9 final : angle::NonCopyable void initialize(); - void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); + void syncState(const gl::State &state, + const gl::State::DirtyBits &dirtyBits, + const gl::State::ExtendedDirtyBits &extendedDirtyBits); void setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask); void setScissorState(const gl::Rectangle &scissor, bool enabled); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp index 48661d437c11..f8a890595d9a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp @@ -87,6 +87,8 @@ class [[nodiscard]] ScopedGLState : angle::NonCopyable stateManager->setDepthRange(0.0f, 1.0f); stateManager->setClipControl(gl::ClipOrigin::LowerLeft, gl::ClipDepthMode::NegativeOneToOne); + stateManager->setClipDistancesEnable(gl::State::ClipDistanceEnableBits()); + stateManager->setDepthClampEnabled(false); stateManager->setBlendEnabled(false); stateManager->setColorMask(true, true, true, true); stateManager->setSampleAlphaToCoverageEnabled(false); @@ -96,6 +98,7 @@ class [[nodiscard]] ScopedGLState : angle::NonCopyable stateManager->setCullFaceEnabled(false); stateManager->setPolygonOffsetFillEnabled(false); stateManager->setRasterizerDiscardEnabled(false); + stateManager->setLogicOpEnabled(false); stateManager->pauseTransformFeedback(); return stateManager->pauseAllQueries(context); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.cpp index 63fdd9e70254..29b9ec7a162b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.cpp @@ -886,9 +886,12 @@ angle::Result ContextGL::popDebugGroup(const gl::Context *context) angle::Result ContextGL::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) { - return mRenderer->getStateManager()->syncState(context, dirtyBits, bitMask); + return mRenderer->getStateManager()->syncState(context, dirtyBits, bitMask, extendedDirtyBits, + extendedBitMask); } GLint ContextGL::getGPUDisjoint() diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.h index 8aa2609cc58d..7b5faf3ad067 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.h @@ -239,6 +239,8 @@ class ContextGL : public ContextImpl angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) override; // Disjoint timer queries diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp index 719f67ea71f4..03e37fb5f852 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp @@ -102,6 +102,7 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, mPackSkipPixels(0), mFramebuffers(angle::FramebufferBindingSingletonMax, 0), mRenderbuffer(0), + mPlaceholderFbo(0), mScissorTestEnabled(false), mScissor(0, 0, 0, 0), mViewport(0, 0, 0, 0), @@ -142,6 +143,7 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, mPolygonOffsetFactor(0.0f), mPolygonOffsetUnits(0.0f), mPolygonOffsetClamp(0.0f), + mDepthClampEnabled(false), mRasterizerDiscardEnabled(false), mLineWidth(1.0f), mPrimitiveRestartEnabled(false), @@ -214,6 +216,10 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, StateManagerGL::~StateManagerGL() { + if (mPlaceholderFbo != 0) + { + deleteFramebuffer(mPlaceholderFbo); + } if (mDefaultVAO != 0) { mFunctions->deleteVertexArrays(1, &mDefaultVAO); @@ -758,6 +764,17 @@ void StateManagerGL::beginQuery(gl::QueryType type, QueryGL *queryObject, GLuint ASSERT(mQueries[type] == nullptr); ASSERT(queryId != 0); + if (mFeatures.bindFramebufferForTimerQueries.enabled && + mFramebuffers[angle::FramebufferBindingDraw] == 0 && + (type == gl::QueryType::TimeElapsed || type == gl::QueryType::Timestamp)) + { + if (!mPlaceholderFbo) + { + mFunctions->genFramebuffers(1, &mPlaceholderFbo); + } + bindFramebuffer(GL_FRAMEBUFFER, mPlaceholderFbo); + } + mQueries[type] = queryObject; mFunctions->beginQuery(ToGLenum(type), queryId); } @@ -1700,6 +1717,25 @@ void StateManagerGL::setPolygonOffset(float factor, float units, float clamp) } } +void StateManagerGL::setDepthClampEnabled(bool enabled) +{ + if (mDepthClampEnabled != enabled) + { + mDepthClampEnabled = enabled; + if (mDepthClampEnabled) + { + mFunctions->enable(GL_DEPTH_CLAMP_EXT); + } + else + { + mFunctions->disable(GL_DEPTH_CLAMP_EXT); + } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_EXTENDED); + mLocalExtendedDirtyBits.set(gl::State::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED); + } +} + void StateManagerGL::setRasterizerDiscardEnabled(bool enabled) { if (mRasterizerDiscardEnabled != enabled) @@ -1830,7 +1866,9 @@ void StateManagerGL::setClearStencil(GLint clearStencil) angle::Result StateManagerGL::syncState(const gl::Context *context, const gl::State::DirtyBits &glDirtyBits, - const gl::State::DirtyBits &bitMask) + const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask) { const gl::State &state = context->getState(); @@ -2218,8 +2256,6 @@ angle::Result StateManagerGL::syncState(const gl::Context *context, break; case gl::State::DIRTY_BIT_EXTENDED: { - const gl::State::ExtendedDirtyBits extendedDirtyBits = - state.getAndResetExtendedDirtyBits(); const gl::State::ExtendedDirtyBits glAndLocalExtendedDirtyBits = extendedDirtyBits | mLocalExtendedDirtyBits; for (size_t extendedDirtyBit : glAndLocalExtendedDirtyBits) @@ -2238,6 +2274,9 @@ angle::Result StateManagerGL::syncState(const gl::Context *context, state.getEnabledClipDistances()); } break; + case gl::State::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED: + setDepthClampEnabled(state.isDepthClampEnabled()); + break; case gl::State::EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED: setLogicOpEnabled(state.isLogicOpEnabled()); break; @@ -2893,6 +2932,17 @@ void StateManagerGL::syncFromNativeContext(const gl::Extensions &extensions, } } + if (extensions.depthClampEXT) + { + get(GL_DEPTH_CLAMP_EXT, &state->enableDepthClamp); + if (mDepthClampEnabled != state->enableDepthClamp) + { + mDepthClampEnabled = state->enableDepthClamp; + mLocalDirtyBits.set(gl::State::DIRTY_BIT_EXTENDED); + mLocalExtendedDirtyBits.set(gl::State::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED); + } + } + get(GL_SAMPLE_COVERAGE_VALUE, &state->sampleCoverageValue); get(GL_SAMPLE_COVERAGE_INVERT, &state->sampleCoverageInvert); if (mSampleCoverageValue != state->sampleCoverageValue || @@ -2991,6 +3041,11 @@ void StateManagerGL::restoreNativeContext(const gl::Extensions &extensions, setPolygonOffset(state->polygonOffsetFactor, state->polygonOffsetUnits, state->polygonOffsetClamp); + if (extensions.depthClampEXT) + { + setDepthClampEnabled(state->enableDepthClamp); + } + setSampleCoverage(state->sampleCoverageValue, state->sampleCoverageInvert); setDitherEnabled(state->enableDither); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h index 4ef2d7534c24..aac1a3fe970b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h @@ -67,6 +67,7 @@ struct ExternalContextState bool enableDither; bool enablePolygonOffsetFill; + bool enableDepthClamp; bool enableSampleAlphaToCoverage; bool enableSampleCoverage; bool multisampleEnabled; @@ -231,6 +232,7 @@ class StateManagerGL final : angle::NonCopyable void setFrontFace(GLenum frontFace); void setPolygonOffsetFillEnabled(bool enabled); void setPolygonOffset(float factor, float units, float clamp); + void setDepthClampEnabled(bool enabled); void setRasterizerDiscardEnabled(bool enabled); void setLineWidth(float width); @@ -277,7 +279,9 @@ class StateManagerGL final : angle::NonCopyable angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &glDirtyBits, - const gl::State::DirtyBits &bitMask); + const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask); ANGLE_INLINE void updateMultiviewBaseViewLayerIndexUniform( const gl::Program *program, @@ -452,6 +456,7 @@ class StateManagerGL final : angle::NonCopyable // TODO(jmadill): Convert to std::array when available std::vector mFramebuffers; GLuint mRenderbuffer; + GLuint mPlaceholderFbo; bool mScissorTestEnabled; gl::Rectangle mScissor; @@ -499,6 +504,7 @@ class StateManagerGL final : angle::NonCopyable GLfloat mPolygonOffsetFactor; GLfloat mPolygonOffsetUnits; GLfloat mPolygonOffsetClamp; + bool mDepthClampEnabled; bool mRasterizerDiscardEnabled; float mLineWidth; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/egl/ContextEGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/egl/ContextEGL.cpp index 0f6b16e84f16..8bc4292d5a39 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/egl/ContextEGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/egl/ContextEGL.cpp @@ -28,7 +28,7 @@ angle::Result ContextEGL::onMakeCurrent(const gl::Context *context) if (!mExtState) { mExtState = std::make_unique(); - const auto &caps = getNativeCaps(); + const auto &caps = getCaps(); mExtState->textureBindings.resize( static_cast(caps.maxCombinedTextureImageUnits)); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp index 43bdda2c43bd..22d98bf5faa9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp @@ -136,6 +136,13 @@ bool IsAdreno5xx(const FunctionsGL *functions) return number != 0 && number >= 500 && number < 600; } +bool IsMali(const FunctionsGL *functions) +{ + constexpr char Mali[] = "Mali"; + const char *nativeGLRenderer = GetString(functions, GL_RENDERER); + return angle::BeginsWith(nativeGLRenderer, Mali); +} + bool IsMaliT8xxOrOlder(const FunctionsGL *functions) { int number = getMaliTNumber(functions); @@ -1474,6 +1481,11 @@ void GenerateCaps(const FunctionsGL *functions, !features.disableMultisampledRenderToTexture.enabled && extensions->multisampledRenderToTextureEXT && functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture2"); + extensions->sampleVariablesOES = functions->isAtLeastGL(gl::Version(4, 2)) || + (functions->hasGLExtension("GL_ARB_sample_shading") && + functions->hasGLExtension("GL_ARB_gpu_shader5")) || + functions->isAtLeastGLES(gl::Version(3, 2)) || + functions->hasGLESExtension("GL_OES_sample_variables"); extensions->standardDerivativesOES = functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("GL_ARB_fragment_shader") || functions->hasGLESExtension("GL_OES_standard_derivatives"); @@ -1482,6 +1494,12 @@ void GenerateCaps(const FunctionsGL *functions, functions->hasGLESExtension("GL_EXT_shader_texture_lod"); extensions->fragDepthEXT = functions->standard == STANDARD_GL_DESKTOP || functions->hasGLESExtension("GL_EXT_frag_depth"); + extensions->conservativeDepthEXT = functions->isAtLeastGL(gl::Version(4, 2)) || + functions->hasGLExtension("GL_ARB_conservative_depth") || + functions->hasGLESExtension("GL_EXT_conservative_depth"); + extensions->depthClampEXT = functions->isAtLeastGL(gl::Version(3, 2)) || + functions->hasGLExtension("GL_ARB_depth_clamp") || + functions->hasGLESExtension("GL_EXT_depth_clamp"); extensions->polygonOffsetClampEXT = functions->hasExtension("GL_EXT_polygon_offset_clamp"); // Support video texture extension on non Android backends. @@ -2338,8 +2356,7 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature features, disableTimestampQueries, (IsLinux() && isVMWare) || (IsAndroid() && isNvidia) || (IsAndroid() && GetAndroidSdkLevel() < 27 && IsAdreno5xxOrOlder(functions)) || - (IsAndroid() && IsMaliT8xxOrOlder(functions)) || - (IsAndroid() && IsMaliG31OrOlder(functions))); + (!isMesa && IsMaliT8xxOrOlder(functions)) || (!isMesa && IsMaliG31OrOlder(functions))); ANGLE_FEATURE_CONDITION(features, decodeEncodeSRGBForGenerateMipmap, IsApple()); @@ -2507,6 +2524,9 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature // EXT_shader_pixel_local_storage ANGLE_FEATURE_CONDITION(features, supportsShaderPixelLocalStorageEXT, functions->hasGLESExtension("GL_EXT_shader_pixel_local_storage")); + + // https://crbug.com/1356053 + ANGLE_FEATURE_CONDITION(features, bindFramebufferForTimerQueries, IsMali(functions)); } void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.h index 73addd6bcfca..3e060391b7d8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.h @@ -192,6 +192,8 @@ class ContextMtl : public ContextImpl, public mtl::Context angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) override; // Disjoint timer queries @@ -482,7 +484,8 @@ class ContextMtl : public ContextImpl, public mtl::Context GLint baseVertex, GLuint baseInstance); void flushCommandBufferIfNeeded(); - void updateExtendedState(const gl::State &glState); + void updateExtendedState(const gl::State &glState, + const gl::State::ExtendedDirtyBits &extendedDirtyBits); void updateViewport(FramebufferMtl *framebufferMtl, const gl::Rectangle &viewport, @@ -526,6 +529,7 @@ class ContextMtl : public ContextImpl, public mtl::Context DIRTY_BIT_DRIVER_UNIFORMS, DIRTY_BIT_DEPTH_STENCIL_DESC, DIRTY_BIT_DEPTH_BIAS, + DIRTY_BIT_DEPTH_CLIP_MODE, DIRTY_BIT_STENCIL_REF, DIRTY_BIT_BLEND_COLOR, DIRTY_BIT_VIEWPORT, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.mm b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.mm index dbedfa11ddbf..7eee61f7cac7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.mm +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.mm @@ -1133,6 +1133,8 @@ GLint GetOwnershipIdentity(const egl::AttributeMap &attribs) angle::Result ContextMtl::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) { const gl::State &glState = context->getState(); @@ -1361,8 +1363,7 @@ GLint GetOwnershipIdentity(const egl::AttributeMap &attribs) case gl::State::DIRTY_BIT_PROVOKING_VERTEX: break; case gl::State::DIRTY_BIT_EXTENDED: - updateExtendedState(glState); - // Nothing to do until EXT_clip_control is implemented. + updateExtendedState(glState, extendedDirtyBits); break; case gl::State::DIRTY_BIT_SAMPLE_SHADING: // Nothing to do until OES_sample_shading is implemented. @@ -1379,11 +1380,27 @@ GLint GetOwnershipIdentity(const egl::AttributeMap &attribs) return angle::Result::Continue; } -void ContextMtl::updateExtendedState(const gl::State &glState) +void ContextMtl::updateExtendedState(const gl::State &glState, + const gl::State::ExtendedDirtyBits &extendedDirtyBits) { - // Handling clip distance enabled flags, mipmap generation hint & shader derivative - // hint. - invalidateDriverUniforms(); + for (size_t extendedDirtyBit : extendedDirtyBits) + { + switch (extendedDirtyBit) + { + case gl::State::EXTENDED_DIRTY_BIT_CLIP_CONTROL: + updateFrontFace(glState); + invalidateDriverUniforms(); + break; + case gl::State::EXTENDED_DIRTY_BIT_CLIP_DISTANCES: + invalidateDriverUniforms(); + break; + case gl::State::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED: + mDirtyBits.set(DIRTY_BIT_DEPTH_CLIP_MODE); + break; + default: + break; + } + } } // Disjoint timer queries @@ -2150,8 +2167,9 @@ GLint GetOwnershipIdentity(const egl::AttributeMap &attribs) void ContextMtl::updateFrontFace(const gl::State &glState) { FramebufferMtl *framebufferMtl = mtl::GetImpl(glState.getDrawFramebuffer()); - mWinding = - mtl::GetFontfaceWinding(glState.getRasterizerState().frontFace, !framebufferMtl->flipY()); + const bool upperLeftOrigin = mState.getClipOrigin() == gl::ClipOrigin::UpperLeft; + mWinding = mtl::GetFrontfaceWinding(glState.getRasterizerState().frontFace, + framebufferMtl->flipY() == upperLeftOrigin); mDirtyBits.set(DIRTY_BIT_WINDING); } @@ -2549,6 +2567,10 @@ static bool isDrawNoOp(const mtl::RenderPipelineDesc &descriptor, case DIRTY_BIT_DEPTH_BIAS: ANGLE_TRY(handleDirtyDepthBias(context)); break; + case DIRTY_BIT_DEPTH_CLIP_MODE: + mRenderEncoder.setDepthClipMode( + mState.isDepthClampEnabled() ? MTLDepthClipModeClamp : MTLDepthClipModeClip); + break; case DIRTY_BIT_STENCIL_REF: mRenderEncoder.setStencilRefVals(mStencilRefFront, mStencilRefBack); break; @@ -2727,14 +2749,20 @@ static bool isDrawNoOp(const mtl::RenderPipelineDesc &descriptor, const float flipX = 1.0; const float flipY = mDrawFramebuffer->flipY() ? -1.0f : 1.0f; - mDriverUniforms.flipXY = gl::PackSnorm4x8(flipX, flipY, flipX, -flipY); + mDriverUniforms.flipXY = gl::PackSnorm4x8( + flipX, flipY, flipX, mState.getClipOrigin() == gl::ClipOrigin::LowerLeft ? -flipY : flipY); // gl_ClipDistance const uint32_t enabledClipDistances = mState.getEnabledClipDistances().bits(); ASSERT((enabledClipDistances & ~sh::vk::kDriverUniformsMiscEnabledClipPlanesMask) == 0); - mDriverUniforms.misc = enabledClipDistances - << sh::vk::kDriverUniformsMiscEnabledClipPlanesOffset; + // GL_CLIP_DEPTH_MODE_EXT + const uint32_t transformDepth = !mState.isClipDepthModeZeroToOne(); + ASSERT((transformDepth & ~sh::vk::kDriverUniformsMiscTransformDepthMask) == 0); + + mDriverUniforms.misc = + (enabledClipDistances << sh::vk::kDriverUniformsMiscEnabledClipPlanesOffset) | + (transformDepth << sh::vk::kDriverUniformsMiscTransformDepthOffset); // Sample coverage mask const uint32_t sampleBitCount = mDrawFramebuffer->getSamples(); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm index 4f0e5befc9b3..ece4e06e3432 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm @@ -925,11 +925,13 @@ bool IsMetalDisplayAvailable() mNativeExtensions.mapbufferOES = true; mNativeExtensions.mapBufferRangeEXT = true; mNativeExtensions.textureStorageEXT = true; + mNativeExtensions.clipControlEXT = true; mNativeExtensions.drawBuffersEXT = true; mNativeExtensions.drawBuffersIndexedEXT = true; mNativeExtensions.drawBuffersIndexedOES = true; mNativeExtensions.fboRenderMipmapOES = true; mNativeExtensions.fragDepthEXT = true; + mNativeExtensions.conservativeDepthEXT = true; mNativeExtensions.framebufferBlitANGLE = true; mNativeExtensions.framebufferBlitNV = true; mNativeExtensions.framebufferMultisampleANGLE = true; @@ -945,6 +947,11 @@ bool IsMetalDisplayAvailable() } #endif + if (ANGLE_APPLE_AVAILABLE_XCI(10.11, 11.0, 13.1)) + { + mNativeExtensions.depthClampEXT = true; + } + // EXT_debug_marker is not implemented yet, but the entry points must be exposed for the // Metal backend to be used in Chrome (http://anglebug.com/4946) mNativeExtensions.debugMarkerEXT = true; @@ -1007,6 +1014,8 @@ bool IsMetalDisplayAvailable() mNativeExtensions.texture3DOES = true; + mNativeExtensions.shaderNoperspectiveInterpolationNV = true; + mNativeExtensions.shaderTextureLodEXT = true; mNativeExtensions.standardDerivativesOES = true; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.h index c7df3484536d..0ee583621fed 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.h @@ -337,6 +337,8 @@ struct RenderCommandEncoderStates id depthStencilState; float depthBias, depthSlopeScale, depthClamp; + MTLDepthClipMode depthClipMode; + uint32_t stencilFrontRef, stencilBackRef; Optional viewport; @@ -373,6 +375,7 @@ class RenderCommandEncoder final : public CommandEncoder RenderCommandEncoder &setDepthStencilState(id state); RenderCommandEncoder &setDepthBias(float depthBias, float slopeScale, float clamp); + RenderCommandEncoder &setDepthClipMode(MTLDepthClipMode depthClipMode); RenderCommandEncoder &setStencilRefVals(uint32_t frontRef, uint32_t backRef); RenderCommandEncoder &setStencilRefVal(uint32_t ref); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.mm b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.mm index ffefdf656c8c..5afc2f3c3c7f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.mm +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.mm @@ -48,6 +48,7 @@ PROC(SetCullMode) \ PROC(SetDepthStencilState) \ PROC(SetDepthBias) \ + PROC(SetDepthClipMode) \ PROC(SetStencilRefVals) \ PROC(SetViewport) \ PROC(SetScissorRect) \ @@ -134,6 +135,13 @@ inline void SetDepthBiasCmd(id encoder, IntermediateCom [encoder setDepthBias:depthBias slopeScale:slopeScale clamp:clamp]; } +inline void SetDepthClipModeCmd(id encoder, + IntermediateCommandStream *stream) +{ + MTLDepthClipMode depthClipMode = stream->fetch(); + [encoder setDepthClipMode:depthClipMode]; +} + inline void SetStencilRefValsCmd(id encoder, IntermediateCommandStream *stream) { @@ -1228,6 +1236,8 @@ inline void PopDebugGroupCmd(id encoder, IntermediateCo depthStencilState = nil; depthBias = depthSlopeScale = depthClamp = 0; + depthClipMode = MTLDepthClipModeClip; + stencilFrontRef = stencilBackRef = 0; viewport.reset(); @@ -1667,6 +1677,18 @@ inline void PopDebugGroupCmd(id encoder, IntermediateCo return *this; } +RenderCommandEncoder &RenderCommandEncoder::setDepthClipMode(MTLDepthClipMode depthClipMode) +{ + if (mStateCache.depthClipMode == depthClipMode) + { + return *this; + } + mStateCache.depthClipMode = depthClipMode; + + mCommands.push(CmdType::SetDepthClipMode).push(depthClipMode); + + return *this; +} RenderCommandEncoder &RenderCommandEncoder::setStencilRefVals(uint32_t frontRef, uint32_t backRef) { // Metal has some bugs when reference values are larger than 0xff diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.h index c438d2798cfd..33b33be0b63d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.h @@ -139,7 +139,7 @@ MTLBlendOperation GetBlendOp(GLenum op); MTLCompareFunction GetCompareFunc(GLenum func); MTLStencilOperation GetStencilOp(GLenum op); -MTLWinding GetFontfaceWinding(GLenum frontFaceMode, bool invert); +MTLWinding GetFrontfaceWinding(GLenum frontFaceMode, bool invert); PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode); MTLPrimitiveType GetPrimitiveType(gl::PrimitiveMode mode); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.mm b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.mm index 5ed3e2f2eac0..07f27d7a886d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.mm +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.mm @@ -929,13 +929,9 @@ MTLSamplerAddressMode GetSamplerAddressMode(GLenum wrap) { case GL_CLAMP_TO_EDGE: return MTLSamplerAddressModeClampToEdge; - case GL_MIRROR_CLAMP_TO_EDGE_EXT: #if !defined(ANGLE_PLATFORM_WATCHOS) || !ANGLE_PLATFORM_WATCHOS + case GL_MIRROR_CLAMP_TO_EDGE_EXT: return MTLSamplerAddressModeMirrorClampToEdge; -#else - // This feature isn't supported on watchOS. The extension should not - // be visible, but return a default value just in case we get to here. - return MTLSamplerAddressModeClampToEdge; #endif case GL_REPEAT: return MTLSamplerAddressModeRepeat; @@ -1067,7 +1063,7 @@ MTLStencilOperation GetStencilOp(GLenum op) } } -MTLWinding GetFontfaceWinding(GLenum frontFaceMode, bool invert) +MTLWinding GetFrontfaceWinding(GLenum frontFaceMode, bool invert) { switch (frontFaceMode) { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.cpp index 6978e6f1809e..bbcf00cd0515 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.cpp @@ -374,6 +374,8 @@ angle::Result ContextNULL::popDebugGroup(const gl::Context *context) angle::Result ContextNULL::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) { return angle::Result::Continue; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.h index 1fb3cb843a8b..0ab4f05888f1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/null/ContextNULL.h @@ -187,6 +187,8 @@ class ContextNULL : public ContextImpl angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) override; // Disjoint timer queries diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/AllocatorHelperRing.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/AllocatorHelperRing.h index 717a7345ee6a..d9f4a484dd77 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/AllocatorHelperRing.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/AllocatorHelperRing.h @@ -84,7 +84,8 @@ class SharedCommandBlockPool final : angle::RingBufferAllocateListener return angle::Result::Continue; } - bool valid() const { return mAllocator.valid(); } + // Always valid (even if allocator is detached). + bool valid() const { return true; } bool empty() const { return getCommandSize() == 0; } void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/BUILD.gn b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/BUILD.gn index 0260aaa6f3d0..f6f571a6ac0d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/BUILD.gn +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/BUILD.gn @@ -80,12 +80,10 @@ config("angle_vulkan_backend_config") { template("angle_vulkan_backend_template") { config("${target_name}_internal_config") { defines = [] - if (invoker.enable_custom_outside_render_pass_cmd_buffers || - angle_enable_vulkan_shared_ring_buffer_cmd_alloc) { + if (invoker.enable_custom_outside_render_pass_cmd_buffers) { defines += [ "ANGLE_USE_CUSTOM_VULKAN_OUTSIDE_RENDER_PASS_CMD_BUFFERS=1" ] } - if (invoker.enable_custom_render_pass_cmd_buffers || - angle_enable_vulkan_shared_ring_buffer_cmd_alloc) { + if (invoker.enable_custom_render_pass_cmd_buffers) { defines += [ "ANGLE_USE_CUSTOM_VULKAN_RENDER_PASS_CMD_BUFFERS=1" ] } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.cpp index ca782973eac6..b5271c9ad566 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.cpp @@ -44,26 +44,6 @@ void InitializeSubmitInfo(VkSubmitInfo *submitInfo, submitInfo->pSignalSemaphores = &signalSemaphore; } } - -template -void ResetSecondaryCommandBuffers(VkDevice device, SecondaryCommandBufferListT *commandBuffers) -{ - // Nothing to do when using ANGLE secondary command buffers. -} - -template <> -[[maybe_unused]] void ResetSecondaryCommandBuffers>( - VkDevice device, - std::vector *commandBuffers) -{ - // Note: we currently free the command buffers individually, but we could potentially reset the - // entire command pool. https://issuetracker.google.com/issues/166793850 - for (VulkanSecondaryCommandBuffer &secondary : *commandBuffers) - { - secondary.free(device); - } - commandBuffers->clear(); -} } // namespace // SharedFence implementation @@ -231,9 +211,9 @@ void CommandProcessorTask::initTask() mRenderPassCommandBuffer = nullptr; mRenderPass = nullptr; mSemaphore = VK_NULL_HANDLE; - mOneOffWaitSemaphore = nullptr; + mOneOffWaitSemaphore = VK_NULL_HANDLE; mOneOffWaitSemaphoreStageMask = 0; - mOneOffFence = nullptr; + mOneOffFence = VK_NULL_HANDLE; mPresentInfo = {}; mPresentInfo.pResults = nullptr; mPresentInfo.pSwapchains = nullptr; @@ -242,7 +222,7 @@ void CommandProcessorTask::initTask() mPresentInfo.pWaitSemaphores = nullptr; mPresentFence = VK_NULL_HANDLE; mSwapchainStatus = nullptr; - mOneOffCommandBufferVk = VK_NULL_HANDLE; + mOneOffCommandBuffer = VK_NULL_HANDLE; mPriority = egl::ContextPriority::Medium; mProtectionType = ProtectionType::InvalidEnum; } @@ -388,31 +368,28 @@ void CommandProcessorTask::initPresent(egl::ContextPriority priority, copyPresentInfo(presentInfo); } -void CommandProcessorTask::initFlushAndQueueSubmit( - const VkSemaphore semaphore, - ProtectionType protectionType, - egl::ContextPriority priority, - SecondaryCommandBufferList &&commandBuffersToReset, - const QueueSerial &submitQueueSerial) +void CommandProcessorTask::initFlushAndQueueSubmit(VkSemaphore semaphore, + ProtectionType protectionType, + egl::ContextPriority priority, + const QueueSerial &submitQueueSerial) { - mTask = CustomTask::FlushAndQueueSubmit; - mSemaphore = semaphore; - mCommandBuffersToReset = std::move(commandBuffersToReset); - mPriority = priority; - mProtectionType = protectionType; - mSubmitQueueSerial = submitQueueSerial; + mTask = CustomTask::FlushAndQueueSubmit; + mSemaphore = semaphore; + mPriority = priority; + mProtectionType = protectionType; + mSubmitQueueSerial = submitQueueSerial; } void CommandProcessorTask::initOneOffQueueSubmit(VkCommandBuffer commandBufferHandle, ProtectionType protectionType, egl::ContextPriority priority, - const Semaphore *waitSemaphore, + VkSemaphore waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMask, - const Fence *fence, + VkFence fence, const QueueSerial &submitQueueSerial) { mTask = CustomTask::OneOffQueueSubmit; - mOneOffCommandBufferVk = commandBufferHandle; + mOneOffCommandBuffer = commandBufferHandle; mOneOffWaitSemaphore = waitSemaphore; mOneOffWaitSemaphoreStageMask = waitSemaphoreStageMask; mOneOffFence = fence; @@ -438,11 +415,10 @@ CommandProcessorTask &CommandProcessorTask::operator=(CommandProcessorTask &&rhs std::swap(mOneOffWaitSemaphore, rhs.mOneOffWaitSemaphore); std::swap(mOneOffWaitSemaphoreStageMask, rhs.mOneOffWaitSemaphoreStageMask); std::swap(mOneOffFence, rhs.mOneOffFence); - std::swap(mCommandBuffersToReset, rhs.mCommandBuffersToReset); std::swap(mSubmitQueueSerial, rhs.mSubmitQueueSerial); std::swap(mPriority, rhs.mPriority); std::swap(mProtectionType, rhs.mProtectionType); - std::swap(mOneOffCommandBufferVk, rhs.mOneOffCommandBufferVk); + std::swap(mOneOffCommandBuffer, rhs.mOneOffCommandBuffer); copyPresentInfo(rhs.mPresentInfo); std::swap(mSwapchainStatus, rhs.mSwapchainStatus); @@ -466,7 +442,7 @@ CommandBatch::CommandBatch(CommandBatch &&other) : CommandBatch() CommandBatch &CommandBatch::operator=(CommandBatch &&other) { std::swap(primaryCommands, other.primaryCommands); - std::swap(commandBuffersToReset, other.commandBuffersToReset); + std::swap(secondaryCommands, other.secondaryCommands); std::swap(fence, other.fence); std::swap(queueSerial, other.queueSerial); std::swap(protectionType, other.protectionType); @@ -476,16 +452,11 @@ CommandBatch &CommandBatch::operator=(CommandBatch &&other) void CommandBatch::destroy(VkDevice device) { primaryCommands.destroy(device); + secondaryCommands.retireCommandBuffers(); fence.destroy(device); protectionType = ProtectionType::InvalidEnum; } -void CommandBatch::resetSecondaryCommandBuffers(VkDevice device) -{ - ResetSecondaryCommandBuffers(device, &commandBuffersToReset.outsideRenderPassCommandBuffers); - ResetSecondaryCommandBuffers(device, &commandBuffersToReset.renderPassCommandBuffers); -} - // CommandProcessor implementation. void CommandProcessor::handleError(VkResult errorCode, const char *file, @@ -667,9 +638,9 @@ angle::Result CommandProcessor::processTask(CommandProcessorTask *task) // End command buffer // Call submitCommands() - ANGLE_TRY(mCommandQueue->submitCommands( - this, task->getProtectionType(), task->getPriority(), task->getSemaphore(), - std::move(task->getCommandBuffersToReset()), task->getSubmitQueueSerial())); + ANGLE_TRY(mCommandQueue->submitCommands(this, task->getProtectionType(), + task->getPriority(), task->getSemaphore(), + task->getSubmitQueueSerial())); mNeedCommandsAndGarbageCleanup = true; break; } @@ -679,7 +650,7 @@ angle::Result CommandProcessor::processTask(CommandProcessorTask *task) ANGLE_TRY(mCommandQueue->queueSubmitOneOff( this, task->getProtectionType(), task->getPriority(), - task->getOneOffCommandBufferVk(), task->getOneOffWaitSemaphore(), + task->getOneOffCommandBuffer(), task->getOneOffWaitSemaphore(), task->getOneOffWaitSemaphoreStageMask(), task->getOneOffFence(), SubmitPolicy::EnsureSubmitted, task->getSubmitQueueSerial())); mNeedCommandsAndGarbageCleanup = true; @@ -718,8 +689,7 @@ angle::Result CommandProcessor::processTask(CommandProcessorTask *task) OutsideRenderPassCommandBufferHelper *originalCommandBuffer = task->getOutsideRenderPassCommandBuffer(); - mRenderer->recycleOutsideRenderPassCommandBufferHelper(mRenderer->getDevice(), - &originalCommandBuffer); + mRenderer->recycleOutsideRenderPassCommandBufferHelper(&originalCommandBuffer); break; } case CustomTask::ProcessRenderPassCommands: @@ -731,8 +701,7 @@ angle::Result CommandProcessor::processTask(CommandProcessorTask *task) RenderPassCommandBufferHelper *originalCommandBuffer = task->getRenderPassCommandBuffer(); - mRenderer->recycleRenderPassCommandBufferHelper(mRenderer->getDevice(), - &originalCommandBuffer); + mRenderer->recycleRenderPassCommandBufferHelper(&originalCommandBuffer); break; } default: @@ -821,19 +790,16 @@ void CommandProcessor::present(egl::ContextPriority priority, swapchainStatus->isPending = false; } -angle::Result CommandProcessor::enqueueSubmitCommands( - Context *context, - ProtectionType protectionType, - egl::ContextPriority priority, - const VkSemaphore signalSemaphore, - SecondaryCommandBufferList &&commandBuffersToReset, - const QueueSerial &submitQueueSerial) +angle::Result CommandProcessor::enqueueSubmitCommands(Context *context, + ProtectionType protectionType, + egl::ContextPriority priority, + VkSemaphore signalSemaphore, + const QueueSerial &submitQueueSerial) { ANGLE_TRY(checkAndPopPendingError(context)); CommandProcessorTask task; - task.initFlushAndQueueSubmit(signalSemaphore, protectionType, priority, - std::move(commandBuffersToReset), submitQueueSerial); + task.initFlushAndQueueSubmit(signalSemaphore, protectionType, priority, submitQueueSerial); ANGLE_TRY(queueCommand(std::move(task))); @@ -847,9 +813,9 @@ angle::Result CommandProcessor::enqueueSubmitOneOffCommands( ProtectionType protectionType, egl::ContextPriority contextPriority, VkCommandBuffer commandBufferHandle, - const Semaphore *waitSemaphore, + VkSemaphore waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMask, - const Fence *fence, + VkFence fence, SubmitPolicy submitPolicy, const QueueSerial &submitQueueSerial) { @@ -912,6 +878,9 @@ angle::Result CommandProcessor::enqueueFlushOutsideRPCommands( (*outsideRPCommands)->markClosed(); + SecondaryCommandPool *commandPool = nullptr; + ANGLE_TRY((*outsideRPCommands)->detachCommandPool(context, &commandPool)); + // Detach functions are only used for ring buffer allocators. SecondaryCommandMemoryAllocator *allocator = (*outsideRPCommands)->detachAllocator(); @@ -919,8 +888,8 @@ angle::Result CommandProcessor::enqueueFlushOutsideRPCommands( task.initOutsideRenderPassProcessCommands(protectionType, priority, *outsideRPCommands); ANGLE_TRY(queueCommand(std::move(task))); - ANGLE_TRY(mRenderer->getOutsideRenderPassCommandBufferHelper( - context, (*outsideRPCommands)->getCommandPool(), allocator, outsideRPCommands)); + ANGLE_TRY(mRenderer->getOutsideRenderPassCommandBufferHelper(context, commandPool, allocator, + outsideRPCommands)); return angle::Result::Continue; } @@ -936,6 +905,9 @@ angle::Result CommandProcessor::enqueueFlushRenderPassCommands( (*renderPassCommands)->markClosed(); + SecondaryCommandPool *commandPool = nullptr; + (*renderPassCommands)->detachCommandPool(&commandPool); + // Detach functions are only used for ring buffer allocators. SecondaryCommandMemoryAllocator *allocator = (*renderPassCommands)->detachAllocator(); @@ -943,8 +915,8 @@ angle::Result CommandProcessor::enqueueFlushRenderPassCommands( task.initRenderPassProcessCommands(protectionType, priority, *renderPassCommands, &renderPass); ANGLE_TRY(queueCommand(std::move(task))); - ANGLE_TRY(mRenderer->getRenderPassCommandBufferHelper( - context, (*renderPassCommands)->getCommandPool(), allocator, renderPassCommands)); + ANGLE_TRY(mRenderer->getRenderPassCommandBufferHelper(context, commandPool, allocator, + renderPassCommands)); return angle::Result::Continue; } @@ -1030,6 +1002,7 @@ void CommandQueue::destroy(Context *context) state.waitSemaphores.clear(); state.waitSemaphoreStageMasks.clear(); state.primaryCommands.destroy(renderer->getDevice()); + state.secondaryCommands.retireCommandBuffers(); } } @@ -1093,7 +1066,7 @@ void CommandQueue::handleDeviceLost(RendererVk *renderer) batch.primaryCommands.destroy(device); } - batch.resetSecondaryCommandBuffers(device); + batch.secondaryCommands.retireCommandBuffers(); mLastCompletedSerials.setQueueSerial(batch.queueSerial); mInFlightCommands.pop(); @@ -1289,7 +1262,8 @@ angle::Result CommandQueue::flushOutsideRPCommands( std::lock_guard lock(mMutex); ANGLE_TRY(ensurePrimaryCommandBufferValid(context, protectionType, priority)); CommandsState &state = mCommandsStateMap[priority][protectionType]; - return (*outsideRPCommands)->flushToPrimary(context, &state.primaryCommands); + return (*outsideRPCommands) + ->flushToPrimary(context, &state.primaryCommands, &state.secondaryCommands); } angle::Result CommandQueue::flushRenderPassCommands( @@ -1302,14 +1276,14 @@ angle::Result CommandQueue::flushRenderPassCommands( std::lock_guard lock(mMutex); ANGLE_TRY(ensurePrimaryCommandBufferValid(context, protectionType, priority)); CommandsState &state = mCommandsStateMap[priority][protectionType]; - return (*renderPassCommands)->flushToPrimary(context, &state.primaryCommands, &renderPass); + return (*renderPassCommands) + ->flushToPrimary(context, &state.primaryCommands, &renderPass, &state.secondaryCommands); } angle::Result CommandQueue::submitCommands(Context *context, ProtectionType protectionType, egl::ContextPriority priority, - const VkSemaphore signalSemaphore, - SecondaryCommandBufferList &&commandBuffersToReset, + VkSemaphore signalSemaphore, const QueueSerial &submitQueueSerial) { ANGLE_TRACE_EVENT0("gpu.angle", "CommandQueue::submitCommands"); @@ -1323,14 +1297,17 @@ angle::Result CommandQueue::submitCommands(Context *context, DeviceScoped scopedBatch(device); CommandBatch &batch = scopedBatch.get(); - batch.queueSerial = submitQueueSerial; - batch.protectionType = protectionType; - batch.commandBuffersToReset = std::move(commandBuffersToReset); + batch.queueSerial = submitQueueSerial; + batch.protectionType = protectionType; CommandsState &state = mCommandsStateMap[priority][protectionType]; // Store the primary CommandBuffer in the in-flight list. batch.primaryCommands = std::move(state.primaryCommands); + // Store secondary Command Buffers. + batch.secondaryCommands = std::move(state.secondaryCommands); + ASSERT(batch.primaryCommands.valid() || batch.secondaryCommands.empty()); + // Move to local copy of vectors since queueSubmit will release the lock. std::vector waitSemaphores = std::move(state.waitSemaphores); std::vector waitSemaphoreStageMasks = @@ -1341,7 +1318,7 @@ angle::Result CommandQueue::submitCommands(Context *context, signalSemaphore != VK_NULL_HANDLE || !waitSemaphores.empty(); VkSubmitInfo submitInfo = {}; VkProtectedSubmitInfo protectedSubmitInfo = {}; - const Fence *fence = nullptr; + VkFence fence = VK_NULL_HANDLE; if (needsQueueSubmit) { @@ -1362,7 +1339,7 @@ angle::Result CommandQueue::submitCommands(Context *context, } ANGLE_VK_TRY(context, batch.fence.init(context->getDevice(), &mFenceRecycler)); - fence = &batch.fence.get(); + fence = batch.fence.get().getHandle(); ++mPerfCounters.vkQueueSubmitCallsTotal; ++mPerfCounters.vkQueueSubmitCallsPerFrame; @@ -1383,9 +1360,9 @@ angle::Result CommandQueue::queueSubmitOneOff(Context *context, ProtectionType protectionType, egl::ContextPriority contextPriority, VkCommandBuffer commandBufferHandle, - const Semaphore *waitSemaphore, + VkSemaphore waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMask, - const Fence *fence, + VkFence fence, SubmitPolicy submitPolicy, const QueueSerial &submitQueueSerial) { @@ -1397,10 +1374,10 @@ angle::Result CommandQueue::queueSubmitOneOff(Context *context, // If caller passed in a fence, use it. Otherwise create an internal fence. That way if we can // go through normal waitForQueueSerial code path to wait for it to finish. - if (fence == nullptr) + if (fence == VK_NULL_HANDLE) { ANGLE_VK_TRY(context, batch.fence.init(context->getDevice(), &mFenceRecycler)); - fence = &batch.fence.get(); + fence = batch.fence.get().getHandle(); } VkSubmitInfo submitInfo = {}; @@ -1423,10 +1400,10 @@ angle::Result CommandQueue::queueSubmitOneOff(Context *context, submitInfo.pCommandBuffers = &commandBufferHandle; } - if (waitSemaphore != nullptr) + if (waitSemaphore != VK_NULL_HANDLE) { submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = waitSemaphore->ptr(); + submitInfo.pWaitSemaphores = &waitSemaphore; submitInfo.pWaitDstStageMask = &waitSemaphoreStageMask; } @@ -1442,7 +1419,7 @@ angle::Result CommandQueue::queueSubmit(Context *context, std::unique_lock &&dequeueLock, egl::ContextPriority contextPriority, const VkSubmitInfo &submitInfo, - const Fence *fence, + VkFence fence, DeviceScoped &commandBatch, const QueueSerial &submitQueueSerial) { @@ -1466,9 +1443,8 @@ angle::Result CommandQueue::queueSubmit(Context *context, if (submitInfo.sType == VK_STRUCTURE_TYPE_SUBMIT_INFO) { - VkQueue queue = getQueue(contextPriority); - VkFence fenceHandle = fence ? fence->getHandle() : VK_NULL_HANDLE; - ANGLE_VK_TRY(context, vkQueueSubmit(queue, 1, &submitInfo, fenceHandle)); + VkQueue queue = getQueue(contextPriority); + ANGLE_VK_TRY(context, vkQueueSubmit(queue, 1, &submitInfo, fence)); } mInFlightCommands.push(commandBatch.release()); @@ -1577,8 +1553,6 @@ angle::Result CommandQueue::finishOneCommandBatchAndCleanup(Context *context, ui angle::Result CommandQueue::retireFinishedCommandsLocked(Context *context) { ANGLE_TRACE_EVENT0("gpu.angle", "retireFinishedCommandsLocked"); - RendererVk *renderer = context->getRenderer(); - VkDevice device = renderer->getDevice(); while (!mFinishedCommandBatches.empty()) { @@ -1595,7 +1569,7 @@ angle::Result CommandQueue::retireFinishedCommandsLocked(Context *context) ANGLE_TRY(commandPool.collect(context, std::move(batch.primaryCommands))); } - batch.resetSecondaryCommandBuffers(device); + batch.secondaryCommands.retireCommandBuffers(); mFinishedCommandBatches.pop(); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.h index 5c5c04ecae2e..f2b26fa882e7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/CommandProcessor.h @@ -139,18 +139,17 @@ class CommandProcessorTask const VkPresentInfoKHR &presentInfo, SwapchainStatus *swapchainStatus); - void initFlushAndQueueSubmit(const VkSemaphore semaphore, + void initFlushAndQueueSubmit(VkSemaphore semaphore, ProtectionType protectionType, egl::ContextPriority priority, - SecondaryCommandBufferList &&commandBuffersToReset, const QueueSerial &submitQueueSerial); void initOneOffQueueSubmit(VkCommandBuffer commandBufferHandle, ProtectionType protectionType, egl::ContextPriority priority, - const Semaphore *waitSemaphore, + VkSemaphore waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMask, - const Fence *fence, + VkFence fence, const QueueSerial &submitQueueSerial); CommandProcessorTask &operator=(CommandProcessorTask &&rhs); @@ -167,14 +166,16 @@ class CommandProcessorTask { return mWaitSemaphoreStageMasks; } - VkSemaphore getSemaphore() { return mSemaphore; } - SecondaryCommandBufferList &getCommandBuffersToReset() { return mCommandBuffersToReset; } + VkSemaphore getSemaphore() const { return mSemaphore; } egl::ContextPriority getPriority() const { return mPriority; } ProtectionType getProtectionType() const { return mProtectionType; } - VkCommandBuffer getOneOffCommandBufferVk() const { return mOneOffCommandBufferVk; } - const Semaphore *getOneOffWaitSemaphore() { return mOneOffWaitSemaphore; } - VkPipelineStageFlags getOneOffWaitSemaphoreStageMask() { return mOneOffWaitSemaphoreStageMask; } - const Fence *getOneOffFence() { return mOneOffFence; } + VkCommandBuffer getOneOffCommandBuffer() const { return mOneOffCommandBuffer; } + VkSemaphore getOneOffWaitSemaphore() const { return mOneOffWaitSemaphore; } + VkPipelineStageFlags getOneOffWaitSemaphoreStageMask() const + { + return mOneOffWaitSemaphoreStageMask; + } + VkFence getOneOffFence() const { return mOneOffFence; } const VkPresentInfoKHR &getPresentInfo() const { return mPresentInfo; } SwapchainStatus *getSwapchainStatus() const { return mSwapchainStatus; } const RenderPass *getRenderPass() const { return mRenderPass; } @@ -203,7 +204,6 @@ class CommandProcessorTask // Flush data VkSemaphore mSemaphore; - SecondaryCommandBufferList mCommandBuffersToReset; // Flush command data QueueSerial mSubmitQueueSerial; @@ -227,10 +227,10 @@ class CommandProcessorTask SwapchainStatus *mSwapchainStatus; // Used by OneOffQueueSubmit - VkCommandBuffer mOneOffCommandBufferVk; - const Semaphore *mOneOffWaitSemaphore; + VkCommandBuffer mOneOffCommandBuffer; + VkSemaphore mOneOffWaitSemaphore; VkPipelineStageFlags mOneOffWaitSemaphoreStageMask; - const Fence *mOneOffFence; + VkFence mOneOffFence; // Flush, Present & QueueWaitIdle data egl::ContextPriority mPriority; @@ -247,10 +247,9 @@ struct CommandBatch final : angle::NonCopyable CommandBatch &operator=(CommandBatch &&other); void destroy(VkDevice device); - void resetSecondaryCommandBuffers(VkDevice device); PrimaryCommandBuffer primaryCommands; - SecondaryCommandBufferList commandBuffersToReset; + SecondaryCommandBufferCollector secondaryCommands; SharedFence fence; QueueSerial queueSerial; ProtectionType protectionType; @@ -380,17 +379,16 @@ class CommandQueue : angle::NonCopyable angle::Result submitCommands(Context *context, ProtectionType protectionType, egl::ContextPriority priority, - const VkSemaphore signalSemaphore, - SecondaryCommandBufferList &&commandBuffersToReset, + VkSemaphore signalSemaphore, const QueueSerial &submitQueueSerial); angle::Result queueSubmitOneOff(Context *context, ProtectionType protectionType, egl::ContextPriority contextPriority, VkCommandBuffer commandBufferHandle, - const Semaphore *waitSemaphore, + VkSemaphore waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMask, - const Fence *fence, + VkFence fence, SubmitPolicy submitPolicy, const QueueSerial &submitQueueSerial); @@ -463,7 +461,7 @@ class CommandQueue : angle::NonCopyable std::unique_lock &&dequeueLock, egl::ContextPriority contextPriority, const VkSubmitInfo &submitInfo, - const Fence *fence, + VkFence fence, DeviceScoped &commandBatch, const QueueSerial &submitQueueSerial); @@ -476,6 +474,7 @@ class CommandQueue : angle::NonCopyable std::vector waitSemaphores; std::vector waitSemaphoreStageMasks; PrimaryCommandBuffer primaryCommands; + SecondaryCommandBufferCollector secondaryCommands; }; using CommandsStateMap = @@ -544,8 +543,7 @@ class CommandProcessor : public Context angle::Result enqueueSubmitCommands(Context *context, ProtectionType protectionType, egl::ContextPriority priority, - const VkSemaphore signalSemaphore, - SecondaryCommandBufferList &&commandBuffersToReset, + VkSemaphore signalSemaphore, const QueueSerial &submitQueueSerial); void requestCommandsAndGarbageCleanup(); @@ -554,9 +552,9 @@ class CommandProcessor : public Context ProtectionType protectionType, egl::ContextPriority contextPriority, VkCommandBuffer commandBufferHandle, - const Semaphore *waitSemaphore, + VkSemaphore waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMask, - const Fence *fence, + VkFence fence, SubmitPolicy submitPolicy, const QueueSerial &submitQueueSerial); void enqueuePresent(egl::ContextPriority contextPriority, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.cpp index b33b71993ed3..9bc225892dcd 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -882,6 +882,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk mHasDeferredFlush(false), mHasAnyCommandsPendingSubmission(false), mIsInFramebufferFetchMode(false), + mAllowRenderPassToReactivate(true), mTotalBufferToImageCopySize(0), mHasWaitSemaphoresPendingSubmission(false), mGpuClockSync{std::numeric_limits::max(), std::numeric_limits::max()}, @@ -953,8 +954,12 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk mDynamicStateDirtyBits |= DirtyBits{ DIRTY_BIT_DYNAMIC_RASTERIZER_DISCARD_ENABLE, DIRTY_BIT_DYNAMIC_DEPTH_BIAS_ENABLE, - DIRTY_BIT_DYNAMIC_PRIMITIVE_RESTART_ENABLE, }; + + if (!getFeatures().forceStaticPrimitiveRestartState.enabled) + { + mDynamicStateDirtyBits.set(DIRTY_BIT_DYNAMIC_PRIMITIVE_RESTART_ENABLE); + } } if (getFeatures().supportsLogicOpDynamicState.enabled) { @@ -1136,7 +1141,11 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk { mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED); mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED); - mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED); + + if (!getFeatures().forceStaticPrimitiveRestartState.enabled) + { + mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED); + } } angle::PerfMonitorCounterGroup vulkanGroup; @@ -1195,12 +1204,17 @@ void ContextVk::onDestroy(const gl::Context *context) } // Recycle current command buffers. + + // Release functions are only used for Vulkan secondary command buffers. + mOutsideRenderPassCommands->releaseCommandPool(); + mRenderPassCommands->releaseCommandPool(); + // Detach functions are only used for ring buffer allocators. mOutsideRenderPassCommands->detachAllocator(); mRenderPassCommands->detachAllocator(); - mRenderer->recycleOutsideRenderPassCommandBufferHelper(device, &mOutsideRenderPassCommands); - mRenderer->recycleRenderPassCommandBufferHelper(device, &mRenderPassCommands); + mRenderer->recycleOutsideRenderPassCommandBufferHelper(&mOutsideRenderPassCommands); + mRenderer->recycleRenderPassCommandBufferHelper(&mRenderPassCommands); mVertexInputGraphicsPipelineCache.destroy(this); mFragmentOutputGraphicsPipelineCache.destroy(this); @@ -1212,6 +1226,17 @@ void ContextVk::onDestroy(const gl::Context *context) mRenderPassCache.destroy(this); mShaderLibrary.destroy(device); mGpuEventQueryPool.destroy(device); + + // Must retire all Vulkan secondary command buffers before destroying the pools. + if ((!vk::OutsideRenderPassCommandBuffer::ExecutesInline() || + !vk::RenderPassCommandBuffer::ExecutesInline()) && + mRenderer->isAsyncCommandBufferResetEnabled()) + { + // This will also reset Primary command buffers which is REQUIRED on some buggy Vulkan + // implementations. + (void)mRenderer->retireFinishedCommands(this); + } + mCommandPools.outsideRenderPassPool.destroy(device); mCommandPools.renderPassPool.destroy(device); @@ -1366,6 +1391,17 @@ angle::Result ContextVk::initialize() constexpr VkMemoryPropertyFlags kMemoryType = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; ANGLE_TRY(mEmptyBuffer.init(this, emptyBufferInfo, kMemoryType)); + // If the share group has one context and is about to add the second one, the first context's + // mutable textures should be flushed. + if (isEligibleForMutableTextureFlush()) + { + ASSERT(mShareGroupVk->getContextCount() == 1); + for (auto context : mShareGroupVk->getContexts()) + { + ANGLE_TRY(context->flushOutsideRenderPassCommands()); + } + } + // Add context into the share group mShareGroupVk->addContext(this); @@ -2242,7 +2278,10 @@ angle::Result ContextVk::handleDirtyAnySamplePassedQueryEnd(DirtyBits::Iterator // getQueryResult gets unblocked sooner. dirtyBitsIterator->setLaterBit(DIRTY_BIT_RENDER_PASS); - mHasDeferredFlush = true; + // Don't let next render pass end up reactivate and reuse the current render pass, which + // defeats the purpose of it. + mAllowRenderPassToReactivate = false; + mHasDeferredFlush = true; } return angle::Result::Continue; } @@ -2250,6 +2289,26 @@ angle::Result ContextVk::handleDirtyAnySamplePassedQueryEnd(DirtyBits::Iterator angle::Result ContextVk::handleDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator, DirtyBits dirtyBitMask) { + FramebufferVk *drawFramebufferVk = getDrawFramebuffer(); + + gl::Rectangle renderArea = drawFramebufferVk->getRenderArea(this); + // Check to see if we can reactivate the current renderPass, if all arguments that we use to + // start the render pass is the same. We don't need to check clear values since mid render pass + // clear are handled differently. + bool reactivateStartedRenderPass = + hasStartedRenderPassWithQueueSerial(drawFramebufferVk->getLastRenderPassQueueSerial()) && + mAllowRenderPassToReactivate && renderArea == mRenderPassCommands->getRenderArea(); + if (reactivateStartedRenderPass) + { + INFO() << "Reactivate already started render pass on draw."; + mRenderPassCommandBuffer = &mRenderPassCommands->getCommandBuffer(); + ASSERT(!drawFramebufferVk->hasDeferredClears()); + ASSERT(hasActiveRenderPass()); + ASSERT(drawFramebufferVk->getRenderPassDesc() == mRenderPassCommands->getRenderPassDesc()); + + return angle::Result::Continue; + } + // If the render pass needs to be recreated, close it using the special mid-dirty-bit-handling // function, so later dirty bits can be set. if (mRenderPassCommands->started()) @@ -2259,11 +2318,9 @@ angle::Result ContextVk::handleDirtyGraphicsRenderPass(DirtyBits::Iterator *dirt RenderPassClosureReason::AlreadySpecifiedElsewhere)); } - FramebufferVk *drawFramebufferVk = getDrawFramebuffer(); - gl::Rectangle scissoredRenderArea = drawFramebufferVk->getRotatedScissoredRenderArea(this); - bool renderPassDescChanged = false; + bool renderPassDescChanged = false; - ANGLE_TRY(startRenderPass(scissoredRenderArea, nullptr, &renderPassDescChanged)); + ANGLE_TRY(startRenderPass(renderArea, nullptr, &renderPassDescChanged)); // The render pass desc can change when starting the render pass, for example due to // multisampled-render-to-texture needs based on loadOps. In that case, recreate the graphics @@ -3167,7 +3224,7 @@ angle::Result ContextVk::handleDirtyDescriptorSetsImpl(CommandBufferHelperT *com { // When using Vulkan secondary command buffers, the descriptor sets need to be updated before // they are bound. - if (!commandBufferHelper->getCommandBuffer().ExecutesInline()) + if (!CommandBufferHelperT::ExecutesInline()) { flushDescriptorSetUpdates(); } @@ -3752,9 +3809,10 @@ void ContextVk::clearAllGarbage() void ContextVk::handleDeviceLost() { - (void)mOutsideRenderPassCommands->reset(this); - (void)mRenderPassCommands->reset(this); - mRenderer->notifyDeviceLost(); + vk::SecondaryCommandBufferCollector collector; + (void)mOutsideRenderPassCommands->reset(this, &collector); + (void)mRenderPassCommands->reset(this, &collector); + collector.retireCommandBuffers(); } angle::Result ContextVk::drawArrays(const gl::Context *context, @@ -5088,6 +5146,8 @@ angle::Result ContextVk::invalidateProgramExecutableHelper(const gl::Context *co angle::Result ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) { const gl::State &glState = context->getState(); @@ -5278,7 +5338,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, mGraphicsDirtyBits.set(DIRTY_BIT_DYNAMIC_LINE_WIDTH); break; case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED: - if (getFeatures().supportsExtendedDynamicState2.enabled) + if (getFeatures().supportsExtendedDynamicState2.enabled && + !getFeatures().forceStaticPrimitiveRestartState.enabled) { mGraphicsDirtyBits.set(DIRTY_BIT_DYNAMIC_PRIMITIVE_RESTART_ENABLE); } @@ -5507,8 +5568,6 @@ angle::Result ContextVk::syncState(const gl::Context *context, break; case gl::State::DIRTY_BIT_EXTENDED: { - gl::State::ExtendedDirtyBits extendedDirtyBits = - glState.getAndResetExtendedDirtyBits(); for (size_t extendedDirtyBit : extendedDirtyBits) { switch (extendedDirtyBit) @@ -5539,6 +5598,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, case gl::State::EXTENDED_DIRTY_BIT_CLIP_DISTANCES: invalidateGraphicsDriverUniforms(); break; + case gl::State::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED: + break; case gl::State::EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT: break; case gl::State::EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT: @@ -7205,6 +7266,9 @@ angle::Result ContextVk::beginNewRenderPass( depthStencilAttachmentIndex, clearValues, renderPassQueueSerial, commandBufferOut)); + // By default all render pass should allow to be reactivated. + mAllowRenderPassToReactivate = true; + if (mCurrentGraphicsPipeline) { ASSERT(mCurrentGraphicsPipeline->valid()); @@ -7653,13 +7717,11 @@ angle::Result ContextVk::endRenderPassQuery(QueryVk *queryVk) void ContextVk::pauseRenderPassQueriesIfActive() { - ASSERT(hasActiveRenderPass()); for (QueryVk *activeQuery : mActiveRenderPassQueries) { if (activeQuery) { activeQuery->onRenderPassEnd(this); - // No need to update rasterizer discard emulation with primitives generated query. The // state will be updated when the next render pass starts. } @@ -7668,7 +7730,6 @@ void ContextVk::pauseRenderPassQueriesIfActive() angle::Result ContextVk::resumeRenderPassQueriesIfActive() { - ASSERT(hasActiveRenderPass()); // Note: these queries should be processed in order. See comment in QueryVk::onRenderPassStart. for (QueryVk *activeQuery : mActiveRenderPassQueries) { @@ -7695,7 +7756,6 @@ angle::Result ContextVk::resumeRenderPassQueriesIfActive() angle::Result ContextVk::resumeXfbRenderPassQueriesIfActive() { - ASSERT(hasActiveRenderPass()); // All other queries are handled separately. QueryVk *xfbQuery = mActiveRenderPassQueries[gl::QueryType::TransformFeedbackPrimitivesWritten]; if (xfbQuery && mState.isTransformFeedbackActiveUnpaused()) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.h index 5b399dd21f69..c4b6d7f6588c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.h @@ -278,6 +278,8 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText angle::Result syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits, const gl::State::DirtyBits &bitMask, + const gl::State::ExtendedDirtyBits &extendedDirtyBits, + const gl::State::ExtendedDirtyBits &extendedBitMask, gl::Command command) override; // Disjoint timer queries @@ -626,11 +628,6 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText return mRenderPassCommands->started() && mRenderPassCommands->usesImage(image); } - bool hasActiveRenderPassWithCommands() const - { - return hasActiveRenderPass() && !mRenderPassCommands->getCommandBuffer().empty(); - } - vk::RenderPassCommandBufferHelper &getStartedRenderPassCommands() { ASSERT(mRenderPassCommands->started()); @@ -792,6 +789,13 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText const QueueSerial &getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; } + // Uploading mutable mipmap textures is currently restricted to single-context applications. + bool isEligibleForMutableTextureFlush() const + { + return getFeatures().mutableMipmapTextureUpload.enabled && !hasDisplayTextureShareGroup() && + mShareGroupVk->getContextCount() == 1; + } + private: // Dirty bits. enum DirtyBitType : size_t @@ -1543,6 +1547,9 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText // avoiding render pass breaks when a framebuffer fetch program is used mid render pass. bool mIsInFramebufferFetchMode; + // True if current started render pass is allowed to reactivate. + bool mAllowRenderPassToReactivate; + // The size of copy commands issued between buffers and images. Used to submit the command // buffer for the outside render pass. VkDeviceSize mTotalBufferToImageCopySize; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/DisplayVk.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/DisplayVk.h index f1f54940876a..f2bf62268e2d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/DisplayVk.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/DisplayVk.h @@ -88,6 +88,8 @@ class ShareGroupVk : public ShareGroupImpl return mMetaDescriptorPools[descriptorSetIndex]; } + size_t getContextCount() const { return mContexts.size(); } + // Used to flush the mutable textures more often. angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.cpp index 1bd7862d2b81..e0ffbfc4d5d7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.cpp @@ -523,18 +523,19 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context, bool clearDepthWithDraw = clearDepth && scissoredClear; bool clearStencilWithDraw = clearStencil && (maskedClearStencil || scissoredClear); - const bool isMidRenderPassClear = contextVk->hasActiveRenderPassWithCommands(); + const bool isMidRenderPassClear = + contextVk->hasStartedRenderPassWithQueueSerial(mLastRenderPassQueueSerial) && + !contextVk->getStartedRenderPassCommands().getCommandBuffer().empty(); if (isMidRenderPassClear) { - // If a render pass is open with commands, it must be for this framebuffer. Otherwise, - // either FramebufferVk::syncState() or ContextVk::syncState() would have closed it. - ASSERT(contextVk->hasStartedRenderPassWithQueueSerial(mLastRenderPassQueueSerial)); // Emit debug-util markers for this mid-render-pass clear ANGLE_TRY( contextVk->handleGraphicsEventLog(rx::GraphicsEventCmdBuf::InRenderPassCmdBufQueryCmd)); } else { + ASSERT(!contextVk->hasActiveRenderPass() || + contextVk->hasStartedRenderPassWithQueueSerial(mLastRenderPassQueueSerial)); // Emit debug-util markers for this outside-render-pass clear ANGLE_TRY( contextVk->handleGraphicsEventLog(rx::GraphicsEventCmdBuf::InOutsideCmdBufQueryCmd)); @@ -675,7 +676,8 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context, { // Start a new render pass if necessary to record the commands. vk::RenderPassCommandBuffer *commandBuffer; - ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer, nullptr)); + gl::Rectangle renderArea = getRenderArea(contextVk); + ANGLE_TRY(contextVk->startRenderPass(renderArea, &commandBuffer, nullptr)); } // Build clear values @@ -2829,7 +2831,7 @@ angle::Result FramebufferVk::getSamplePosition(const gl::Context *context, } angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, - const gl::Rectangle &scissoredRenderArea, + const gl::Rectangle &renderArea, vk::RenderPassCommandBuffer **commandBufferOut, bool *renderPassDescChangedOut) { @@ -3062,13 +3064,9 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ANGLE_TRY( getFramebuffer(contextVk, &framebuffer, nullptr, nullptr, SwapchainResolveMode::Disabled)); - // If deferred clears were used in the render pass, expand the render area to the whole + // If deferred clears were used in the render pass, the render area must cover the whole // framebuffer. - gl::Rectangle renderArea = scissoredRenderArea; - if (hasDeferredClears) - { - renderArea = getRotatedCompleteRenderArea(contextVk); - } + ASSERT(!hasDeferredClears || renderArea == getRotatedCompleteRenderArea(contextVk)); ANGLE_TRY(contextVk->beginNewRenderPass( framebuffer, renderArea, mRenderPassDesc, renderPassAttachmentOps, colorIndexVk, @@ -3117,6 +3115,18 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, return angle::Result::Continue; } +gl::Rectangle FramebufferVk::getRenderArea(ContextVk *contextVk) const +{ + if (hasDeferredClears()) + { + return getRotatedCompleteRenderArea(contextVk); + } + else + { + return getRotatedScissoredRenderArea(contextVk); + } +} + void FramebufferVk::updateActiveColorMasks(size_t colorIndexGL, bool r, bool g, bool b, bool a) { gl::BlendStateExt::ColorMaskStorage::SetValueIndexed( diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.h index e0f8c3f06ded..656652e45e31 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/FramebufferVk.h @@ -103,13 +103,16 @@ class FramebufferVk : public FramebufferImpl gl::Rectangle getNonRotatedCompleteRenderArea() const; gl::Rectangle getRotatedCompleteRenderArea(ContextVk *contextVk) const; gl::Rectangle getRotatedScissoredRenderArea(ContextVk *contextVk) const; + // Returns render area with deferred clears in consideration. When deferred clear is used + // in the render pass, the render area must cover the whole framebuffer. + gl::Rectangle getRenderArea(ContextVk *contextVk) const; const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const; RenderTargetVk *getColorDrawRenderTarget(size_t colorIndex) const; RenderTargetVk *getColorReadRenderTarget() const; angle::Result startNewRenderPass(ContextVk *contextVk, - const gl::Rectangle &scissoredRenderArea, + const gl::Rectangle &renderArea, vk::RenderPassCommandBuffer **commandBufferOut, bool *renderPassDescChangedOut); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.cpp index 0dbdefed5e32..1a9aaea19a95 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.cpp @@ -3617,6 +3617,9 @@ void RendererVk::initFeatures(DisplayVk *displayVk, isVulkan11Device() || ExtensionFound(VK_KHR_MAINTENANCE1_EXTENSION_NAME, deviceExtensionNames); + ANGLE_FEATURE_CONDITION(&mFeatures, appendAliasedMemoryDecorationsToSsbo, + isARM && (isVenus || armDriverVersion >= ARMDriverVersion(38, 1, 0))); + ANGLE_FEATURE_CONDITION( &mFeatures, supportsSharedPresentableImageExtension, ExtensionFound(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, deviceExtensionNames)); @@ -4152,10 +4155,7 @@ void RendererVk::initFeatures(DisplayVk *displayVk, // http://anglebug.com/7308 // Flushing mutable textures causes flakes in perf tests using Windows/Intel GPU. Failures are // due to lost context/device. - // http://b/264143971 - // The mutable texture uploading feature can sometimes result in incorrect rendering of some - // textures. - ANGLE_FEATURE_CONDITION(&mFeatures, mutableMipmapTextureUpload, false); + ANGLE_FEATURE_CONDITION(&mFeatures, mutableMipmapTextureUpload, !(IsWindows() && isIntel)); // Use VMA for image suballocation. ANGLE_FEATURE_CONDITION(&mFeatures, useVmaForImageSuballocation, true); @@ -4188,6 +4188,10 @@ void RendererVk::initFeatures(DisplayVk *displayVk, ANGLE_FEATURE_CONDITION(&mFeatures, forceStaticVertexStrideState, mFeatures.supportsExtendedDynamicState.enabled && isARM); + // Avoid dynamic state for primitive restart on buggy drivers. + ANGLE_FEATURE_CONDITION(&mFeatures, forceStaticPrimitiveRestartState, + mFeatures.supportsExtendedDynamicState2.enabled && isARM); + // Support GL_QCOM_shading_rate extension ANGLE_FEATURE_CONDITION(&mFeatures, supportsFragmentShadingRate, canSupportFragmentShadingRate(deviceExtensionNames)); @@ -4369,18 +4373,6 @@ void RendererVk::initFeatures(DisplayVk *displayVk, ApplyFeatureOverrides(&mFeatures, displayVk->getState()); - // Disable async command queue when using Vulkan secondary command buffers temporarily to avoid - // threading hazards with ContextVk::mCommandPools. Note that this is done even if the feature - // is enabled through an override. - // TODO: Investigate whether async command queue is useful with Vulkan secondary command buffers - // and enable the feature. http://anglebug.com/6811 - if (!vk::OutsideRenderPassCommandBuffer::ExecutesInline() || - !vk::RenderPassCommandBuffer::ExecutesInline()) - { - mFeatures.asyncCommandQueue.enabled = false; - mFeatures.asyncCommandBufferReset.enabled = false; - } - // Disable memory report feature overrides if extension is not supported. if ((mFeatures.logMemoryReportCallbacks.enabled || mFeatures.logMemoryReportStats.enabled) && !mMemoryReportFeatures.deviceMemoryReport) @@ -4688,17 +4680,22 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context, ANGLE_TRY(allocateScopedQueueSerialIndex(&index)); QueueSerial submitQueueSerial(index.get(), generateQueueSerial(index.get())); + ASSERT(waitSemaphore == nullptr || waitSemaphore->valid()); + ASSERT(fence == nullptr || fence->valid()); + const VkSemaphore waitVkSemaphore = waitSemaphore ? waitSemaphore->getHandle() : VK_NULL_HANDLE; + const VkFence vkFence = fence ? fence->getHandle() : VK_NULL_HANDLE; + if (isAsyncCommandQueueEnabled()) { ANGLE_TRY(mCommandProcessor.enqueueSubmitOneOffCommands( - context, protectionType, priority, primary.getHandle(), waitSemaphore, - waitSemaphoreStageMasks, fence, submitPolicy, submitQueueSerial)); + context, protectionType, priority, primary.getHandle(), waitVkSemaphore, + waitSemaphoreStageMasks, vkFence, submitPolicy, submitQueueSerial)); } else { ANGLE_TRY(mCommandQueue.queueSubmitOneOff( - context, protectionType, priority, primary.getHandle(), waitSemaphore, - waitSemaphoreStageMasks, fence, submitPolicy, submitQueueSerial)); + context, protectionType, priority, primary.getHandle(), waitVkSemaphore, + waitSemaphoreStageMasks, vkFence, submitPolicy, submitQueueSerial)); } *queueSerialOut = submitQueueSerial; @@ -4715,21 +4712,23 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context, angle::Result RendererVk::queueSubmitWaitSemaphore(vk::Context *context, egl::ContextPriority priority, - const vk::Semaphore *waitSemaphore, + const vk::Semaphore &waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMasks, QueueSerial submitQueueSerial) { if (isAsyncCommandQueueEnabled()) { ANGLE_TRY(mCommandProcessor.enqueueSubmitOneOffCommands( - context, vk::ProtectionType::Unprotected, priority, VK_NULL_HANDLE, waitSemaphore, - waitSemaphoreStageMasks, nullptr, vk::SubmitPolicy::AllowDeferred, submitQueueSerial)); + context, vk::ProtectionType::Unprotected, priority, VK_NULL_HANDLE, + waitSemaphore.getHandle(), waitSemaphoreStageMasks, VK_NULL_HANDLE, + vk::SubmitPolicy::AllowDeferred, submitQueueSerial)); } else { ANGLE_TRY(mCommandQueue.queueSubmitOneOff( - context, vk::ProtectionType::Unprotected, priority, VK_NULL_HANDLE, waitSemaphore, - waitSemaphoreStageMasks, nullptr, vk::SubmitPolicy::AllowDeferred, submitQueueSerial)); + context, vk::ProtectionType::Unprotected, priority, VK_NULL_HANDLE, + waitSemaphore.getHandle(), waitSemaphoreStageMasks, VK_NULL_HANDLE, + vk::SubmitPolicy::AllowDeferred, submitQueueSerial)); } return angle::Result::Continue; @@ -5039,26 +5038,19 @@ angle::Result RendererVk::submitCommands(vk::Context *context, const vk::Semaphore *signalSemaphore, const QueueSerial &submitQueueSerial) { - vk::SecondaryCommandBufferList commandBuffersToReset; - mOutsideRenderPassCommandBufferRecycler.releaseCommandBuffersToReset( - &commandBuffersToReset.outsideRenderPassCommandBuffers); - mRenderPassCommandBufferRecycler.releaseCommandBuffersToReset( - &commandBuffersToReset.renderPassCommandBuffers); - + ASSERT(signalSemaphore == nullptr || signalSemaphore->valid()); const VkSemaphore signalVkSemaphore = signalSemaphore ? signalSemaphore->getHandle() : VK_NULL_HANDLE; if (isAsyncCommandQueueEnabled()) { - ANGLE_TRY(mCommandProcessor.enqueueSubmitCommands( - context, protectionType, contextPriority, signalVkSemaphore, - std::move(commandBuffersToReset), submitQueueSerial)); + ANGLE_TRY(mCommandProcessor.enqueueSubmitCommands(context, protectionType, contextPriority, + signalVkSemaphore, submitQueueSerial)); } else { ANGLE_TRY(mCommandQueue.submitCommands(context, protectionType, contextPriority, - signalVkSemaphore, std::move(commandBuffersToReset), - submitQueueSerial)); + signalVkSemaphore, submitQueueSerial)); } ANGLE_TRY(mCommandQueue.postSubmitCheck(context)); @@ -5101,7 +5093,7 @@ angle::Result RendererVk::submitPriorityDependency(vk::Context *context, // Submit only Wait Semaphore into the destination Priority (VkQueue). QueueSerial queueSerial(index, generateQueueSerial(index)); semaphore.get().setQueueSerial(queueSerial); - ANGLE_TRY(queueSubmitWaitSemaphore(context, dstContextPriority, &semaphore.get().get(), + ANGLE_TRY(queueSubmitWaitSemaphore(context, dstContextPriority, semaphore.get().get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, queueSerial)); return angle::Result::Continue; @@ -5251,7 +5243,7 @@ void RendererVk::queuePresent(vk::Context *context, template angle::Result RendererVk::getCommandBufferImpl( vk::Context *context, - vk::CommandPool *commandPool, + vk::SecondaryCommandPool *commandPool, vk::SecondaryCommandMemoryAllocator *commandsAllocator, RecyclerT *recycler, CommandBufferHelperT **commandBufferHelperOut) @@ -5262,7 +5254,7 @@ angle::Result RendererVk::getCommandBufferImpl( angle::Result RendererVk::getOutsideRenderPassCommandBufferHelper( vk::Context *context, - vk::CommandPool *commandPool, + vk::SecondaryCommandPool *commandPool, vk::SecondaryCommandMemoryAllocator *commandsAllocator, vk::OutsideRenderPassCommandBufferHelper **commandBufferHelperOut) { @@ -5273,7 +5265,7 @@ angle::Result RendererVk::getOutsideRenderPassCommandBufferHelper( angle::Result RendererVk::getRenderPassCommandBufferHelper( vk::Context *context, - vk::CommandPool *commandPool, + vk::SecondaryCommandPool *commandPool, vk::SecondaryCommandMemoryAllocator *commandsAllocator, vk::RenderPassCommandBufferHelper **commandBufferHelperOut) { @@ -5283,19 +5275,17 @@ angle::Result RendererVk::getRenderPassCommandBufferHelper( } void RendererVk::recycleOutsideRenderPassCommandBufferHelper( - VkDevice device, vk::OutsideRenderPassCommandBufferHelper **commandBuffer) { ANGLE_TRACE_EVENT0("gpu.angle", "RendererVk::recycleOutsideRenderPassCommandBufferHelper"); - mOutsideRenderPassCommandBufferRecycler.recycleCommandBufferHelper(device, commandBuffer); + mOutsideRenderPassCommandBufferRecycler.recycleCommandBufferHelper(commandBuffer); } void RendererVk::recycleRenderPassCommandBufferHelper( - VkDevice device, vk::RenderPassCommandBufferHelper **commandBuffer) { ANGLE_TRACE_EVENT0("gpu.angle", "RendererVk::recycleRenderPassCommandBufferHelper"); - mRenderPassCommandBufferRecycler.recycleCommandBufferHelper(device, commandBuffer); + mRenderPassCommandBufferRecycler.recycleCommandBufferHelper(commandBuffer); } void RendererVk::logCacheStats() const diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.h index 3acb6b588cb7..e07310a3bf74 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/RendererVk.h @@ -284,16 +284,6 @@ class RendererVk : angle::NonCopyable return mOneOffCommandPoolMap[protectionType].getCommandBuffer(context, commandBufferOut); } - void resetOutsideRenderPassCommandBuffer(vk::OutsideRenderPassCommandBuffer &&commandBuffer) - { - mOutsideRenderPassCommandBufferRecycler.resetCommandBuffer(std::move(commandBuffer)); - } - - void resetRenderPassCommandBuffer(vk::RenderPassCommandBuffer &&commandBuffer) - { - mRenderPassCommandBufferRecycler.resetCommandBuffer(std::move(commandBuffer)); - } - // Fire off a single command buffer immediately with default priority. // Command buffer must be allocated with getCommandBufferOneOff and is reclaimed. angle::Result queueSubmitOneOff(vk::Context *context, @@ -308,7 +298,7 @@ class RendererVk : angle::NonCopyable angle::Result queueSubmitWaitSemaphore(vk::Context *context, egl::ContextPriority priority, - const vk::Semaphore *waitSemaphore, + const vk::Semaphore &waitSemaphore, VkPipelineStageFlags waitSemaphoreStageMasks, QueueSerial submitQueueSerial); @@ -509,6 +499,7 @@ class RendererVk : angle::NonCopyable VkResult *result); angle::Result finish(vk::Context *context); angle::Result checkCompletedCommands(vk::Context *context); + angle::Result retireFinishedCommands(vk::Context *context); angle::Result flushWaitSemaphores(vk::ProtectionType protectionType, egl::ContextPriority priority, @@ -535,20 +526,18 @@ class RendererVk : angle::NonCopyable angle::Result getOutsideRenderPassCommandBufferHelper( vk::Context *context, - vk::CommandPool *commandPool, + vk::SecondaryCommandPool *commandPool, vk::SecondaryCommandMemoryAllocator *commandsAllocator, vk::OutsideRenderPassCommandBufferHelper **commandBufferHelperOut); angle::Result getRenderPassCommandBufferHelper( vk::Context *context, - vk::CommandPool *commandPool, + vk::SecondaryCommandPool *commandPool, vk::SecondaryCommandMemoryAllocator *commandsAllocator, vk::RenderPassCommandBufferHelper **commandBufferHelperOut); void recycleOutsideRenderPassCommandBufferHelper( - VkDevice device, vk::OutsideRenderPassCommandBufferHelper **commandBuffer); - void recycleRenderPassCommandBufferHelper(VkDevice device, - vk::RenderPassCommandBufferHelper **commandBuffer); + void recycleRenderPassCommandBufferHelper(vk::RenderPassCommandBufferHelper **commandBuffer); // Process GPU memory reports void processMemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT &callbackData) @@ -758,7 +747,7 @@ class RendererVk : angle::NonCopyable template angle::Result getCommandBufferImpl(vk::Context *context, - vk::CommandPool *commandPool, + vk::SecondaryCommandPool *commandPool, vk::SecondaryCommandMemoryAllocator *commandsAllocator, RecyclerT *recycler, CommandBufferHelperT **commandBufferHelperOut); @@ -949,11 +938,9 @@ class RendererVk : angle::NonCopyable vk::CommandProcessor mCommandProcessor; // Command buffer pool management. - vk::CommandBufferRecycler + vk::CommandBufferRecycler mOutsideRenderPassCommandBufferRecycler; - vk::CommandBufferRecycler - mRenderPassCommandBufferRecycler; + vk::CommandBufferRecycler mRenderPassCommandBufferRecycler; SamplerCache mSamplerCache; SamplerYcbcrConversionCache mYuvConversionCache; @@ -1069,6 +1056,11 @@ ANGLE_INLINE angle::Result RendererVk::checkCompletedCommands(vk::Context *conte { return mCommandQueue.checkAndCleanupCompletedCommands(context); } + +ANGLE_INLINE angle::Result RendererVk::retireFinishedCommands(vk::Context *context) +{ + return mCommandQueue.retireFinishedCommands(context); +} } // namespace rx #endif // LIBANGLE_RENDERER_VULKAN_RENDERERVK_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandBuffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandBuffer.h index 685820307159..3ba6ed544100 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandBuffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandBuffer.h @@ -29,6 +29,7 @@ namespace vk { class Context; class RenderPassDesc; +class SecondaryCommandPool; #if ANGLE_ENABLE_VULKAN_SHARED_RING_BUFFER_CMD_ALLOC using SecondaryCommandMemoryAllocator = SharedCommandMemoryAllocator; @@ -634,7 +635,7 @@ class SecondaryCommandBuffer final : angle::NonCopyable static constexpr bool ExecutesInline() { return true; } static angle::Result InitializeCommandPool(Context *context, - CommandPool *pool, + SecondaryCommandPool *pool, uint32_t queueFamilyIndex, ProtectionType protectionType) { @@ -891,7 +892,7 @@ class SecondaryCommandBuffer final : angle::NonCopyable // Initialize the SecondaryCommandBuffer by setting the allocator it will use angle::Result initialize(vk::Context *context, - vk::CommandPool *pool, + vk::SecondaryCommandPool *pool, bool isRenderPassCommandBuffer, SecondaryCommandMemoryAllocator *allocator) { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.cpp new file mode 100644 index 000000000000..a584cf1955f1 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.cpp @@ -0,0 +1,126 @@ +// +// Copyright 2023 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. +// +// SecondaryCommandPool: +// A class for allocating Command Buffers for VulkanSecondaryCommandBuffer. +// + +#include "libANGLE/renderer/vulkan/SecondaryCommandPool.h" + +#include "common/debug.h" +#include "libANGLE/renderer/vulkan/RendererVk.h" +#include "libANGLE/renderer/vulkan/vk_utils.h" + +namespace rx +{ +namespace vk +{ + +SecondaryCommandPool::SecondaryCommandPool() {} + +SecondaryCommandPool::~SecondaryCommandPool() +{ + ASSERT(mCollectedBuffers.empty()); + ASSERT(mCollectedBuffersOverflow.empty()); +} + +angle::Result SecondaryCommandPool::init(Context *context, + uint32_t queueFamilyIndex, + ProtectionType protectionType) +{ + VkCommandPoolCreateInfo poolInfo = {}; + poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + poolInfo.queueFamilyIndex = queueFamilyIndex; + if (context->getRenderer()->getFeatures().useResetCommandBufferBitForSecondaryPools.enabled) + { + poolInfo.flags |= VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + } + ASSERT(protectionType == ProtectionType::Unprotected || + protectionType == ProtectionType::Protected); + if (protectionType == ProtectionType::Protected) + { + poolInfo.flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT; + } + ANGLE_VK_TRY(context, mCommandPool.init(context->getDevice(), poolInfo)); + return angle::Result::Continue; +} + +void SecondaryCommandPool::destroy(VkDevice device) +{ + // Command buffers will be destroyed with the Pool. Avoid possible slowdown during cleanup. + mCollectedBuffers.clear(); + mCollectedBuffersOverflow.clear(); + mCommandPool.destroy(device); +} + +angle::Result SecondaryCommandPool::allocate(Context *context, VulkanSecondaryCommandBuffer *buffer) +{ + ASSERT(valid()); + ASSERT(!buffer->valid()); + + VkDevice device = context->getDevice(); + + freeCollectedBuffers(device); + + VkCommandBufferAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; + allocInfo.commandBufferCount = 1; + allocInfo.commandPool = mCommandPool.getHandle(); + + ANGLE_VK_TRY(context, buffer->init(device, allocInfo)); + + return angle::Result::Continue; +} + +void SecondaryCommandPool::collect(VulkanSecondaryCommandBuffer *buffer) +{ + ASSERT(valid()); + ASSERT(buffer->valid()); + + VkCommandBuffer bufferHandle = buffer->releaseHandle(); + + if (!mCollectedBuffers.full()) + { + mCollectedBuffers.push(bufferHandle); + } + else + { + std::lock_guard lock(mOverflowMutex); + mCollectedBuffersOverflow.emplace_back(bufferHandle); + mHasOverflow.store(true, std::memory_order_relaxed); + } +} + +void SecondaryCommandPool::freeCollectedBuffers(VkDevice device) +{ + // Free Command Buffer for now. May later add recycling or reset/free pool at once. + ANGLE_TRACE_EVENT0("gpu.angle", "SecondaryCommandPool::freeCollectedBuffers"); + + while (!mCollectedBuffers.empty()) + { + VkCommandBuffer bufferHandle = mCollectedBuffers.front(); + mCommandPool.freeCommandBuffers(device, 1, &bufferHandle); + mCollectedBuffers.pop(); + } + + if (ANGLE_UNLIKELY(mHasOverflow.load(std::memory_order_relaxed))) + { + std::vector buffers; + { + std::lock_guard lock(mOverflowMutex); + buffers = std::move(mCollectedBuffersOverflow); + mHasOverflow.store(false, std::memory_order_relaxed); + } + for (VkCommandBuffer bufferHandle : buffers) + { + mCommandPool.freeCommandBuffers(device, 1, &bufferHandle); + } + } +} + +} // namespace vk +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.h new file mode 100644 index 000000000000..5e769df96c8d --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SecondaryCommandPool.h @@ -0,0 +1,69 @@ +// +// Copyright 2023 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. +// +// SecondaryCommandPool: +// A class for allocating Command Buffers for VulkanSecondaryCommandBuffer. +// + +#ifndef LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDPOOL_H_ +#define LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDPOOL_H_ + +#include "common/FixedQueue.h" +#include "libANGLE/renderer/vulkan/vk_command_buffer_utils.h" +#include "libANGLE/renderer/vulkan/vk_wrapper.h" + +namespace rx +{ +namespace vk +{ +class Context; +class VulkanSecondaryCommandBuffer; + +// VkCommandPool must be externally synchronized when its Command Buffers are: allocated, freed, +// reset, or recorded. This class ensures that Command Buffers are freed from the thread that +// recording commands (Context thread). +class SecondaryCommandPool final : angle::NonCopyable +{ + public: + SecondaryCommandPool(); + ~SecondaryCommandPool(); + + angle::Result init(Context *context, uint32_t queueFamilyIndex, ProtectionType protectionType); + void destroy(VkDevice device); + + bool valid() const { return mCommandPool.valid(); } + + // Call only from the Context thread that owns the SecondaryCommandPool instance. + angle::Result allocate(Context *context, VulkanSecondaryCommandBuffer *buffer); + + // Single threaded - use external synchronization. + // Example threads: any Context thread or "asyncCommandQueue" thread. + void collect(VulkanSecondaryCommandBuffer *buffer); + + private: + static constexpr size_t kFixedQueueLimit = 100u; + + // Context thread access members. + + void freeCollectedBuffers(VkDevice device); + + // Use single pool for now. + CommandPool mCommandPool; + + // Other thread access members. + + // Fast lock free queue for processing buffers while new may be added from the other thread. + angle::FixedQueue mCollectedBuffers; + + // Overflow vector to use in cases when FixedQueue is filled. + std::vector mCollectedBuffersOverflow; + std::mutex mOverflowMutex; + std::atomic mHasOverflow; +}; + +} // namespace vk +} // namespace rx + +#endif // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDPOOL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ShaderVk.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ShaderVk.cpp index 189cc1462504..007665e25a37 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ShaderVk.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ShaderVk.cpp @@ -108,6 +108,11 @@ std::shared_ptr ShaderVk::compile(const gl::Context *conte options->precisionSafeDivision = true; } + if (contextVk->getFeatures().appendAliasedMemoryDecorationsToSsbo.enabled) + { + options->aliasedSSBOUnlessRestrict = true; + } + if (contextVk->getExtensions().shaderPixelLocalStorageANGLE) { options->pls = contextVk->getNativePixelLocalStorageOptions(); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/TextureVk.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/TextureVk.cpp index 06a2d15e3264..5e5ba9fd2501 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/TextureVk.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/TextureVk.cpp @@ -675,8 +675,7 @@ angle::Result TextureVk::setSubImageImpl(const gl::Context *context, ANGLE_TRY(contextVk->submitStagedTextureUpdates()); } } - else if (contextVk->getFeatures().mutableMipmapTextureUpload.enabled && - !contextVk->hasDisplayTextureShareGroup() && !mState.getImmutableFormat()) + else if (contextVk->isEligibleForMutableTextureFlush() && !mState.getImmutableFormat()) { // Check if we should flush any mutable textures from before. ANGLE_TRY(contextVk->getShareGroup()->onMutableTextureUpload(contextVk, this)); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/UtilsVk.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/UtilsVk.cpp index ce06d10615cb..559369f71f7a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/UtilsVk.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/UtilsVk.cpp @@ -1106,7 +1106,10 @@ void ResetDynamicState(ContextVk *contextVk, vk::RenderPassCommandBuffer *comman { commandBuffer->setRasterizerDiscardEnable(VK_FALSE); commandBuffer->setDepthBiasEnable(VK_FALSE); - commandBuffer->setPrimitiveRestartEnable(VK_FALSE); + if (!contextVk->getFeatures().forceStaticPrimitiveRestartState.enabled) + { + commandBuffer->setPrimitiveRestartEnable(VK_FALSE); + } } if (contextVk->getFeatures().supportsFragmentShadingRate.enabled) { @@ -2198,6 +2201,8 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, } else { + // Deferred clears should be handled already. + ASSERT(!framebuffer->hasDeferredClears()); ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer, nullptr)); } @@ -2308,7 +2313,8 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, } } - ASSERT(contextVk->hasActiveRenderPass()); + ASSERT(contextVk->hasStartedRenderPassWithQueueSerial( + framebuffer->getLastRenderPassQueueSerial())); // Make sure this draw call doesn't count towards occlusion query results. contextVk->pauseRenderPassQueriesIfActive(); commandBuffer->draw(3, 0); @@ -2596,6 +2602,8 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk, SetStencilStateForWrite(&pipelineDesc); } + // All deferred clear must have been flushed, otherwise it will conflict with params.blitArea. + ASSERT(!framebuffer->hasDeferredClears()); vk::RenderPassCommandBuffer *commandBuffer; ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer, nullptr)); @@ -2603,8 +2611,11 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk, ANGLE_TRY(allocateDescriptorSet(contextVk, &contextVk->getStartedRenderPassCommands(), Function::BlitResolve, &descriptorSet)); - contextVk->onImageRenderPassRead(src->getAspectFlags(), vk::ImageLayout::FragmentShaderReadOnly, - src); + // Pick layout consistent with GetImageReadLayout() to avoid unnecessary layout change. + vk::ImageLayout srcImagelayout = src->isDepthOrStencil() + ? vk::ImageLayout::DepthReadStencilReadFragmentShaderRead + : vk::ImageLayout::FragmentShaderReadOnly; + contextVk->onImageRenderPassRead(src->getAspectFlags(), srcImagelayout, src); UpdateColorAccess(contextVk, framebuffer->getState().getColorAttachmentsMask(), framebuffer->getState().getEnabledDrawBuffers()); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.cpp index 0d21cf7991f8..15387ef3cc5c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.cpp @@ -18,25 +18,11 @@ namespace rx namespace vk { angle::Result VulkanSecondaryCommandBuffer::InitializeCommandPool(Context *context, - CommandPool *pool, + SecondaryCommandPool *pool, uint32_t queueFamilyIndex, ProtectionType protectionType) { - VkCommandPoolCreateInfo poolInfo = {}; - poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; - poolInfo.queueFamilyIndex = queueFamilyIndex; - if (context->getRenderer()->getFeatures().useResetCommandBufferBitForSecondaryPools.enabled) - { - poolInfo.flags |= VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - } - ASSERT(protectionType == ProtectionType::Unprotected || - protectionType == ProtectionType::Protected); - if (protectionType == ProtectionType::Protected) - { - poolInfo.flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT; - } - ANGLE_VK_TRY(context, pool->init(context->getDevice(), poolInfo)); + ANGLE_TRY(pool->init(context, queueFamilyIndex, protectionType)); return angle::Result::Continue; } @@ -46,7 +32,7 @@ angle::Result VulkanSecondaryCommandBuffer::InitializeRenderPassInheritanceInfo( const RenderPassDesc &renderPassDesc, VkCommandBufferInheritanceInfo *inheritanceInfoOut) { - const vk::RenderPass *compatibleRenderPass = nullptr; + const RenderPass *compatibleRenderPass = nullptr; ANGLE_TRY(contextVk->getCompatibleRenderPass(renderPassDesc, &compatibleRenderPass)); inheritanceInfoOut->sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; @@ -58,23 +44,15 @@ angle::Result VulkanSecondaryCommandBuffer::InitializeRenderPassInheritanceInfo( } angle::Result VulkanSecondaryCommandBuffer::initialize(Context *context, - vk::CommandPool *pool, + SecondaryCommandPool *pool, bool isRenderPassCommandBuffer, SecondaryCommandMemoryAllocator *allocator) { - VkDevice device = context->getDevice(); - mCommandPool = pool; mCommandTracker.reset(); mAnyCommand = false; - VkCommandBufferAllocateInfo allocInfo = {}; - allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; - allocInfo.commandBufferCount = 1; - allocInfo.commandPool = pool->getHandle(); - - ANGLE_VK_TRY(context, init(device, allocInfo)); + ANGLE_TRY(pool->allocate(context, this)); // Outside-RP command buffers are begun automatically here. RP command buffers are begun when // the render pass itself starts, as they require inheritance info. @@ -88,12 +66,12 @@ angle::Result VulkanSecondaryCommandBuffer::initialize(Context *context, return angle::Result::Continue; } -void VulkanSecondaryCommandBuffer::free(VkDevice device) +void VulkanSecondaryCommandBuffer::destroy() { - if (mHandle != VK_NULL_HANDLE) + if (valid()) { - mCommandPool->freeCommandBuffers(device, 1, &mHandle); - mHandle = VK_NULL_HANDLE; + ASSERT(mCommandPool != nullptr); + mCommandPool->collect(this); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.h index 86ea27734297..f66f914305ec 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.h @@ -34,6 +34,7 @@ namespace vk { class Context; class RenderPassDesc; +class SecondaryCommandPool; class VulkanSecondaryCommandBuffer : public priv::CommandBuffer { @@ -41,7 +42,7 @@ class VulkanSecondaryCommandBuffer : public priv::CommandBuffer VulkanSecondaryCommandBuffer() = default; static angle::Result InitializeCommandPool(Context *context, - CommandPool *pool, + SecondaryCommandPool *pool, uint32_t queueFamilyIndex, ProtectionType protectionType); static angle::Result InitializeRenderPassInheritanceInfo( @@ -50,20 +51,19 @@ class VulkanSecondaryCommandBuffer : public priv::CommandBuffer const RenderPassDesc &renderPassDesc, VkCommandBufferInheritanceInfo *inheritanceInfoOut); - angle::Result initialize(vk::Context *context, - vk::CommandPool *pool, + angle::Result initialize(Context *context, + SecondaryCommandPool *pool, bool isRenderPassCommandBuffer, SecondaryCommandMemoryAllocator *allocator); - void free(VkDevice device); + void destroy(); void attachAllocator(SecondaryCommandMemoryAllocator *source) {} void detachAllocator(SecondaryCommandMemoryAllocator *destination) {} - angle::Result begin(vk::Context *context, - const VkCommandBufferInheritanceInfo &inheritanceInfo); - angle::Result end(vk::Context *context); + angle::Result begin(Context *context, const VkCommandBufferInheritanceInfo &inheritanceInfo); + angle::Result end(Context *context); VkResult reset(); void executeCommands(PrimaryCommandBuffer *primary) { primary->executeCommands(1, this); } @@ -234,9 +234,14 @@ class VulkanSecondaryCommandBuffer : public priv::CommandBuffer void open() const {} void close() const {} - bool empty() const { return !mAnyCommand; } + bool empty() const + { + ASSERT(valid()); + return !mAnyCommand; + } uint32_t getRenderPassWriteCommandCount() const { + ASSERT(valid()); return mCommandTracker.getRenderPassWriteCommandCount(); } std::string dumpCommands(const char *separator) const { return ""; } @@ -244,7 +249,7 @@ class VulkanSecondaryCommandBuffer : public priv::CommandBuffer private: void onRecordCommand() { mAnyCommand = true; } - CommandPool *mCommandPool = nullptr; + SecondaryCommandPool *mCommandPool = nullptr; CommandBufferCommandTracker mCommandTracker; bool mAnyCommand = false; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000000.inc b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000000.inc index 546564271000..eea431b04975 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000000.inc +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000000.inc @@ -10,440 +10,475 @@ #pragma once constexpr uint8_t kEtcToBc_comp_00000000[] = { - 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0x6d,0x5c,0x0b,0xd8,0x56,0x53, - 0xda,0x7e,0xdf,0xef,0xfd,0xf6,0xf9,0x45,0x07,0x45,0x44,0x0e,0x33,0xc3,0x84,0x8c, - 0xe3,0x6f,0xa4,0x72,0xce,0xa1,0x46,0x42,0x0e,0x8d,0x42,0x07,0x87,0x3f,0xa5,0xdf, - 0x94,0x10,0xa5,0x8c,0x1a,0x92,0x4c,0xdf,0x08,0x21,0xd2,0x20,0x34,0x61,0xc2,0x0c, - 0xfd,0x7e,0x9a,0x09,0x83,0x19,0x9a,0x86,0x0e,0xce,0x72,0x16,0x32,0xa3,0xc8,0x21, - 0xff,0xbe,0xdf,0xfb,0x7e,0xbe,0xfd,0x7c,0x6f,0x7d,0xd7,0xb5,0xae,0x77,0xaf,0xfb, - 0x39,0xac,0xe7,0x79,0xd6,0x5a,0xcf,0x5a,0x7b,0xef,0xb5,0xbf,0x4a,0xc3,0xce,0x51, - 0xa9,0x52,0x2e,0xa5,0xa5,0xb8,0xf4,0x70,0xb5,0x54,0xfb,0x6b,0x5d,0x6a,0x28,0x95, - 0xf5,0xdb,0x45,0xbf,0xdd,0xf4,0x7b,0x88,0x7e,0x0f,0xcb,0x7f,0xb3,0x52,0x58,0xe3, - 0xeb,0xd9,0xeb,0x84,0x5e,0x5d,0x2e,0xfc,0xd5,0xe0,0x2e,0xfb,0xee,0xf7,0x33,0xc8, - 0x6f,0x5e,0xaa,0xd4,0xf4,0x80,0xb6,0x45,0xae,0x37,0xc8,0x7f,0x1b,0xf3,0x72,0xfe, - 0x99,0xe7,0x0e,0x07,0xde,0x33,0x27,0xf7,0xce,0xcb,0xa4,0x1c,0x6c,0x95,0xeb,0x68, - 0xac,0xe9,0x2c,0x95,0x0e,0x96,0x0c,0xca,0x51,0xb9,0xd4,0xd3,0x34,0xa7,0xb4,0xb3, - 0x7e,0x0d,0x2b,0x0b,0x6b,0x74,0x58,0x83,0xb0,0xd8,0x61,0x15,0x61,0x55,0x87,0x35, - 0x0a,0x6b,0xe5,0xb0,0x40,0xd8,0x96,0x0e,0x0b,0x85,0x6d,0xed,0xb0,0x48,0x58,0x47, - 0xf8,0x90,0x6b,0xb7,0x76,0x7b,0xe6,0x5a,0xe1,0x53,0x96,0x5f,0x6f,0xa3,0x7a,0x6f, - 0xd5,0xb7,0x15,0x2f,0x7c,0x2d,0x89,0x86,0x6b,0xd0,0x7e,0xaa,0xfa,0xf1,0xb9,0x01, - 0x3b,0x95,0x0a,0x3a,0xea,0x3b,0x36,0xd7,0x2b,0xa5,0x6f,0x83,0x82,0xd6,0x2b,0x6c, - 0xc9,0x8b,0xfa,0x8e,0x8a,0x09,0x78,0x51,0xef,0x60,0x7a,0x42,0xb6,0xd3,0x41,0xb4, - 0xef,0x13,0xca,0xb5,0xcd,0xad,0x86,0xdd,0x3b,0xe6,0x58,0x45,0x3e,0xb4,0xcb,0xf9, - 0xe1,0xf3,0x0e,0xd2,0xbd,0x55,0x5e,0x8f,0x14,0x87,0x86,0x1a,0xde,0x58,0x8b,0x6d, - 0xa4,0x02,0xfe,0x44,0xfc,0x65,0xd1,0x53,0xd1,0x12,0xc9,0xb7,0xd2,0xb5,0xc9,0xb7, - 0x16,0xbd,0x55,0x2d,0xd6,0x0d,0xa5,0x36,0xe2,0xdb,0x52,0x7c,0x8d,0xe2,0xeb,0x24, - 0x3e,0xb4,0xdd,0x3e,0xb7,0x70,0x57,0xb5,0x03,0x5e,0xc4,0x6c,0x57,0xf5,0x2d,0xea, - 0x7b,0x8b,0x0f,0xf5,0xdd,0x64,0xd3,0x49,0x79,0xd9,0xc3,0xd5,0xfb,0x39,0x3a,0x78, - 0xfb,0xcb,0x66,0xa3,0x0f,0x50,0x3f,0x5b,0x7d,0xa0,0xc6,0x91,0xd5,0x87,0x68,0x6c, - 0x58,0x7d,0xa8,0x6c,0xb5,0xfa,0x30,0xf9,0x64,0xf5,0x91,0x1a,0x53,0x56,0x1f,0x9d, - 0x97,0x4e,0xae,0x3e,0x46,0x31,0x31,0x7b,0x26,0x4b,0xbe,0x63,0x5e,0xff,0x8d,0xda, - 0x9a,0xec,0xf8,0xaf,0xae,0xcd,0xa9,0x52,0x69,0xf7,0x3c,0x2a,0xa0,0x5d,0x23,0x1d, - 0x23,0x65,0xeb,0xd5,0x8e,0x77,0x8a,0xe2,0x61,0xf5,0x6b,0x15,0x5b,0xab,0x4f,0xd5, - 0x7c,0x30,0x5d,0xd7,0x49,0xd7,0x14,0xf1,0x4e,0x75,0xbc,0xd3,0xea,0xe2,0x74,0xbd, - 0xfa,0xc5,0x64,0x7f,0x2b,0x9e,0xa1,0xa2,0x4d,0x75,0xb4,0xe9,0xa2,0xf5,0x93,0x9d, - 0x5e,0x6f,0x53,0x89,0xe3,0xd2,0x78,0x7f,0xe7,0xfc,0xb9,0x5e,0x74,0xe3,0xbd,0x21, - 0x2f,0xa9,0xe3,0x9d,0xe1,0xec,0x1d,0x28,0xba,0xd1,0x6e,0x54,0x7b,0x53,0xa4,0xc7, - 0xd3,0x6e,0x92,0xdc,0xd0,0x4d,0xd0,0x6e,0x96,0xad,0xd6,0xfe,0xb5,0x8e,0x36,0xb3, - 0xce,0x47,0x4f,0xbb,0xc5,0xf9,0x58,0x4f,0xbb,0xd5,0xc9,0x4d,0xa9,0xa3,0xdd,0x26, - 0x5b,0xfa,0x39,0x9a,0xf9,0x3b,0x4b,0xf3,0xcf,0x78,0x6f,0x17,0x36,0x4d,0x32,0x5e, - 0xcf,0x1d,0x2e,0xbe,0xd7,0x2b,0x1e,0x46,0x9b,0xed,0xfc,0x9d,0xd2,0x4c,0x6b,0x5b, - 0x1b,0x5f,0x77,0x6a,0x0c,0x5d,0xa7,0x3e,0x9c,0xae,0x3e,0x98,0xa1,0x18,0xde,0xa4, - 0x98,0xcc,0x94,0x8f,0xb7,0xca,0xe6,0xdb,0xd5,0xe6,0x6c,0xcd,0xd3,0xbb,0x34,0x1e, - 0x7e,0xe3,0xec,0x5f,0x90,0x97,0x1f,0xf2,0xd2,0x39,0x9f,0x71,0x98,0xdf,0x8b,0xf3, - 0xb2,0x7d,0xde,0x83,0x96,0x53,0x43,0x8d,0xc7,0x70,0x13,0x05,0x3a,0x9f,0x11,0x1d, - 0xfc,0x5d,0x55,0x7f,0x56,0x18,0xe8,0x7f,0x73,0xf2,0x36,0x7f,0x96,0xd4,0xcd,0xa7, - 0xa5,0x8a,0xe1,0x4f,0x65,0xc3,0x72,0xe5,0x8a,0x15,0x92,0xf5,0xb9,0xe0,0x0d,0xe5, - 0x73,0xab,0xbf,0xe9,0xe6,0x3a,0xea,0x6f,0x35,0xcf,0x97,0xb0,0x96,0x6b,0xde,0x96, - 0xcc,0x9b,0xa2,0x19,0xdf,0x3b,0x75,0x39,0xe1,0xa3,0xda,0xda,0x57,0xd4,0x3f,0xd5, - 0x1a,0x67,0xf5,0xb5,0x5a,0x1b,0xac,0x8e,0x89,0xd6,0xd6,0xe9,0xdb,0xa1,0x5c,0xe4, - 0x0c,0xd4,0xfb,0x96,0x99,0x93,0x90,0x23,0x4e,0x28,0xd3,0x0f,0x60,0x26,0x7f,0x62, - 0x19,0x3e,0xba,0x1c,0x58,0x66,0xce,0x6c,0xce,0x81,0x65,0xae,0x37,0x56,0x3f,0xb9, - 0xcc,0xf5,0x76,0xf7,0x7c,0x26,0x42,0xdf,0x29,0xe5,0x62,0x3c,0x36,0x29,0xa7,0x41, - 0x27,0xf4,0x40,0xf6,0xe4,0x32,0xe3,0x7f,0x5a,0x99,0x7d,0x0e,0x19,0xc4,0x04,0x31, - 0x9d,0x5e,0xe6,0x18,0xb5,0x62,0x78,0x53,0x99,0xe3,0xc1,0x8a,0xb5,0xbd,0xa2,0x4c, - 0x87,0xad,0xfe,0x9a,0x16,0x7d,0xab,0xef,0xd3,0xc0,0x35,0xcb,0xea,0xdd,0xf2,0x7a, - 0x1b,0x57,0x3f,0x33,0xaf,0x6f,0xa6,0x58,0xb4,0xaa,0x30,0x77,0xf6,0xad,0xd9,0x13, - 0xd4,0xae,0x5b,0x57,0x38,0xf6,0x39,0xe6,0x89,0xb5,0xa9,0x70,0x9e,0x7c,0xea,0xf4, - 0xb4,0xcd,0xb1,0xed,0x1c,0xcf,0x96,0x15,0xce,0x2f,0xe0,0xc6,0xd3,0xae,0x82,0xb1, - 0x5c,0xf0,0xb4,0xaf,0xb0,0xfd,0x76,0x8e,0x67,0xab,0xfc,0xfa,0x20,0xc7,0xb3,0x75, - 0x85,0x36,0x6f,0xe5,0x78,0x3a,0xe4,0xd7,0x7d,0x1c,0xcf,0x36,0x15,0xae,0x3b,0x1d, - 0x1c,0xcf,0xb6,0x15,0xae,0xe5,0x56,0xef,0x98,0xd7,0xcf,0x73,0x32,0xdb,0x55,0xc8, - 0xd3,0xd1,0xc9,0x6c,0x9f,0x5f,0xef,0xe9,0x64,0x3a,0xe5,0xf5,0x47,0x9d,0xcc,0x0e, - 0x15,0xf2,0x00,0x47,0x5f,0x23,0x5e,0x3b,0x56,0x18,0x23,0xc4,0x04,0x3e,0xc3,0x27, - 0xd8,0x0c,0x9b,0xd0,0x06,0x64,0xd0,0xd7,0x3f,0xaa,0x68,0xbd,0x56,0xfd,0xc8,0x0a, - 0xd7,0x83,0xbd,0x35,0x37,0x51,0xef,0x29,0xcc,0xea,0xbd,0x2b,0xc5,0x7e,0xe0,0x17, - 0xba,0xf6,0x73,0xf5,0xa4,0x4a,0x31,0x2f,0x50,0x1f,0x5a,0x29,0xd6,0xf2,0x91,0x15, - 0xf2,0x36,0x3a,0xfa,0xe8,0x0a,0xd7,0x66,0xe4,0x35,0xd0,0x2f,0xaa,0x70,0x7e,0xa3, - 0xbf,0x27,0x8b,0x6e,0xbc,0x17,0x57,0x98,0x7b,0x50,0xc7,0x1e,0xe1,0x61,0x6e,0x43, - 0x7b,0x58,0xbd,0xb3,0xf6,0x60,0x56,0x3f,0xa9,0x56,0x1f,0xdf,0x4c,0x1f,0x50,0xab, - 0x8f,0x3b,0xdc,0xea,0x67,0xe5,0xf5,0x49,0xed,0x6f,0xea,0x6e,0xf5,0x41,0x79,0x7d, - 0xf6,0x11,0xed,0x9b,0xf9,0x07,0xe7,0xf5,0x97,0xc7,0x7c,0xd4,0x0d,0xe3,0x1d,0x73, - 0x6b,0x48,0x23,0x65,0xc0,0x07,0x9a,0xf1,0x5d,0x98,0x5f,0x8f,0x68,0x53,0xe9,0xd1, - 0x55,0x31,0xc1,0xfe,0xaf,0xec,0xec,0x98,0x53,0x6b,0xf7,0xad,0x83,0xcd,0x8f,0x7b, - 0x1b,0x19,0xf7,0xe6,0x7c,0xd6,0x58,0xec,0x27,0x50,0x5f,0xd7,0x58,0xc4,0x14,0xf2, - 0xad,0x73,0xe2,0xfa,0xaf,0xbf,0xee,0x66,0xf5,0x36,0x79,0xfd,0xfb,0xef,0xc6,0x76, - 0x37,0xbb,0xda,0x06,0xe4,0x69,0xa3,0x5f,0xc4,0x7a,0xaf,0x80,0x73,0xaa,0xa1,0xb6, - 0x3f,0x4c,0x4a,0xbf,0x08,0xa8,0x53,0x5b,0xcd,0xe6,0xbf,0xb2,0x7e,0xb7,0xcd,0x7b, - 0xe9,0xb8,0x9c,0x08,0x3e,0xf4,0x6d,0x1f,0x31,0x02,0xeb,0xaa,0xfa,0xf1,0xc2,0x40, - 0x1f,0x10,0x30,0x47,0xf9,0xbd,0xc7,0x86,0x1c,0xfb,0x21,0xff,0x43,0x7b,0xc7,0x84, - 0x6c,0xaf,0x5c,0xd7,0x5e,0x43,0x6d,0xbd,0xa0,0x8e,0x63,0x43,0x62,0xe0,0xed,0xaa, - 0x7a,0xaf,0xb0,0xe8,0x43,0x5c,0xf6,0x09,0x2d,0x8f,0x31,0x3f,0x63,0xcf,0x0b,0xac, - 0xbf,0xf6,0x79,0x98,0x07,0x88,0xe5,0xbf,0x32,0x8e,0x19,0x9f,0x27,0x5e,0xce,0x98, - 0x27,0xc6,0xb8,0xf9,0xf2,0x4a,0xc6,0x3c,0xd8,0xcf,0x8d,0xb9,0x65,0x19,0xc7,0x96, - 0x2f,0x96,0xe3,0x96,0x3b,0xfe,0x7e,0x2e,0xf7,0xad,0x70,0xba,0xc7,0x38,0x7c,0x65, - 0xc6,0x1c,0x64,0xc5,0xf0,0x57,0x33,0xae,0x19,0x56,0xcc,0x9f,0xd7,0x9c,0xdd,0x7d, - 0x5d,0xce,0x7d,0x3d,0xe3,0xda,0x6e,0xc5,0xf8,0xdf,0xc8,0xb8,0x1e,0x5a,0x29,0xe7, - 0xfd,0x06,0xfe,0xef,0x33,0x5e,0xc3,0x9f,0xd3,0xab,0x1c,0x03,0xf3,0xaa,0x1c,0x03, - 0x95,0x52,0x41,0x5b,0x90,0x63,0xfb,0xe7,0xb1,0x68,0xd0,0x3c,0x2c,0x89,0xfe,0x75, - 0x8e,0x04,0x9a,0xe7,0x58,0xf7,0xef,0x49,0x39,0x46,0xbb,0xda,0x9a,0x10,0xb5,0xac, - 0x6f,0xed,0xea,0xc8,0x23,0x7b,0xba,0x3a,0xd6,0xc1,0x09,0x41,0x51,0xc7,0xba,0xb6, - 0x4b,0xc8,0xfa,0x57,0x79,0x6b,0x7d,0xd5,0xc7,0xdf,0xe6,0xd7,0x98,0xeb,0x27,0x84, - 0x6c,0x1f,0xbf,0xdd,0xb4,0xe7,0x3f,0x2d,0x64,0xee,0x39,0x2e,0x97,0x82,0x5c,0xff, - 0x90,0xd8,0x69,0x61,0x31,0x6e,0xaf,0x54,0xdf,0x9f,0x1e,0x92,0x8e,0x31,0x70,0x48, - 0x8e,0x61,0x0e,0x0e,0x08,0x99,0xab,0xa0,0xbf,0x9b,0xc6,0xd2,0xc0,0x90,0xf8,0xa2, - 0x9c,0x07,0xf5,0x33,0x42,0x62,0x58,0xdb,0x9f,0x11,0x36,0x48,0x18,0xf2,0x98,0x61, - 0x43,0x42,0xf2,0xf6,0x57,0x9b,0xb5,0xbc,0x26,0x39,0xd0,0x8e,0x17,0x76,0x4e,0x48, - 0x5b,0x6a,0x59,0x47,0xd8,0xb9,0x21,0x71,0xf0,0xf7,0xcd,0x11,0xd8,0x7b,0x7c,0x46, - 0xdc,0x78,0xad,0x9d,0x61,0x6a,0x67,0x89,0x6b,0xe7,0x7c,0xd5,0x87,0xb9,0x76,0x46, - 0x48,0xb6,0xec,0xda,0xb9,0x20,0x24,0x7e,0xbe,0x6b,0xe7,0xc4,0x8c,0xf8,0xf1,0x19, - 0x79,0xad,0x9d,0x0b,0x43,0xfa,0x89,0xdc,0x6c,0xb1,0x18,0x25,0x0c,0x63,0xb9,0x8f, - 0xe2,0x3a,0x3a,0x24,0x2f,0x68,0xe3,0x85,0x8d,0x09,0xa9,0x17,0xb4,0xb1,0xba,0x07, - 0xbc,0x24,0x24,0x8e,0xd8,0x63,0xff,0xd6,0x39,0xe0,0x9e,0xae,0x9f,0x8b,0xfd,0x6e, - 0x01,0xf1,0xb1,0xca,0x15,0xbb,0x07,0xc4,0x4c,0x66,0x0f,0xc9,0x0c,0x75,0x32,0x5d, - 0x02,0xe2,0x26,0xb3,0x67,0x40,0xac,0x8f,0xe6,0xf2,0xcf,0x02,0xea,0x01,0x3e,0x3f, - 0xc7,0x90,0xf3,0xf6,0x0e,0x68,0x0f,0x68,0x37,0xe7,0x72,0x18,0xff,0xfb,0x08,0xc7, - 0xd8,0xdb,0x4f,0x39,0xec,0x9b,0x9c,0x06,0x7c,0xdf,0xbc,0x00,0xc3,0xf8,0xc3,0xf5, - 0xfa,0xfc,0xb7,0xaf,0xc6,0x23,0xf0,0xbf,0xa8,0xad,0x03,0xa5,0x17,0x39,0xe5,0x19, - 0x61,0xdd,0x85,0x21,0xa7,0xa0,0x6f,0x60,0xe3,0x21,0x01,0xf1,0x92,0xfa,0x10,0xd8, - 0xa1,0x01,0xfd,0x02,0xcd,0xf8,0x0e,0x17,0x9f,0xf5,0x21,0xb0,0x23,0x02,0xf2,0x82, - 0x66,0xb2,0x47,0x4b,0x16,0x98,0xf1,0xf5,0x0a,0x88,0x43,0x1f,0x62,0x85,0x1c,0xdd, - 0x57,0xf9,0xd9,0xf4,0x9f,0x18,0xd0,0x66,0x3f,0x46,0x4e,0x56,0xcc,0x7d,0xbf,0x9f, - 0x12,0x10,0x47,0xbf,0x5b,0x9c,0x4f,0x0d,0x88,0x9b,0x0d,0xa7,0x05,0xd4,0x77,0xaa, - 0xd3,0xff,0x4b,0xe9,0x2f,0x39,0xfb,0x4f,0x0f,0xc8,0xfb,0x4b,0xf5,0x2b,0xd6,0x88, - 0x81,0xea,0xd7,0x31,0xea,0x57,0xf0,0x9d,0x21,0xdc,0xe4,0xce,0x0c,0x28,0x0b,0x7c, - 0x30,0xd6,0xd0,0xfc,0xf7,0x2c,0xf9,0x34,0x30,0xe7,0x41,0xde,0x1a,0x24,0xec,0x4c, - 0x37,0x66,0x06,0x4b,0xf7,0x48,0x37,0x66,0x86,0x04,0xc4,0xef,0xcd,0x79,0xd0,0xf7, - 0x43,0x03,0x62,0xc8,0xad,0xe8,0xff,0x73,0x5c,0xff,0x83,0x76,0x76,0x5e,0x86,0xab, - 0xff,0xcf,0x0e,0x8a,0x39,0x36,0x3e,0x64,0x9b,0x95,0xda,0x7c,0xe0,0x3a,0x71,0x75, - 0x48,0xdc,0x97,0x45,0xb2,0xef,0x9a,0x90,0xf4,0x8b,0x94,0x37,0x80,0x4d,0x0d,0x89, - 0x2f,0xcb,0x0a,0xbd,0xd3,0x42,0xe2,0xf8,0xfb,0xab,0xb0,0xeb,0x43,0xe2,0xd8,0xeb, - 0x18,0xdf,0x74,0xf1,0x95,0x1d,0x5f,0x53,0x48,0x7c,0x72,0xed,0xbe,0x8b,0xd8,0xef, - 0x42,0xca,0x37,0xb9,0xfc,0x30,0x43,0xb2,0x0d,0x4e,0xf6,0xc6,0x90,0x38,0xe2,0x60, - 0xb2,0x37,0x85,0x94,0xbf,0xd1,0xc9,0xce,0x94,0x6c,0xc5,0xc9,0xde,0x12,0x12,0x5f, - 0xea,0xda,0xbd,0x35,0xa4,0xfc,0x2d,0x4e,0x76,0xa2,0x62,0xd6,0xe0,0x62,0x36,0x3b, - 0x24,0xee,0x8b,0xc5,0xec,0xce,0x90,0x74,0x1f,0xb3,0xbb,0x42,0xe2,0x3e,0x66,0xf7, - 0x84,0xc4,0x7d,0xcc,0xe6,0x86,0xc4,0x7d,0xcc,0xee,0x13,0x9f,0x8f,0xd9,0xfd,0x21, - 0x71,0x1f,0xb3,0x79,0x21,0xe5,0xef,0x77,0xb6,0xcf,0x97,0xac,0x8f,0xd9,0x03,0x21, - 0x71,0x1f,0xb3,0x07,0x43,0xca,0x3f,0xe0,0x64,0xff,0x28,0x59,0x1f,0xb3,0x05,0x21, - 0x71,0x1f,0xb3,0x87,0x43,0xca,0x83,0x66,0x39,0xf6,0xd7,0x21,0x63,0x09,0x1a,0x72, - 0xcf,0x39,0x1a,0x8b,0xc3,0xdd,0x58,0x7c,0x5c,0x71,0x2d,0xbb,0xb8,0x2e,0x0e,0x89, - 0xfb,0x62,0x71,0x7d,0x3a,0x24,0xdd,0xc7,0xf5,0x6f,0x21,0x71,0x1f,0xd7,0xe7,0x43, - 0xe2,0x3e,0xae,0x2f,0x84,0xc4,0x7d,0x5c,0xff,0x21,0x3e,0x1f,0xd7,0x17,0x43,0xe2, - 0x3e,0xae,0x2f,0x85,0x94,0x7f,0xd1,0xc5,0xe6,0x9f,0x92,0xf5,0x71,0x5d,0x1a,0x12, - 0xf7,0x71,0xfd,0x57,0x48,0xf9,0xa5,0x4e,0xf6,0x15,0xc9,0xfa,0xb8,0x2e,0x0b,0x89, - 0xfb,0xb8,0x2e,0x0f,0x29,0xbf,0xcc,0xc9,0x3e,0xa1,0x98,0x95,0x5c,0xcc,0x5e,0x0f, - 0x89,0xfb,0x62,0x31,0x7b,0x23,0x24,0xdd,0xc7,0xec,0xed,0x90,0xb8,0x8f,0xd9,0xaa, - 0x90,0xb8,0x8f,0xd9,0xbb,0x21,0x71,0x1f,0xb3,0xf7,0xc5,0xe7,0x63,0xf6,0x41,0x48, - 0xdc,0xc7,0xec,0xc3,0x90,0xf2,0x1f,0x38,0xdb,0x3f,0x96,0xac,0x8f,0xd9,0x27,0x21, - 0x71,0x1f,0xb3,0xd5,0x21,0xe5,0x3f,0x71,0xb2,0x9f,0x49,0xd6,0xc7,0xec,0xf3,0x90, - 0xb8,0x8f,0xd9,0x9a,0x90,0xf2,0x9f,0xbb,0xb1,0xf8,0x64,0xc8,0x58,0xae,0xa9,0x1b, - 0x8b,0xf8,0x5d,0xab,0x7d,0xd8,0x9b,0x19,0xc7,0x2c,0x72,0x25,0xf8,0x87,0xbb,0x5c, - 0x3b,0x5a,0xb9,0xb6,0xbf,0xf6,0x79,0x63,0x5c,0xae,0x05,0xed,0x22,0xac,0x33,0xd2, - 0x79,0x91,0x1b,0xdf,0x97,0x04,0xd4,0xeb,0xf7,0x28,0x97,0x06,0xc4,0xb1,0xf7,0x31, - 0xfd,0x63,0x03,0xe2,0xf0,0x03,0xf6,0x99,0xae,0x31,0xb2,0x0f,0x3c,0x97,0x05,0xb4, - 0x03,0x36,0x8f,0x55,0x9b,0xdd,0x73,0x5b,0x26,0x68,0xbd,0xb5,0x36,0xf7,0x89,0x36, - 0x6e,0x73,0xdf,0x88,0x38,0xec,0xc7,0x1a,0x83,0xe7,0x92,0xfb,0x47,0xdc,0xcb,0x82, - 0x66,0xeb,0xd7,0x7f,0x45,0xc4,0x9f,0xd1,0xfa,0x75,0x40,0x44,0x0c,0x6b,0xdc,0x5f, - 0x84,0xfd,0x3c,0x22,0x3e,0x4d,0xeb,0x2a,0xf4,0x1f,0x18,0x11,0xbf,0x4f,0xfe,0x74, - 0x8b,0x5a,0xc6,0xeb,0xb0,0xa8,0x88,0x17,0x68,0xdd,0xf3,0x02,0x0c,0x3e,0x76,0x8f, - 0x0a,0x3b,0x0f,0x91,0x9d,0x3e,0x36,0x87,0x46,0xc4,0x2d,0x36,0x26,0x87,0x5f,0x8b, - 0xcd,0xe1,0x11,0xdb,0x44,0xbc,0x0e,0x95,0x7e,0xb4,0xdb,0x98,0x14,0xed,0x82,0xe7, - 0x88,0xbc,0x9c,0x28,0x79,0x5c,0x1f,0x97,0xef,0xe0,0xb1,0x27,0xef,0xa9,0x98,0x59, - 0xdc,0xca,0x6e,0x1f,0x0e,0xbb,0x8e,0x8e,0xb8,0x27,0x86,0x9f,0x7d,0x74,0xbf,0x72, - 0x4c,0x44,0xdc,0xca,0x84,0x9c,0x17,0xf8,0xb1,0x11,0x9f,0xb5,0x81,0xbe,0x48,0x58, - 0xaf,0x88,0x6d,0x80,0x36,0x56,0xcf,0xf3,0x7a,0x47,0xc4,0xe1,0x3b,0xea,0x7d,0x22, - 0x62,0xb8,0x9f,0xba,0x52,0xd8,0x09,0x11,0x71,0xdc,0x7b,0xc1,0x77,0xf8,0x03,0xdb, - 0xe1,0xc3,0xf3,0xb9,0x1d,0xb5,0xbd,0x8f,0x62,0xb6,0x56,0xfb,0x05,0xdb,0xeb,0x9c, - 0x12,0x91,0x66,0xf5,0xfe,0xe2,0x7b,0x2e,0x97,0xaa,0xed,0x73,0x22,0x62,0x03,0xb4, - 0x9f,0x35,0x7d,0x03,0xc5,0x87,0x00,0x78,0x7d,0x67,0x44,0xa4,0x99,0xfc,0x60,0xc9, - 0x0f,0xab,0x93,0x3f,0x5b,0xf2,0x4d,0x75,0xf6,0x9c,0x13,0x91,0x66,0xf2,0xc3,0x24, - 0x3f,0x50,0xf2,0xb6,0x67,0x1a,0x11,0xd1,0x76,0xd8,0x67,0xd8,0xff,0x44,0x6c,0x7f, - 0xb0,0xc3,0x46,0x45,0xd4,0x39,0x2c,0x2a,0xc6,0xe1,0x45,0x11,0xe5,0xef,0xd7,0xd8, - 0x19,0x13,0x11,0xdb,0x41,0x7b,0xa4,0x8a,0x1b,0x0f,0xa0,0x5d,0x9c,0x97,0x65,0x1a, - 0x0f,0x17,0xbb,0x98,0x8e,0x95,0x0f,0x03,0x4a,0x2d,0xf7,0x8f,0x97,0x45,0xa4,0x19, - 0xdf,0x78,0x17,0x7b,0xcf,0x77,0x45,0x44,0xda,0x5f,0x65,0xeb,0x84,0x88,0xd8,0x18, - 0xe5,0x29,0x60,0x13,0x23,0xea,0x9b,0xe0,0xf4,0x5d,0x25,0x7d,0x43,0x74,0xbf,0x60, - 0xfa,0x26,0x45,0xa4,0x19,0xdf,0xd5,0xe2,0x1b,0x56,0xc7,0x77,0x4d,0x44,0x9a,0xf1, - 0x4d,0x15,0xdf,0xd4,0x3a,0xbe,0xeb,0x22,0xd2,0x8c,0xef,0xb7,0xe2,0x1b,0x58,0xc7, - 0x37,0x3d,0x22,0xcd,0xf8,0x6e,0x10,0xdf,0xd0,0x3a,0xbe,0x19,0x11,0x69,0xc6,0x77, - 0xb3,0xf8,0xec,0x19,0x82,0xe5,0xeb,0x99,0x11,0x69,0xd3,0x5c,0xbe,0x9e,0x15,0x11, - 0x47,0x1e,0x42,0x3e,0xc3,0xfd,0x38,0x9e,0xe9,0x5a,0x9e,0xba,0x23,0xe2,0x3d,0xfa, - 0x2c,0x97,0xa7,0x66,0x47,0xc4,0x2d,0xe7,0xcd,0xd1,0xfc,0xf5,0x7b,0xf6,0xbb,0x22, - 0x3e,0x8f,0xc0,0xbd,0x87,0xdd,0x13,0xdc,0x1d,0x91,0xf7,0x2e,0x97,0x73,0xee,0x89, - 0x88,0x2f,0x71,0xfe,0xcc,0x8d,0x88,0x9b,0xdc,0x3c,0xc9,0x41,0x97,0xc9,0xfd,0x21, - 0x22,0xde,0xdf,0xc9,0xcd,0x8f,0x88,0x5b,0x1f,0x3f,0x14,0x51,0xd7,0x7c,0xe5,0xa3, - 0x47,0x5d,0x1e,0x44,0x3e,0x5f,0x90,0xd7,0x1f,0xd5,0xf8,0xc3,0xb5,0xe5,0xbc,0x47, - 0x22,0xca,0x8e,0x51,0xce,0x33,0x9e,0x47,0x5d,0xce,0xfb,0x3c,0xe3,0x9a,0x80,0x71, - 0x0b,0x7e,0x2f,0xff,0x67,0xc9,0xcf,0x52,0xfe,0x7d,0xc5,0xb5,0x0b,0xda,0x63,0xf0, - 0x4d,0x3a,0x1f,0x53,0x4e,0x43,0xbe,0x79,0x22,0xe2,0xb8,0xc4,0x78,0xc3,0x58,0xb2, - 0x3c,0xf4,0x54,0x44,0x9a,0xe5,0xa1,0x57,0x24,0xbb,0x48,0x79,0x0f,0xbe,0xfe,0x55, - 0xf6,0x3e,0xe4,0xf4,0x3d,0x1b,0x71,0xac,0x61,0x1c,0xcd,0x70,0xfa,0x9e,0x8b,0x48, - 0x5b,0x99,0x15,0xf7,0x62,0x7f,0x8f,0xa8,0x63,0xb6,0x93,0xff,0x47,0x44,0xdc,0xca, - 0x78,0xc9,0xbf,0x18,0x51,0x07,0xe8,0xd5,0x3c,0x87,0x03,0x5b,0x12,0x31,0x67,0xef, - 0x21,0x3a,0x9e,0xed,0xe3,0x39,0xbe,0xb7,0xf7,0x15,0xc5,0x0f,0xfc,0x59,0x95,0x7e, - 0xc1,0xff,0x25,0x8a,0x07,0x78,0x2b,0xca,0xb1,0xcb,0x5c,0x5e,0x59,0x11,0x31,0x07, - 0x59,0x5e,0x59,0x19,0x11,0xb3,0xbc,0xd2,0xe0,0xf2,0x0a,0x68,0xaf,0x62,0x9d,0x89, - 0xa9,0xe7,0x55,0x37,0x2f,0xde,0x70,0xf9,0xc2,0xcf,0x9f,0x37,0x23,0xd2,0x8c,0xef, - 0x1d,0x97,0x7f,0xfa,0x39,0xbe,0x55,0x11,0x69,0x96,0x57,0xde,0x8d,0x88,0x61,0x3e, - 0xd9,0x58,0xfd,0x40,0xb2,0x6f,0xba,0xf5,0xff,0xc3,0x88,0xb8,0x1f,0xab,0x1f,0x45, - 0xc4,0x6d,0xac,0x7e,0x1c,0x51,0xdf,0x47,0xce,0x8e,0x4f,0xa5,0xeb,0xa3,0x3a,0x3b, - 0x3e,0x8b,0x48,0xb3,0x36,0xbf,0x10,0xdf,0x64,0xd7,0xe6,0xbf,0x23,0xe2,0xd8,0xd7, - 0x99,0xdc,0x7f,0x22,0xe2,0xd6,0xe6,0x97,0x11,0x75,0xfd,0xc7,0xb5,0xf9,0x95,0x5b, - 0x3f,0x7c,0x8c,0xbe,0x8e,0x48,0x33,0xbe,0x6f,0xc5,0x77,0x7d,0x1d,0xdf,0x77,0x11, - 0x69,0xc6,0xf7,0x83,0xf8,0xfa,0xd5,0xf1,0xe1,0xe1,0xdd,0x0f,0x2e,0x0f,0x54,0x62, - 0xf2,0xbd,0xe3,0xd6,0xfd,0x24,0x66,0x5e,0xd8,0x37,0x2a,0x9e,0x35,0xa4,0x31,0x79, - 0x41,0xb3,0xb1,0x5b,0x8d,0xd9,0x87,0x78,0x3f,0x64,0xd8,0xe6,0x31,0x63,0x8a,0x77, - 0x44,0x96,0x93,0xb6,0x88,0xc9,0x0b,0x9a,0x61,0xad,0x63,0xe2,0x5f,0x46,0x85,0x6c, - 0xdb,0x98,0xfe,0x7a,0x7d,0xed,0x62,0xfa,0xe6,0xf5,0xb5,0x8f,0xc9,0xdb,0xce,0xe9, - 0xdb,0x3a,0x26,0x0e,0xff,0xe6,0x6b,0xbc,0x76,0x88,0xd9,0x0e,0x68,0x73,0x15,0x97, - 0x6d,0x62,0xe2,0xfd,0xf5,0xde,0xd1,0xfc,0xeb,0x18,0xd3,0x47,0xd0,0x91,0x8f,0xb7, - 0xae,0xcb,0xc7,0xdb,0xc7,0x7c,0x46,0x0a,0x3e,0xcb,0xc7,0x9d,0x62,0xe2,0x96,0x8f, - 0x77,0x8c,0x37,0xce,0xc7,0x3b,0xc7,0x1b,0xe7,0xe3,0x1f,0xc5,0xe4,0x05,0xcd,0xfa, - 0xe1,0xc7,0x31,0x71,0x9f,0x8f,0x7f,0x12,0x13,0x37,0xb9,0xce,0x92,0xf3,0xf9,0x78, - 0xb7,0x98,0xb8,0x1f,0xe3,0xbb,0xc7,0xc4,0x31,0x47,0xf7,0x89,0x5b,0xe6,0xde,0x2e, - 0xe8,0x6f,0xcd,0xd1,0x2e,0x2e,0x7e,0x7b,0xc5,0x6c,0x0f,0xb2,0x96,0x4f,0xf7,0x8e, - 0x89,0x5b,0x3e,0x36,0x39,0xfc,0x5a,0x3e,0xfe,0xb7,0xf2,0x31,0xe6,0x3b,0xf8,0xa1, - 0xd3,0xf6,0xc3,0xfb,0x49,0xa7,0xe5,0xe3,0x83,0x9d,0x2d,0xa0,0xed,0x9f,0x97,0xae, - 0xd2,0x89,0x6b,0xcb,0x7f,0x07,0x6a,0x1c,0xa0,0xdf,0xd1,0x9f,0x68,0xfb,0x60,0xf1, - 0x75,0x75,0x7c,0x3d,0x34,0xfe,0x30,0xde,0xbe,0x8c,0x5a,0xf2,0x1d,0x1c,0x17,0x39, - 0xef,0x9d,0x8c,0x3a,0xd1,0x46,0x0f,0xb5,0x69,0x39,0xf9,0xf0,0x98,0x74,0x9f,0x93, - 0x8f,0x94,0xcf,0x88,0x85,0xe5,0xf9,0x9e,0x31,0xf3,0xcd,0x91,0x6e,0xfc,0x1f,0x13, - 0x13,0xef,0xe4,0x6c,0xea,0x15,0x13,0xb7,0x62,0xb9,0xbb,0x77,0xcc,0xb6,0x40,0xb7, - 0xdc,0x7d,0x5c,0x5c,0xe4,0x6e,0xd0,0x7d,0xee,0x6e,0xb0,0x3d,0x6f,0x5c,0xe4,0xe3, - 0x7e,0x31,0xf7,0x7f,0x96,0x8f,0x4f,0x8e,0x89,0x59,0x3e,0x2e,0xbb,0x7c,0x0c,0xda, - 0x29,0x79,0x59,0xad,0x78,0xe0,0xda,0x72,0x43,0x7f,0xcd,0x79,0xbc,0xb7,0x9d,0xe2, - 0xc6,0xcd,0x2f,0x63,0xd2,0x9a,0xf7,0xc4,0xe2,0xfb,0xb4,0xd4,0x92,0xef,0x8c,0x98, - 0x34,0x1b,0x97,0x83,0xc4,0x87,0x77,0xa8,0xc6,0x33,0x38,0x26,0x6e,0xf7,0x54,0x43, - 0x62,0x62,0x27,0x97,0x8b,0x3c,0x38,0x34,0xa6,0xae,0x21,0xae,0xcd,0x73,0xe3,0x22, - 0xbf,0xf9,0xdc,0x7b,0x5e,0x4c,0x9a,0xf1,0x9d,0x1f,0x17,0xf9,0xd2,0xef,0x41,0x87, - 0xc7,0xa4,0xd9,0x5a,0x31,0x22,0x26,0xd6,0xcf,0xed,0x41,0x2f,0x88,0xa9,0x6f,0x84, - 0xf3,0xe1,0x42,0xa7,0xcf,0x74,0xfd,0x2a,0x26,0x6e,0x3e,0x8c,0x8a,0x89,0x9d,0xe4, - 0x7c,0x18,0x1d,0x53,0xdf,0xa8,0xb8,0x90,0xbb,0x24,0x66,0xee,0x34,0x5b,0x2f,0x8b, - 0x8b,0x7d,0xa1,0xbf,0x37,0xb8,0x3c,0x26,0xcd,0x6c,0x1d,0x17,0x13,0x9b,0xe6,0x6c, - 0x1d,0x1f,0x53,0xdf,0x38,0x97,0x67,0x26,0xb8,0x3c,0x63,0x6d,0x4c,0x8c,0x89,0x9f, - 0x59,0xd7,0xa7,0x57,0xc6,0xa4,0x19,0xdf,0x24,0xf1,0xa1,0xef,0xaf,0x77,0x7c,0x93, - 0x63,0xd2,0x8c,0xef,0x1a,0xf1,0xd9,0xd9,0x1c,0xe3,0x9b,0x12,0x93,0x66,0x7c,0xd7, - 0x89,0x0f,0x03,0xd9,0xb7,0x3b,0x2d,0x26,0xcd,0xf8,0xa6,0x8b,0x6f,0x56,0xdd,0x58, - 0x6a,0x8a,0x49,0xb3,0x18,0xdc,0x10,0x73,0x1c,0xfa,0x7b,0xef,0x1b,0x85,0x0d,0x75, - 0x71,0xb9,0x29,0x26,0xef,0x8d,0x4e,0x76,0x66,0xcc,0x78,0x79,0xd9,0x5b,0x85,0x79, - 0xd9,0xdb,0x62,0xf2,0xde,0xea,0x64,0x6f,0x8f,0x19,0x2b,0x2f,0x3b,0x5b,0x98,0x97, - 0xbd,0x33,0x26,0xef,0x6c,0x27,0xfb,0xfb,0x98,0x63,0x79,0x9a,0x93,0xbd,0x5b,0xd8, - 0x14,0x27,0x7b,0x4f,0x4c,0xde,0xbb,0x9d,0xec,0xbd,0x31,0x63,0xef,0x65,0xef,0x17, - 0xe6,0x65,0xe7,0xc5,0xe4,0xbd,0xdf,0xc9,0xce,0x8f,0xd9,0x1f,0x5e,0xf6,0x41,0x61, - 0x5e,0xf6,0xa1,0x98,0xbc,0x0f,0x3a,0xd9,0x05,0x31,0xc7,0xae,0xf7,0xf7,0x11,0x61, - 0xde,0xdf,0x47,0x63,0xf2,0x3e,0xe2,0x64,0xff,0x1c,0xb3,0x7f,0xbd,0xec,0xe3,0xc2, - 0xbc,0xec,0xc2,0x98,0xbc,0x8f,0x3b,0xd9,0x27,0x62,0xf6,0xb9,0x97,0x7d,0x52,0x98, - 0x97,0x7d,0x2a,0x26,0xef,0x93,0x2e,0xb7,0x2e,0x8e,0xd9,0xef,0x88,0xe3,0xa3,0x0e, - 0xff,0x5b,0xcc,0x3e,0x45,0x8c,0x16,0x2a,0x67,0x03,0x7f,0x3e,0x26,0x6d,0xb1,0xe3, - 0x7d,0x31,0x66,0x1f,0x22,0x26,0x4f,0x39,0xde,0x25,0x31,0x69,0xe0,0xb5,0x35,0xff, - 0x9f,0x31,0x9f,0x15,0x2d,0x75,0xef,0x3a,0x96,0xc6,0xc4,0x4d,0xdf,0xcb,0x31,0x31, - 0x2b,0xb6,0xae,0xbc,0x12,0xb3,0xfd,0x97,0x9d,0xbe,0x65,0xd2,0xd7,0xdf,0xe9,0x5b, - 0x1e,0x13,0x37,0x7d,0x2b,0x63,0x62,0x56,0x4c,0xdf,0xab,0x31,0x6d,0x5c,0xe9,0xd6, - 0x94,0x37,0x63,0xb6,0xf3,0xaa,0xc3,0xde,0x8e,0x89,0xe3,0x7d,0xf6,0x5f,0x84,0xad, - 0x8a,0x89,0x03,0x33,0xbe,0x77,0xe5,0xeb,0x2a,0xb7,0x1e,0xbd,0xef,0xd6,0xa3,0x77, - 0xeb,0xd6,0xa3,0xb2,0xd6,0xa3,0xd5,0xce,0xd6,0x35,0x31,0x9f,0x59,0x9c,0xa1,0x67, - 0x12,0x36,0xa7,0xff,0x1d,0x17,0xcf,0x8c,0xc0,0xb7,0x2e,0xe6,0x73,0x8d,0xc1,0x7a, - 0x6e,0x61,0xf8,0x57,0x31,0x79,0xad,0x98,0xaf,0x5f,0xc7,0xa4,0xad,0x73,0x7e,0xad, - 0x8f,0xd9,0xde,0xd7,0x1a,0x4b,0xc0,0xbe,0x8b,0x89,0x2f,0x77,0xbe,0xfe,0x20,0x0c, - 0xbe,0x2e,0x16,0x06,0xa3,0xc0,0xfb,0x43,0xdc,0xd2,0x17,0xfc,0xda,0x1e,0x61,0xb3, - 0x2a,0xfd,0xc7,0x3a,0x89,0x77,0xef,0xab,0xdd,0xfe,0xa1,0x5c,0x25,0x06,0x1a,0x74, - 0xad,0xd6,0x7e,0x12,0x6b,0xf0,0xbd,0x55,0xae,0xc3,0x8b,0xf5,0xac,0xd2,0xf0,0xfb, - 0x1c,0xbe,0xbc,0xd4,0x72,0x4d,0x6f,0x70,0xed,0x56,0xab,0xdc,0x07,0x60,0xbf,0x02, - 0x1b,0xbc,0x4d,0x1b,0x32,0xb6,0x0b,0x5a,0xd9,0xd1,0xa0,0x7f,0x4d,0xc6,0xbd,0x17, - 0x68,0xf7,0xd6,0xd1,0x3e,0xcc,0xd8,0x2e,0x68,0xf7,0x89,0xe6,0xef,0xf1,0x2a,0xae, - 0x8d,0xb4,0xca,0x7b,0x42,0xdc,0x23,0xc2,0x16,0x6f,0xdb,0x57,0x6a,0x1f,0x34,0xd8, - 0xd2,0xe0,0xda,0xf8,0x34,0xe3,0xbd,0x38,0x68,0x6b,0xea,0x68,0xef,0xaa,0x7d,0xd0, - 0x3e,0x14,0xcd,0x3f,0xc7,0x6b,0x74,0x6d,0x84,0x8a,0x2d,0x9e,0x4b,0xc2,0x16,0x6f, - 0xdb,0xba,0x8c,0xcf,0x02,0x41,0x83,0x2d,0x15,0xd7,0xc6,0x6a,0xed,0x3b,0x41,0xfb, - 0xb4,0x8e,0xb6,0x2a,0x63,0xcc,0x41,0x7b,0x57,0x34,0xec,0x8f,0x0e,0x70,0xfb,0x23, - 0xf0,0x84,0x79,0xfd,0x00,0xd9,0x84,0x6b,0xdb,0xb7,0xa6,0x09,0xc7,0x2f,0xe6,0xfd, - 0x5c,0x3d,0xb7,0xcb,0x12,0xe2,0xd3,0x74,0x66,0xae,0xf9,0x1e,0x28,0xe1,0xde,0x02, - 0x74,0xdb,0x2b,0x6e,0x96,0x70,0x9d,0x07,0xcd,0xd6,0xbf,0xcd,0x13,0xee,0x01,0x36, - 0x13,0xbf,0xad,0xe5,0xad,0x92,0x8d,0xef,0x19,0xda,0x24,0x1b,0xdf,0x33,0xb4,0x4d, - 0xc8,0x0b,0x9a,0xed,0xfd,0xb7,0x4c,0x88,0xfb,0x7b,0x86,0x76,0x09,0x71,0x93,0xeb, - 0x20,0x39,0x7f,0xcf,0xb0,0x4d,0x42,0xdc,0xdf,0x33,0x6c,0x9b,0x10,0x37,0x1f,0xb6, - 0x93,0xaf,0xed,0x14,0xbb,0x5d,0x5c,0xec,0x10,0xfb,0x4e,0x79,0x7d,0x17,0xc5,0x0e, - 0xd7,0x16,0x8f,0x9d,0x12,0xca,0x42,0x9f,0xf9,0xf3,0xe3,0x84,0x7a,0x80,0xd9,0xbd, - 0xc5,0x4f,0x12,0xe2,0x76,0x6f,0x61,0xba,0x76,0x71,0xfd,0x58,0xa9,0xb2,0x9f,0xd1, - 0x37,0xe0,0xef,0x24,0x5a,0xed,0x1e,0x3a,0x63,0x3b,0xa0,0xed,0x24,0x1a,0xee,0xdb, - 0x70,0x6e,0x05,0xe7,0xe5,0x0e,0xc9,0x3d,0x45,0xce,0xed,0x9c,0xf0,0x2c,0xcb,0xe6, - 0x6a,0xdf,0xf2,0xee,0x6e,0x09,0x69,0x66,0xf7,0x1e,0x09,0x31,0xe8,0xb5,0xfc,0xf4, - 0xb3,0x84,0xb8,0x15,0xcb,0x45,0x7b,0x25,0x1c,0x9b,0xa0,0x5b,0xee,0xdc,0x3b,0x29, - 0x72,0x27,0xe8,0x3e,0x77,0xda,0x18,0x3b,0xc0,0x8d,0xed,0xa0,0xca,0xb1,0x8f,0xb9, - 0xb0,0xb7,0x62,0x69,0x7e,0x37,0xc8,0x6f,0xd0,0x10,0x03,0xd0,0xee,0xb6,0x77,0x0c, - 0x09,0xdf,0x87,0x80,0x07,0xba,0x7b,0x48,0x37,0x7e,0x6d,0xac,0xde,0x5f,0x25,0xdf, - 0x2c,0x9d,0xe3,0x84,0x3f,0x38,0x3b,0xf4,0x07,0xe1,0x56,0xe6,0xca,0xcf,0xf9,0xa2, - 0xc1,0x66,0xd8,0xd5,0x7c,0xf6,0x21,0x21,0xad,0x54,0x2a,0xb0,0xc3,0x84,0x95,0x1d, - 0x76,0x84,0x30,0xbc,0xdf,0xba,0x47,0x67,0x34,0x7e,0x1b,0xf0,0xdd,0x04,0xc6,0x4e, - 0x93,0x7b,0x6f,0x04,0x7c,0x7a,0x5e,0x9a,0xf4,0xae,0x07,0xd7,0xf3,0xe4,0xdb,0x8c, - 0x80,0xb6,0xcf,0xd2,0x98,0x30,0x9e,0x26,0xf7,0x3e,0xe8,0x46,0xe9,0x85,0xbf,0x33, - 0xa4,0x0b,0x6d,0xcc,0x74,0x6d,0x80,0xe7,0xe6,0xbc,0xcc,0x94,0xfc,0xcd,0x41,0x71, - 0x0f,0x75,0x5b,0x40,0xbf,0xac,0x7e,0x47,0x40,0x9f,0xac,0x3e,0x27,0xa0,0x3f,0xf6, - 0xbe,0xe3,0xf7,0x01,0x65,0xc0,0x37,0x47,0x6d,0x5d,0x91,0xb4,0x7c,0x0f,0x76,0x16, - 0xfa,0x44,0xfd,0x80,0xeb,0xd3,0xcb,0x1c,0xa3,0x83,0x92,0xe2,0xbc,0xe4,0x34,0x7d, - 0x23,0x00,0x1a,0xf4,0x0e,0x71,0x34,0xb4,0x31,0x59,0x39,0x05,0xb4,0xb3,0x13,0xd2, - 0x71,0x36,0xcc,0xec,0x3a,0x37,0xa1,0x3e,0xb3,0xeb,0xbc,0x84,0x98,0x95,0xf1,0x92, - 0xfd,0xef,0x84,0xf2,0xe7,0xb9,0xb1,0x7d,0xbe,0xe6,0xd9,0x20,0xe7,0xe7,0xf0,0x84, - 0xb8,0xe9,0x1b,0x91,0x10,0xb3,0x72,0x95,0xf4,0x5d,0x90,0x50,0xe7,0x88,0xa4,0x78, - 0x87,0x33,0x32,0x21,0x6e,0xf5,0x0b,0x13,0xfa,0x60,0x7b,0xa9,0x51,0x09,0xb1,0x91, - 0xca,0xfb,0x57,0x28,0x36,0xa3,0x9d,0xcc,0x18,0xc9,0x58,0x3c,0x2e,0xd9,0x44,0x3c, - 0xcc,0xa7,0xb1,0x09,0xe9,0x38,0x5b,0x67,0xef,0x96,0x2e,0x4f,0x88,0xbf,0x9e,0x15, - 0x3a,0xc7,0x25,0xc4,0xcd,0x8e,0xf1,0x09,0xdb,0x19,0x57,0x67,0xc7,0x15,0x6e,0x1e, - 0x76,0xac,0xd2,0x5e,0xf4,0xdb,0x78,0xf5,0xa3,0x8d,0xeb,0x89,0x09,0xe9,0xfe,0xec, - 0xcf,0x55,0x09,0xf1,0x89,0xae,0x9f,0x27,0x39,0xdb,0x41,0x87,0xed,0x23,0x74,0xb6, - 0x73,0x72,0x42,0xba,0xe9,0x9c,0x22,0x9d,0x65,0xa7,0xf3,0x5a,0xe9,0x9b,0xe2,0x74, - 0x4e,0x75,0x3a,0xaf,0xad,0xd3,0x79,0x5d,0x42,0xba,0xe9,0x9c,0x2e,0x9d,0x0d,0x4e, - 0x67,0x93,0x74,0x4e,0x77,0x3a,0x7f,0xe7,0x74,0x36,0xd5,0xe9,0xbc,0x21,0x21,0xdd, - 0xe4,0x67,0xca,0x1e,0x6f,0xd3,0x2d,0x4e,0x7e,0x66,0x9d,0xfc,0xad,0x09,0xe9,0x26, - 0x3f,0x5b,0xb2,0xbe,0xfd,0x3b,0x9d,0xfc,0xec,0x3a,0xf9,0x39,0x09,0xe9,0x26,0x3f, - 0x57,0xb2,0x5e,0xfe,0x5e,0x27,0x3f,0xb7,0x4e,0xfe,0xbe,0x84,0xf4,0x21,0x1a,0x4f, - 0xf3,0x36,0x31,0x9e,0xce,0x12,0x6d,0xfe,0x26,0x68,0xf6,0x1e,0xf3,0x81,0x84,0xb2, - 0xe0,0xb9,0x40,0xdf,0x2f,0x3d,0x98,0x10,0xc7,0x18,0x7a,0x48,0x63,0xe8,0x21,0x8d, - 0x21,0xd0,0x3b,0x55,0xc9,0x83,0x71,0x35,0x27,0xbf,0x5e,0x29,0x1a,0xec,0xda,0xbe, - 0xca,0x73,0xcc,0xa0,0xbd,0x94,0x14,0xb4,0xda,0x1a,0xab,0x5c,0x07,0xda,0x6b,0xa2, - 0x3d,0xa8,0x5c,0xf8,0x70,0x42,0x3a,0xee,0x89,0xd6,0xe5,0x76,0xbc,0x2e,0xba,0xe5, - 0x1d,0xd0,0x1f,0xc1,0xf8,0x97,0x3d,0x8f,0x68,0x2e,0xc3,0x9e,0xc7,0x12,0x8e,0x3b, - 0x8c,0x13,0xf4,0x6b,0x53,0xae,0x13,0xb6,0x2c,0x4c,0x48,0x83,0xbd,0xc6,0xfb,0xa4, - 0xf8,0xd0,0x7f,0x73,0x1c,0xef,0xa2,0x84,0x34,0xcf,0xfb,0xb4,0xf4,0x81,0xef,0x3e, - 0xc7,0xfb,0x6c,0x42,0x9a,0xe7,0x7d,0x21,0x61,0x7b,0xd0,0xf3,0xac,0xe3,0x7d,0x31, - 0x21,0xed,0x85,0xda,0xda,0x19,0xd6,0xb0,0x97,0xb4,0x76,0x76,0x12,0xfd,0x31,0xc5, - 0xe0,0x9f,0x8a,0x19,0xe2,0x87,0xbc,0xbb,0xc2,0xf9,0x0f,0xda,0xd2,0xbc,0xac,0x90, - 0xff,0x4b,0x6b,0xe3,0x81,0x6d,0xbc,0x9c,0xf0,0xac,0x38,0x64,0xa7,0xe6,0x18,0xec, - 0x59,0xae,0x36,0x5f,0x56,0x3f,0x9a,0xdc,0x0a,0xd7,0x8f,0xe8,0xbb,0x17,0x14,0xd7, - 0xe5,0xd2,0x0f,0xde,0x95,0xe2,0x5d,0xe9,0xf6,0x34,0xaf,0xa9,0x7f,0xa6,0x95,0x5a, - 0x8e,0x0b,0xf4,0xc7,0x9f,0x64,0xff,0x9b,0x09,0xfb,0x7f,0x80,0xec,0xff,0xc2,0xd9, - 0x0f,0xda,0x5b,0x79,0x79,0x5b,0x72,0x6f,0xa9,0xad,0x2f,0x54,0x7f,0x5b,0xf3,0x1b, - 0xfe,0xac,0x52,0x6c,0x4b,0xa5,0x22,0x66,0xef,0x2a,0x66,0x8d,0xa2,0x1b,0xef,0xfb, - 0xe2,0x2d,0x3b,0xde,0x0f,0x1c,0xef,0xfb,0xb5,0xb8,0x73,0x6c,0x7e,0x28,0xdc,0xf4, - 0x7d,0xe0,0xf4,0x7c,0x2c,0x3d,0x0d,0x4e,0xcf,0x27,0x4e,0xcf,0xc7,0x4e,0xcf,0x6a, - 0xa7,0x07,0x3a,0x3f,0x71,0x7d,0xf1,0x59,0xc2,0xf3,0xf4,0xab,0x5d,0x5f,0xac,0x91, - 0xee,0xcf,0xea,0x7c,0xfe,0xc2,0xf5,0xc5,0x0e,0x55,0x9e,0xcf,0x47,0x5c,0xd6,0x28, - 0x4e,0x36,0x1f,0xff,0xa3,0xb5,0xc3,0xc6,0xd4,0xda,0x84,0x18,0x64,0x06,0x95,0x69, - 0xd3,0x57,0x6e,0x8e,0xaf,0x55,0xae,0x18,0x2a,0xda,0xfa,0x4d,0xd0,0x16,0xa8,0xcf, - 0xbe,0x4b,0x88,0x7d,0x95,0x14,0x67,0x10,0xf1,0x1d,0x26,0xbe,0x01,0xb0,0x77,0x08, - 0x1b,0x12,0xf2,0x01,0xc7,0x3d,0x02,0x72,0x4e,0xed,0x9d,0x8b,0xd3,0xbb,0xa1,0x4e, - 0x6f,0x43,0x4a,0xbd,0xeb,0x93,0x42,0x4f,0x63,0x4a,0xbc,0x5e,0x4f,0x90,0x16,0x7a, - 0xc0,0x03,0x3d,0xa7,0x96,0xb9,0x4e,0xc7,0xa2,0xc1,0x7f,0xb4,0x67,0x78,0xe6,0x70, - 0xc8,0x5b,0xac,0x5a,0xa5,0x94,0xf9,0xb5,0x62,0xdf,0x3a,0x25,0x86,0x6f,0x0c,0xaa, - 0x9a,0xab,0x6d,0xd2,0xe2,0xec,0x07,0xe8,0xe7,0xeb,0xcc,0x76,0xdb,0x94,0x34,0xbb, - 0x57,0x69,0x97,0x12,0xf3,0x67,0xa5,0xda,0xa7,0xc4,0x9b,0xdc,0x3d,0xcd,0xd6,0xe2, - 0xf3,0x67,0xa5,0x3a,0xa4,0xc4,0x47,0xba,0x77,0xe0,0xdb,0xa4,0x94,0xef,0xe0,0xda, - 0xe8,0x28,0xd9,0x06,0xc7,0xb7,0x5d,0x4a,0xde,0x8e,0xce,0xaf,0x9d,0x52,0xfa,0x6c, - 0x7e,0xed,0x9c,0x12,0xf3,0x7e,0xfd,0xc8,0xf9,0xb5,0xb3,0xf3,0xeb,0xc7,0x29,0x69, - 0xd6,0xe6,0x2e,0x29,0x31,0xef,0xd7,0xae,0x29,0x71,0xef,0x57,0x67,0xf1,0x79,0xbf, - 0x76,0x4b,0x89,0x7b,0xbf,0x76,0x4f,0x29,0xbf,0x9b,0x6b,0xa3,0x8b,0x64,0xbd,0x5f, - 0x7b,0xa6,0xe4,0x05,0xcd,0xee,0x3d,0x1f,0x0b,0xe8,0x2f,0x68,0xc8,0x19,0x0b,0xdd, - 0xbe,0x16,0xb4,0xc7,0xf3,0xb2,0x50,0xfb,0x5a,0x5c,0xdb,0xfa,0xf7,0x7f,0xda,0xd7, - 0x5a,0x7d,0x91,0xf6,0xb5,0x56,0x5f,0xec,0xf6,0xb5,0xb5,0x5c,0x1e,0x50,0x06,0x7c, - 0x8b,0x83,0xe2,0xde,0xe1,0x85,0x80,0xf7,0xd5,0xf6,0xbd,0xe3,0x44,0xc5,0xf7,0xe7, - 0x8a,0x6f,0xab,0xb4,0x98,0x77,0x07,0xa9,0xfe,0x73,0x87,0xf5,0x10,0x9f,0xc7,0x0e, - 0x4d,0xd9,0x1e,0xb0,0x89,0xc2,0x8e,0x48,0x89,0x1f,0xe4,0xb0,0xa3,0x52,0xca,0x1f, - 0x94,0x16,0xf9,0xe3,0xe8,0x94,0xbc,0xa0,0x99,0x2f,0xc7,0xa6,0xb4,0xf3,0xd7,0xe2, - 0xe9,0x95,0x92,0x0f,0xf8,0x15,0xc2,0x7a,0xa7,0xc4,0xf1,0x4d,0xd1,0x70,0xdd,0xf3, - 0xfd,0x22,0x25,0x8e,0x7b,0x36,0xd4,0xfb,0xa4,0xc5,0x3d,0x1b,0x68,0xb3,0xe4,0xbf, - 0xed,0x91,0x8f,0x4f,0xc9,0x73,0xb9,0xea,0x27,0xa4,0xc4,0xec,0x3e,0xfa,0xc4,0x94, - 0x18,0xe6,0xdd,0x03,0xea,0xbf,0x7e,0x29,0xf1,0x25,0xa5,0x62,0x9e,0x9f,0x9c,0x12, - 0xb7,0x77,0x8e,0x4f,0x4b,0xfe,0x54,0xf1,0x82,0x6e,0x6d,0xf6,0x97,0x6f,0xf6,0x5e, - 0xf2,0xf4,0x94,0x7c,0xc0,0x27,0x08,0x1b,0x98,0x12,0x47,0xbb,0xc8,0x9f,0x36,0x1e, - 0x16,0xea,0x3e,0x09,0x3c,0x3f,0xa9,0xb2,0x2d,0xe4,0x54,0xf0,0x63,0xac,0x98,0x8d, - 0x2f,0x07,0x1c,0x5f,0xdb,0x69,0x8c,0x2d,0x77,0x63,0x0c,0xb4,0x65,0x79,0x59,0x2e, - 0x9d,0xb8,0x36,0x7b,0x57,0x06,0xd4,0xdb,0xdf,0x9d,0x53,0x7b,0x3d,0x20,0x0e,0x5b, - 0xec,0x1e,0xf5,0x0d,0x8d,0xa1,0xd7,0x75,0xfe,0xfe,0x2d,0xe9,0x7a,0x2b,0x28,0x62, - 0xf2,0x40,0x95,0x7c,0x4b,0xa4,0x17,0x7c,0xd6,0xe6,0x72,0xe7,0xc7,0x31,0x55,0xb6, - 0x09,0xdf,0x20,0x03,0x1d,0xbf,0x57,0x3b,0xab,0x02,0xfa,0x72,0x99,0xe4,0xdf,0x93, - 0xfc,0x7b,0xae,0x9d,0x07,0xab,0xe4,0x33,0x7f,0x0d,0x7f,0x48,0xb8,0xcd,0xb5,0xe6, - 0xb3,0x95,0x01,0x65,0x86,0xf9,0xb3,0x95,0x01,0xf9,0x3f,0x57,0x3b,0x76,0x5f,0x39, - 0xd3,0xd9,0x79,0x94,0xe2,0x8d,0x7b,0x55,0xd8,0xfc,0x9e,0xa3,0xed,0xe3,0x68,0xd0, - 0xf5,0x9e,0xee,0x23,0xd7,0xd6,0x9d,0xa7,0xfc,0x12,0x32,0xd2,0xfd,0xa5,0x78,0xbe, - 0xa9,0xbb,0xaf,0x5d,0x8f,0x6f,0xc5,0xc4,0xb3,0x3e,0x28,0xd6,0x28,0xfc,0xcf,0x01, - 0xac,0x51,0xcd,0xe7,0x01,0x02,0x62,0xb0,0xf7,0x1b,0xf1,0x7f,0x5f,0x57,0xff,0x26, - 0x28,0xf6,0xa2,0x7b,0x55,0x29,0x03,0x9d,0x1b,0xd4,0xc6,0x60,0xed,0xbb,0x4b,0x61, - 0xb1,0x1e,0x81,0x0f,0xeb,0x91,0xe5,0xab,0x06,0x7d,0x0c,0xbc,0x41,0xf6,0x36,0x86, - 0x85,0xbd,0xa0,0x55,0xf2,0xd2,0xa8,0xef,0x2f,0x2a,0x61,0x31,0xce,0x23,0xc9,0x61, - 0xfd,0xc2,0x65,0xac,0x36,0x10,0xab,0x48,0xe7,0x55,0x4d,0x0e,0xbf,0x16,0xcb,0x13, - 0xaa,0xe4,0x81,0xed,0xb1,0xf4,0xa3,0xdd,0xcc,0xb7,0x9b,0xd3,0x53,0xfc,0x2f,0x05, - 0xc9,0xe3,0xda,0xc6,0xeb,0xe6,0x61,0xcb,0x67,0x0c,0xc6,0x93,0x85,0xc5,0x33,0x86, - 0x2d,0x42,0x3e,0x5f,0x41,0xbb,0xe0,0x4f,0x65,0x4f,0x6b,0xf1,0xe2,0xd7,0xc6,0xd1, - 0x1f,0xab,0xe4,0x87,0xed,0x47,0xe9,0x99,0x8c,0xf5,0xe1,0x5a,0x37,0x06,0xfa,0xc8, - 0x6e,0x8c,0x19,0xf8,0xd0,0xda,0xf9,0xd4,0xb3,0x4a,0x59,0xd0,0xfe,0x28,0x5a,0xf3, - 0xf9,0x07,0x7d,0xc3,0x83,0x6f,0x44,0x9a,0xd7,0xdc,0x90,0x32,0xa0,0x9d,0xa3,0x3d, - 0xc3,0x56,0xae,0x8f,0xda,0xeb,0x4c,0x32,0xe2,0xd2,0x31,0x6c,0xf9,0x7d,0xc4,0xb6, - 0x79,0x7d,0x7f,0xf9,0xb1,0xad,0xbe,0x2d,0xc2,0xd9,0xe8,0x27,0x33,0xda,0xb8,0x40, - 0x7b,0x3e,0xc3,0x17,0x65,0xd4,0x0d,0x7a,0xc5,0xad,0x85,0xff,0x9d,0x6e,0x7c,0x86, - 0x7d,0x54,0x4a,0xdc,0x17,0x3b,0x8f,0x3d,0x3a,0x25,0xdd,0x9f,0xc7,0xbe,0x38,0x25, - 0xee,0xcf,0x63,0x5f,0x9a,0x12,0xf7,0x6b,0xf1,0xd8,0x94,0xb8,0x3f,0x8f,0x7d,0xb9, - 0xf8,0xfc,0x5a,0x3c,0x2e,0x25,0xee,0xcf,0x63,0x8f,0x4f,0x29,0x3f,0xce,0xad,0xc5, - 0x13,0x24,0xeb,0xcf,0x63,0x4f,0x4c,0x89,0xfb,0xf3,0xd8,0x57,0xa6,0x94,0x9f,0xe8, - 0x64,0xaf,0x92,0xac,0x3f,0x8f,0x3d,0x29,0x25,0xee,0xcf,0x63,0x4f,0x4e,0x29,0x3f, - 0xc9,0xc9,0x0e,0x4f,0x37,0x3e,0xc3,0x7e,0x6d,0x4a,0xdc,0x17,0x8b,0xd9,0xd4,0x94, - 0x74,0x1f,0xb3,0xeb,0x53,0xe2,0x3e,0x66,0xd3,0x53,0xe2,0x3e,0x66,0x4d,0x29,0x71, - 0x1f,0xb3,0x1b,0xc4,0xe7,0x63,0x36,0x23,0x25,0xee,0x63,0x76,0x63,0x4a,0xf9,0x19, - 0xce,0xf6,0x9b,0x25,0xeb,0x63,0x36,0x33,0x25,0xee,0x63,0x76,0x4b,0x4a,0xf9,0x99, - 0x4e,0xf6,0x36,0xc9,0xfa,0x98,0xcd,0x4a,0x89,0xfb,0x98,0xdd,0x9e,0x52,0x1e,0x34, - 0x3b,0xc3,0x7e,0x41,0xca,0x58,0x82,0x86,0xe7,0xbb,0xf8,0xee,0x10,0x98,0xcd,0x8f, - 0x79,0x29,0xf7,0x29,0x47,0x04,0xc5,0xb3,0xeb,0x3f,0xa4,0xfc,0x9f,0x22,0xa0,0xe1, - 0xdd,0x1b,0xee,0x2b,0xe7,0xa7,0xfc,0x66,0xb1,0xbf,0xfb,0xb6,0xe8,0x81,0x94,0xb8, - 0x3d,0xa3,0x7f,0x30,0x25,0x36,0x40,0xdf,0xa2,0x5b,0x2e,0x7d,0x28,0x25,0xcd,0xe4, - 0x16,0xd4,0xc9,0x3d,0x9c,0x12,0xab,0x3f,0xbf,0xfa,0x48,0x4a,0x9a,0xc9,0xfd,0xa9, - 0x4e,0xee,0xcf,0x29,0xb1,0xfa,0xf3,0xac,0x8f,0xa5,0xa4,0xd9,0xfb,0xd1,0x85,0x29, - 0x7d,0x1a,0x59,0x2a,0xfc,0xf9,0x5f,0xf9,0xb3,0xd0,0xe9,0x7f,0x22,0x25,0x6e,0xe7, - 0x15,0x9e,0x94,0xdc,0x68,0x77,0x4e,0xe0,0xa9,0x94,0x7c,0xa0,0xf9,0x73,0x13,0x8b, - 0x52,0xd2,0x9a,0xcf,0x35,0xa6,0xfc,0x0e,0x7d,0x9e,0xb3,0xe3,0xe9,0x94,0xb8,0xb7, - 0xe3,0x19,0xd9,0xf1,0xb4,0xb3,0xe3,0xd9,0x94,0xb8,0xd9,0xf1,0x9c,0xe4,0x46,0xbb, - 0xf3,0x7a,0xcf,0xa7,0xe4,0x7b,0xce,0xed,0xa7,0x5e,0x48,0x89,0xfb,0xf7,0x12,0x7f, - 0x4f,0x89,0xa3,0xef,0xf1,0x0d,0xeb,0x9d,0xa5,0xe2,0xd9,0xfe,0x4b,0x29,0xbf,0x6b, - 0x45,0xbc,0x16,0xa5,0xc5,0xb3,0xfd,0x25,0x29,0x69,0xe6,0xcb,0xd2,0x94,0x7a,0xa6, - 0x69,0xef,0x05,0xec,0x5f,0x29,0xf9,0x96,0xba,0xb1,0xb4,0x3c,0x25,0x8e,0x7e,0xb3, - 0xfb,0xfc,0x15,0x29,0xfb,0x7f,0xb9,0xdb,0x37,0xbe,0xea,0xf6,0x8d,0x2b,0xd2,0xe2, - 0x39,0xbb,0xad,0x6d,0x5d,0x42,0xe6,0xeb,0x33,0xb5,0x7e,0xee,0x95,0x15,0xb9,0xf9, - 0x55,0xcd,0x35,0x5b,0x5b,0xf7,0xd9,0x04,0xcd,0xd6,0xd6,0xb5,0x29,0x65,0xc1,0x83, - 0x5c,0xfe,0x6d,0x5a,0xe4,0x72,0xd0,0xd6,0xe5,0x05,0x18,0x72,0xf9,0x3a,0xe7,0xef, - 0x81,0x92,0x81,0xac,0xed,0x99,0xbb,0x66,0xc4,0x8d,0xa7,0x7b,0xc6,0xf6,0x3c,0x4f, - 0x8f,0x8c,0xb8,0xed,0xbd,0x0f,0xc9,0x88,0x41,0xd6,0xf6,0xda,0x87,0x66,0xc4,0xf1, - 0x0d,0xbc,0xed,0xb5,0x0f,0xcb,0x88,0x63,0xaf,0x7d,0xbe,0x62,0x70,0x78,0x46,0xdc, - 0xf6,0xce,0x47,0x66,0xc4,0xac,0xaf,0x7b,0x66,0xc4,0xf0,0xed,0xbc,0x9d,0x67,0x3a, - 0x5a,0xdf,0x42,0x83,0x66,0xf7,0x23,0xc7,0x64,0xc4,0xed,0xbd,0x9b,0xc5,0xf8,0xd8, - 0x8c,0x34,0xdb,0x9b,0xf6,0xce,0x28,0x77,0xac,0xce,0xea,0x5a,0x5c,0xf0,0x6b,0xeb, - 0xec,0xaf,0xb4,0x0f,0xc3,0xba,0x07,0x7e,0xc4,0xcc,0xf6,0xc4,0xdf,0xa7,0xec,0xb7, - 0xa5,0x7a,0x56,0x13,0x64,0x45,0xac,0x41,0xdb,0x90,0x97,0xc6,0x8c,0x3a,0x37,0xa4, - 0xc5,0x59,0xc9,0xb2,0xfa,0xaf,0x4b,0x58,0xec,0xd9,0x1b,0x32,0xe2,0x93,0x5d,0xbe, - 0xab,0x64,0x6c,0xbf,0x41,0xf6,0x05,0xd2,0xd5,0x58,0x57,0xc7,0xaf,0xd9,0x3b,0xaa, - 0x4a,0xb9,0x0d,0xca,0x93,0xe0,0xb5,0x58,0xc5,0x59,0x4b,0x7b,0x5b,0x39,0x7b,0x41, - 0x4b,0xf2,0xb2,0x85,0x74,0x26,0x59,0x61,0x6f,0xd5,0xd9,0x6b,0xf7,0x13,0x9b,0x65, - 0xc4,0xbd,0xbd,0x9b,0xcb,0xde,0xcd,0x64,0x5f,0x2b,0xe9,0xda,0xa2,0xae,0xde,0xca, - 0xd9,0x7b,0x51,0x95,0x72,0x68,0x0f,0xf6,0x82,0xd7,0xf6,0x5d,0x6d,0xeb,0xec,0xed, - 0xe4,0xec,0x05,0x6d,0x4b,0xbc,0x53,0x94,0xce,0x2d,0xdd,0x38,0x69,0x2f,0x3b,0xfa, - 0x3b,0xdb,0xb6,0xca,0x88,0x8f,0x76,0x6b,0x47,0x87,0x8c,0xf1,0xda,0xca,0xc9,0x6e, - 0x2b,0x59,0xfc,0xff,0x05,0xcb,0x3b,0x1d,0x33,0xe2,0xfe,0x2c,0xfe,0xf6,0x19,0x6d, - 0xef,0x28,0xdf,0xcc,0x8e,0x4e,0xce,0xb7,0x4b,0xab,0xe4,0x81,0xbf,0xdb,0xcb,0x5e, - 0xa3,0x5d,0x52,0x65,0xdb,0xa0,0x75,0x10,0xcd,0xf6,0x65,0x3b,0xba,0xf9,0x7d,0x89, - 0xf6,0xce,0x46,0xdb,0xd9,0xd1,0x2e,0xad,0x16,0xe7,0x88,0x6b,0xef,0x4c,0x35,0x87, - 0x17,0x38,0x6c,0x17,0xcd,0xe9,0x05,0xa5,0xe2,0x3c,0xcd,0xae,0x19,0xf1,0x81,0xee, - 0xec,0xcc,0x4f,0x33,0xca,0xef,0xea,0xde,0x1f,0x75,0xce,0x88,0x37,0x3f,0xa3,0xc8, - 0x88,0xed,0x98,0x15,0x6b,0x6d,0x97,0x8c,0x38,0xec,0x3a,0x2e,0xd7,0x84,0xfd,0xc6, - 0x7e,0x21,0xf7,0x80,0xa0,0x35,0xea,0xff,0x4d,0x34,0xe8,0x7f,0x0c,0x20,0x56,0x1d, - 0xb5,0x97,0xdc,0xdf,0xed,0x25,0x97,0x68,0x2f,0x79,0xba,0x9e,0x59,0x1a,0xbe,0x54, - 0x7b,0xc9,0x25,0xfa,0xde,0xc8,0xcb,0x77,0xd4,0x7e,0x18,0x7c,0x77,0x54,0xd9,0x2e, - 0xe2,0x0f,0x99,0xfd,0xdd,0xfe,0xfd,0x20,0xe5,0x56,0x3b,0x53,0xda,0xdd,0xed,0x6f, - 0x41,0xeb,0x96,0x97,0xee,0xd2,0xd9,0xcd,0x7d,0xc3,0xde,0x23,0xe4,0xb7,0xc5,0xb3, - 0xdc,0xfa,0x7f,0x70,0x48,0xfc,0x2a,0xfb,0x0e,0x2b,0x24,0xf6,0x8e,0x5b,0x7f,0x0e, - 0x0d,0x89,0x9b,0x9e,0xc3,0xa4,0x67,0x9a,0xd3,0x73,0x78,0x48,0xdc,0xf4,0x1c,0x11, - 0x12,0xf3,0x7a,0x8e,0x0c,0x89,0xdb,0xb7,0xee,0x3d,0x43,0xea,0x3e,0x52,0x79,0x03, - 0xd8,0xd1,0x21,0xbf,0xc1,0xee,0xa9,0xff,0x9b,0x80,0xff,0xa3,0xd1,0x5b,0xff,0x43, - 0x63,0x10,0xfe,0x47,0x5d,0x48,0x9e,0x3b,0x74,0x9f,0x61,0x7e,0x76,0x0f,0x5b,0x7e, - 0xe7,0x8e,0xdf,0xef,0xf3,0x08,0x1f,0x90,0x97,0xff,0x07,0x78,0xf5,0xe8,0xd4,0x30, - 0x50,0x00,0x00 + 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0x6d,0x5c,0x09,0xdc,0x95,0x63, + 0xfa,0x3e,0xe7,0x3b,0xdf,0x79,0xd7,0x73,0x94,0x7d,0x4b,0x49,0xa2,0x12,0x46,0xc5, + 0x18,0x89,0x22,0x4b,0x65,0x09,0xf3,0x47,0x66,0x68,0x14,0xbe,0x94,0x35,0x63,0xf9, + 0x9b,0x22,0x89,0x61,0x8c,0x65,0x08,0x95,0x92,0x2d,0x24,0x59,0xb2,0xd6,0x0c,0x9a, + 0x9a,0xb2,0xfd,0xad,0x21,0x33,0x4a,0xb6,0xd0,0xc2,0xd8,0x42,0x28,0xff,0xf7,0x3a, + 0xd7,0x75,0xf7,0xde,0xdf,0xd1,0xf7,0xfb,0x3d,0xbf,0xf3,0x3e,0xd7,0x75,0xdf,0xf7, + 0x73,0x3f,0xf7,0xf3,0xbc,0xf7,0xf3,0xbc,0xdb,0x57,0x6a,0x68,0x17,0x16,0x4a,0xc5, + 0x42,0x52,0x88,0x0a,0x5f,0x55,0x0b,0xb5,0xbf,0x0d,0x0b,0x0d,0x85,0xa2,0x7e,0x77, + 0xd1,0x6f,0x0f,0xfd,0xf6,0xd2,0xef,0xfe,0xd9,0x6f,0x5a,0x08,0x6a,0x72,0x07,0x1d, + 0x72,0xd4,0x21,0xbb,0x9c,0xf3,0xc7,0x93,0x76,0xe9,0xb6,0xfb,0xaf,0xa0,0xbf,0x41, + 0xa1,0x54,0xb3,0x03,0xae,0x45,0x66,0xb7,0x9c,0xfd,0x36,0x66,0xe5,0xf4,0x13,0x4f, + 0x3d,0x03,0xf8,0x51,0x19,0x3d,0x20,0x2b,0xe7,0x64,0x60,0xcb,0xcc,0x46,0x63,0xcd, + 0x66,0xa1,0xd0,0x53,0x3a,0x28,0x07,0x67,0x5a,0xaf,0xd3,0x9d,0x42,0x3b,0xfd,0x1a, + 0x56,0x14,0xd6,0xe8,0xb0,0x06,0x61,0x91,0xc3,0x4a,0xc2,0x2a,0x0e,0x6b,0x14,0xd6, + 0xd2,0x61,0x65,0x61,0x9b,0x38,0x2c,0x10,0xb6,0x85,0xc3,0x42,0x61,0xad,0xd0,0xe7, + 0xcc,0xba,0xb5,0x7b,0x50,0x66,0x15,0x7d,0x4a,0xb3,0xe3,0xad,0x54,0x1f,0xa0,0xfa, + 0xd6,0x92,0x45,0x5f,0x0b,0xe2,0x70,0x0c,0xae,0xa3,0xea,0xb3,0x32,0x07,0xb6,0x2b, + 0xe4,0x3c,0xea,0x6d,0xd7,0xd5,0x4b,0x85,0x33,0x82,0x9c,0x7b,0x26,0x68,0x2e,0x8b, + 0x7a,0x5b,0xc5,0x04,0xb2,0xa8,0x6f,0x29,0xee,0x5f,0x01,0xdb,0xd9,0x52,0xdc,0x31, + 0x09,0xf5,0x36,0xce,0xbc,0x86,0xdf,0x6d,0x33,0xac,0xa4,0x3e,0x6c,0x9a,0xc9,0xa3, + 0x99,0x6d,0x65,0x7b,0xf3,0xac,0x1e,0x2a,0x0e,0x0d,0x35,0xbc,0xb1,0x16,0xdb,0x50, + 0x05,0xf2,0xb1,0xe4,0x8b,0xe2,0x13,0x71,0xb1,0xf4,0x5b,0xea,0xd8,0xf4,0x37,0x14, + 0xdf,0xb2,0x16,0xeb,0x86,0xc2,0x46,0x92,0xdb,0x44,0x72,0x8d,0x92,0x6b,0x23,0x39, + 0xb4,0xbd,0x59,0xe6,0x61,0x07,0xb5,0x03,0x59,0xc4,0xac,0x83,0xc6,0x16,0xf5,0x2e, + 0x92,0x43,0x7d,0x27,0xf9,0x74,0x62,0x56,0x76,0x76,0xf5,0x41,0x8e,0x87,0x6c,0x93, + 0x7c,0x36,0x7e,0xa8,0xc6,0xd9,0xea,0xc3,0x34,0x8f,0xac,0x7e,0xb6,0xe6,0x86,0xd5, + 0x87,0xcb,0x57,0xab,0x5f,0xa0,0x3e,0x59,0x7d,0xa4,0xe6,0x94,0xd5,0x47,0x67,0xa5, + 0x8d,0xab,0x8f,0x51,0x4c,0xcc,0x9f,0xb1,0xd2,0x6f,0x95,0xd5,0x6f,0x54,0x5b,0x63, + 0x9d,0xfc,0x4d,0xb5,0x73,0xaa,0x50,0xe8,0x9c,0x45,0x05,0xdc,0xcd,0xb2,0x31,0x52, + 0xbe,0xde,0xe4,0x64,0xc7,0x29,0x1e,0x56,0x1f,0xaf,0xd8,0x5a,0x7d,0x82,0xce,0x07, + 0xb3,0x75,0x8b,0x6c,0x8d,0x93,0xec,0x04,0x27,0x3b,0xb1,0x2e,0x4e,0x93,0x34,0x2e, + 0xa6,0x7b,0xab,0x64,0x86,0x8b,0x9b,0xe0,0xb8,0xc9,0xe2,0x06,0xc9,0x4f,0x6f,0xf7, + 0xb6,0x02,0xe7,0xa5,0xc9,0xde,0xee,0xfa,0x33,0x49,0xbc,0xc9,0xde,0x91,0x95,0xc4, + 0xc9,0xde,0xe9,0xfc,0x1d,0x26,0xde,0xb8,0xbb,0xd4,0xde,0x38,0xd9,0xf1,0xdc,0x14, + 0xe9,0x0d,0x5f,0x0f,0x77,0xb7,0x7c,0xb5,0xf6,0xc7,0x3b,0xee,0x9e,0xba,0x3e,0x7a, + 0xee,0x5e,0xd7,0xc7,0x7a,0x6e,0xaa,0xd3,0x1b,0x57,0xc7,0xdd,0x27,0x5f,0x06,0x39, + 0xce,0xfa,0x3b,0x4d,0xe7,0x9f,0xc9,0xde,0x2f,0x6c,0xa2,0x74,0xbc,0x9d,0xe9,0x2e, + 0xbe,0x93,0x14,0x0f,0xe3,0x1e,0x70,0xfd,0x1d,0xb7,0x8e,0xdb,0xb8,0x36,0xbf,0x1e, + 0xd4,0x1c,0xba,0x45,0x63,0x38,0x59,0x63,0x70,0xa7,0x62,0x38,0x45,0x31,0xb9,0x47, + 0x7d,0x9c,0x2a,0x9f,0xef,0x57,0x9b,0x0f,0xe8,0x3c,0x9d,0xa1,0xf9,0x70,0xa3,0xf3, + 0x7f,0x76,0x56,0x7e,0xce,0x4a,0xa7,0xec,0x8c,0xc3,0xf9,0xfd,0x5a,0x56,0x5a,0x67, + 0x23,0x68,0x39,0x35,0xd0,0x7c,0x0c,0xd6,0x53,0x60,0x73,0x81,0x78,0xc8,0x77,0x57, + 0xfd,0x0d,0x61,0xe0,0xdf,0x74,0xfa,0x76,0xfe,0x2c,0xae,0x3b,0x9f,0x96,0x28,0x86, + 0x1d,0xe5,0xc3,0x47,0xca,0x15,0x4b,0xa5,0xeb,0x73,0xc1,0x72,0xe5,0x73,0xab,0xaf, + 0x70,0xe7,0x3a,0xea,0x2b,0xd7,0x9d,0x2f,0x41,0x2d,0xd7,0x7c,0x26,0x9d,0x15,0xe2, + 0x4c,0xee,0xf3,0xba,0x9c,0xb0,0xaa,0xb6,0xf6,0xe5,0xf5,0xd5,0x5a,0xe3,0xac,0x5e, + 0x2c,0x72,0x6d,0xb0,0x7a,0xa5,0x88,0xbc,0x9c,0xdb,0xeb,0x5c,0xcc,0x73,0x06,0xea, + 0x27,0x14,0x99,0x93,0x90,0x23,0x06,0x16,0xd9,0x0f,0x60,0xa6,0xff,0x87,0x22,0xfa, + 0xe8,0x72,0x60,0x91,0x39,0x73,0x5d,0x0e,0x2c,0x72,0xbd,0xb1,0xfa,0xe0,0x22,0xd7, + 0xdb,0xce,0xd9,0x99,0x08,0x7b,0x27,0x15,0xf3,0xf9,0x78,0x9b,0x72,0x1a,0x6c,0xc2, + 0x0e,0x74,0x07,0x17,0x19,0xff,0x53,0x8a,0x1c,0x73,0xe8,0x20,0x26,0x88,0xe9,0xe4, + 0x22,0xe7,0xa8,0x15,0xc3,0x6f,0x2b,0x72,0x3e,0x58,0xb1,0xb6,0x97,0x16,0xb9,0x3b, + 0xb0,0xfa,0xa7,0x5a,0xf4,0xad,0xbe,0x6f,0x03,0xd7,0x2c,0xab,0xf7,0xc9,0xea,0x1b, + 0xb9,0xfa,0xe9,0x59,0xbd,0xaa,0x58,0xb4,0x2a,0x31,0x77,0x9e,0x50,0xf3,0xa7,0x5c, + 0x3b,0xde,0xa6,0xc4,0xb9,0xcf,0x39,0x4f,0xac,0x75,0x89,0xe7,0xc9,0x6a,0x67,0xa7, + 0x4d,0x86,0x6d,0xe3,0x64,0xb6,0x2d,0xf1,0xfc,0x02,0x6e,0x32,0x6d,0x4b,0x98,0xcb, + 0xb9,0xcc,0x76,0x25,0xb6,0xdf,0xd6,0xc9,0xb4,0xcb,0x8e,0xf7,0x76,0x32,0xdb,0x97, + 0xe8,0x73,0x3b,0x27,0xd3,0x3e,0x3b,0xee,0xef,0x64,0x76,0x28,0x71,0xdd,0x69,0xef, + 0x64,0x76,0x2c,0x71,0x2d,0xb7,0x7a,0x07,0xc9,0x98,0x4e,0xc7,0x12,0x65,0x3a,0x38, + 0x9d,0x4e,0xd9,0xf1,0xae,0x4e,0x67,0xa7,0xac,0xfe,0x84,0xd3,0xe9,0x5c,0xa2,0x0c, + 0x70,0x8c,0x35,0xe2,0xb5,0x73,0x89,0x31,0x42,0x4c,0xd0,0x67,0xf4,0x09,0x3e,0xc3, + 0x27,0xb4,0x01,0x1d,0x8c,0xf5,0xaf,0x4a,0x1c,0xeb,0x56,0xaa,0x1f,0x59,0xe2,0x7a, + 0xd0,0x45,0xe7,0x26,0xea,0x47,0x09,0xb3,0xfa,0x80,0x52,0xbe,0x1f,0x38,0x4e,0xc7, + 0xfe,0x5c,0x3d,0xb1,0x94,0x9f,0x17,0xa8,0x0f,0x2f,0xe5,0x6b,0xf9,0xc8,0x12,0x65, + 0x1b,0x1d,0x3f,0xba,0xc4,0xb5,0x19,0x79,0x0d,0xfc,0xa5,0x25,0x9e,0xdf,0x18,0xef, + 0xb1,0xe2,0x4d,0xf6,0xb2,0x12,0x73,0x0f,0xea,0xd8,0x23,0x3c,0xcd,0x6d,0xe8,0xba, + 0xfa,0x33,0xb5,0xfa,0xa8,0x7d,0xad,0x3e,0x87,0x7c,0x4f,0xab,0xcf,0xad,0xd5,0x7b, + 0xf6,0x34,0x7b,0xcf,0x97,0xb8,0x8f,0xd8,0x22,0xab,0x57,0x1b,0x79,0xfe,0x94,0x9c, + 0xbd,0xbe,0xb5,0x3d,0xdd,0xc5,0xbd,0xad,0x7e,0x58,0x56,0xff,0xf3,0x66,0xe3,0xf7, + 0xb1,0xfa,0xe1,0x59,0xfd,0x8e,0x03,0x36,0x5b,0xd7,0x5e,0xff,0xac,0xfe,0xe6,0x05, + 0xcb,0x7a,0xe0,0xfc,0x80,0xad,0x23,0x1a,0xa9,0x03,0x39,0x70,0x26,0x37,0x30,0x3b, + 0x3e,0x73,0xa3,0xd2,0xbe,0xdd,0x15,0x43,0xec,0x17,0x8b,0xae,0xdd,0x1b,0x6a,0xed, + 0xbe,0xb7,0xce,0xcf,0x71,0x59,0xfd,0xec,0xa3,0xbb,0x35,0x58,0xfd,0x1f,0x8d,0xf9, + 0xfe,0x03,0xf2,0xcb,0xb2,0xfa,0xea,0xef,0xbf,0xef,0x61,0xf5,0xe5,0x59,0x7d,0xcd, + 0x4f,0x23,0xf6,0x31,0x3f,0x56,0x34,0x52,0x66,0xb9,0x7e,0x31,0x16,0x6d,0xca,0x3c, + 0xe7,0x6c,0x6c,0x26,0xa8,0xde,0x50,0xdb,0x4f,0xc6,0x85,0x27,0xca,0x1c,0xab,0x72, + 0xa1,0xf9,0x5f,0x51,0xbf,0x5b,0x67,0x9a,0x4f,0x66,0x24,0xe4,0x30,0x17,0x66,0x4a, + 0x10,0x58,0x77,0xd5,0x67,0x09,0x03,0xff,0x6c,0x99,0x39,0xcd,0xef,0x55,0xce,0xce, + 0x1a,0xf8,0x39,0xfb,0x43,0x7b,0x4f,0x05,0x6c,0xaf,0x58,0xd7,0x5e,0x43,0x6d,0x7d, + 0xa1,0x8d,0xa7,0xb5,0x4f,0x86,0x6c,0x77,0xd5,0x9f,0x09,0xf2,0x39,0x80,0xc3,0xb9, + 0x81,0xe5,0x3d,0xe6,0x73,0xec,0x91,0x81,0x35,0x69,0x5f,0x88,0xf3,0x06,0x73,0xfe, + 0xc7,0x0a,0xe7,0x98,0xcf,0x2b,0x3f,0x55,0x98,0x57,0xc6,0xb8,0xf3,0x6b,0x4d,0x85, + 0x79,0x73,0x90,0x9b,0xa3,0x6b,0x2b,0x9c,0x8b,0xbe,0x58,0x4e,0xfc,0xd9,0xc9,0x0f, + 0x72,0xb9,0x12,0x09,0xcd,0x6c,0x8f,0x71,0x78,0xb1,0xca,0x9c,0x65,0xc5,0xf0,0x86, + 0x2a,0xd7,0x18,0x2b,0xd6,0x9f,0x52,0x35,0xf7,0xfb,0x04,0x97,0xa3,0x1b,0xab,0xdc, + 0x0b,0x58,0x31,0xf9,0x72,0x95,0xeb,0xa7,0x95,0x62,0x36,0x6e,0x90,0xdf,0xbe,0xca, + 0x63,0xf4,0x67,0x9c,0x8e,0x21,0xff,0x85,0xc3,0xbf,0xcc,0x8e,0xf7,0xc8,0xe2,0xd0, + 0xa0,0x73,0xb6,0xa0,0xf9,0xf2,0x7d,0x86,0x94,0x95,0x13,0xb0,0x47,0x98,0x99,0x32, + 0x8f,0x74,0xd7,0xfa,0x71,0x61,0xd8,0xbc,0x7e,0x95,0xab,0x23,0xe7,0xdc,0xe1,0xea, + 0x58,0x33,0x57,0x94,0xf3,0x3a,0xd6,0xc0,0x09,0x01,0xeb,0xdf,0x65,0xad,0xcd,0xd3, + 0xf8,0xfe,0x98,0x1d,0x23,0x2f,0xcc,0x0f,0xd8,0x3e,0x7e,0x7b,0xe8,0xfa,0xe0,0xa5, + 0x80,0x79,0xea,0xf0,0x4c,0x0b,0x7a,0x2f,0x07,0xc4,0x5e,0x0a,0xf2,0x39,0x3b,0x46, + 0xe3,0xfe,0x6a,0x40,0x1e,0xe3,0xdf,0x2b,0xc3,0x70,0xfe,0xbd,0x16,0x30,0xaf,0xc1, + 0x7e,0x0f,0xcd,0xa3,0xd7,0x03,0xe2,0x73,0x32,0x19,0xd4,0x17,0x04,0xc4,0xb0,0x0f, + 0x78,0x56,0xd8,0x5b,0xc2,0x90,0xf3,0x0c,0x7b,0x3b,0xa0,0x6c,0x93,0xda,0x04,0xf6, + 0x6f,0xe9,0x81,0x3b,0x42,0xd8,0x3b,0x01,0x7d,0xa9,0x65,0x2c,0x61,0x8b,0x02,0xe2, + 0x90,0x3f,0x32,0x43,0xe0,0xef,0xa1,0x15,0xe2,0x26,0x6b,0xed,0x2c,0x51,0x3b,0x8b, + 0x5d,0x3b,0xef,0xa9,0xbe,0xc4,0xb5,0xf3,0x81,0x74,0x8b,0xae,0x9d,0x0f,0x03,0xe2, + 0xef,0xb9,0x76,0xfa,0x57,0x88,0xa3,0xbd,0xa2,0x6b,0xe7,0xe3,0x80,0xfd,0x44,0x1e, + 0xb7,0x58,0x7c,0x2a,0x0c,0xf3,0xb8,0xbf,0xe2,0xba,0x2c,0xa0,0x2c,0xb8,0x51,0xc2, + 0x56,0x04,0xb4,0x0b,0x6e,0x84,0xae,0x17,0x3f,0x0b,0x88,0x23,0xf6,0xd8,0xeb,0xdd, + 0x50,0xe6,0xfe,0x6f,0x90,0x8b,0xfd,0xd8,0x32,0xf1,0x11,0xca,0x13,0x37,0x96,0x89, + 0x99,0xce,0x4d,0xd2,0x19,0xee,0x74,0x6e,0x2e,0x13,0x37,0x9d,0x71,0x65,0x62,0xfd, + 0x75,0x1e,0x8f,0x2f,0xd3,0x0e,0xf0,0x07,0x33,0x0c,0xf9,0xee,0x96,0x32,0xfd,0x01, + 0x37,0x21,0xd3,0x43,0xfe,0x9b,0x28,0x1c,0x73,0xef,0x56,0xe5,0xaf,0x1f,0x32,0x0e, + 0xf8,0xa4,0xac,0x00,0xc3,0xfc,0xc3,0xf1,0xea,0xec,0x77,0x9e,0xe6,0x23,0xf0,0xb9, + 0x6a,0xeb,0x4e,0xd9,0x45,0x3e,0x79,0x56,0xd8,0x3d,0xc2,0x90,0x4f,0x30,0x36,0xf0, + 0xf1,0xbe,0x32,0xf1,0x82,0xc6,0xb0,0x76,0x7d,0x50,0x66,0xbf,0xc0,0x99,0xdc,0x74, + 0xc9,0xd9,0x18,0x02,0x7b,0xa0,0x4c,0x59,0x70,0xa6,0x3b,0x43,0xba,0xc0,0x4c,0xee, + 0xb1,0x32,0x71,0xd8,0x43,0xac,0x90,0x9f,0xff,0xae,0xdc,0x6c,0xf6,0x9f,0x2a,0xd3, + 0x67,0x3f,0x47,0x66,0x2b,0xe6,0x7e,0xdc,0xff,0x59,0x26,0x8e,0x71,0xb7,0x38,0xcf, + 0x29,0x13,0x37,0x1f,0xe6,0x96,0x69,0x6f,0x8e,0xb3,0x3f,0x4f,0xf6,0x0b,0xce,0xff, + 0xf9,0x65,0xca,0xce,0xd3,0xb8,0x62,0x7d,0x78,0x4e,0xe3,0x3a,0x46,0xe3,0x0a,0xb9, + 0xe7,0x85,0x9b,0xde,0x0b,0x65,0xea,0x02,0x3f,0x29,0x93,0xc1,0xfa,0xf3,0xa2,0xfa, + 0x34,0x30,0x93,0x41,0xde,0xfa,0x3f,0x61,0x2f,0xb8,0x39,0xf3,0x92,0x6c,0x8f,0x74, + 0x73,0xe6,0xe5,0x32,0xf1,0xfb,0x32,0x19,0x8c,0xfd,0x2b,0x65,0x62,0xc8,0xab,0x18, + 0xff,0xd7,0xdc,0xf8,0x83,0x7b,0x35,0x2b,0x0b,0x35,0xfe,0xaf,0x96,0xf3,0x73,0xec, + 0xeb,0x80,0x6d,0x96,0x6a,0xe7,0x03,0xd7,0x88,0x35,0x01,0x71,0x5f,0xe6,0xc8,0xbf, + 0xb5,0x01,0xf9,0x4b,0x95,0x37,0x80,0x15,0x43,0xe2,0x6b,0x2b,0xb9,0xdd,0x52,0x48, + 0x1c,0x7f,0xff,0x12,0xd6,0x18,0x12,0xc7,0xbe,0xc8,0xe4,0x02,0xc9,0x15,0x9d,0x5c, + 0x18,0x12,0xc7,0x1e,0x6a,0x9e,0xb0,0x28,0xa4,0x3e,0x38,0xd3,0x4d,0xa4,0xdb,0xe0, + 0x74,0xd3,0x90,0x38,0xe2,0x60,0xba,0x95,0x90,0xfa,0xa9,0xd3,0xdd,0x40,0xba,0x25, + 0xa7,0xdb,0x22,0x24,0xbe,0xc4,0xb5,0xdb,0x32,0xa4,0x7e,0x0b,0xa7,0xfb,0xad,0x62, + 0xd6,0xe0,0x62,0xb6,0x69,0x48,0xdc,0x17,0x8b,0xd9,0x66,0x21,0x79,0x1f,0xb3,0x2d, + 0x43,0xe2,0x3e,0x66,0x5b,0x87,0xc4,0x7d,0xcc,0x5a,0x85,0xc4,0x7d,0xcc,0x5a,0x4b, + 0xce,0xc7,0xac,0x4d,0x48,0xdc,0xc7,0x6c,0xdb,0x90,0xfa,0x6d,0x9c,0xef,0xdb,0x49, + 0xd7,0xc7,0xac,0x5d,0x48,0xdc,0xc7,0x6c,0xfb,0x90,0xfa,0xed,0x9c,0xee,0x0e,0xd2, + 0xf5,0x31,0xdb,0x31,0x24,0xee,0x63,0xd6,0x21,0xa4,0x3e,0x38,0xcb,0xb1,0xdf,0x07, + 0x8c,0x25,0x38,0xe4,0x9e,0xd7,0x34,0x17,0x17,0xba,0xb9,0xb8,0x4b,0xc8,0xb8,0x16, + 0x5d,0x5c,0xf7,0x0c,0x89,0xfb,0x62,0x71,0xfd,0x4d,0x48,0xde,0xc7,0x75,0xef,0x90, + 0xb8,0x8f,0xeb,0x3e,0x21,0x71,0x1f,0xd7,0x7d,0x43,0xe2,0x3e,0xae,0xbd,0x24,0xe7, + 0xe3,0xba,0x5f,0x48,0xdc,0xc7,0x75,0xff,0x90,0xfa,0xfb,0xb9,0xd8,0x1c,0x20,0x5d, + 0x1f,0xd7,0x03,0x43,0xe2,0x3e,0xae,0x07,0x85,0xd4,0x3f,0xd0,0xe9,0xf6,0x91,0xae, + 0x8f,0x6b,0xdf,0x90,0xb8,0x8f,0x6b,0xbf,0x90,0xfa,0x7d,0x9d,0xee,0x6e,0x8a,0x59, + 0xc1,0xc5,0xac,0x7f,0x48,0xdc,0x17,0x8b,0xd9,0x11,0x21,0x79,0x1f,0xb3,0xdf,0x86, + 0xc4,0x7d,0xcc,0x8e,0x0e,0x89,0xfb,0x98,0x1d,0x13,0x12,0xf7,0x31,0x1b,0x20,0x39, + 0x1f,0xb3,0xe3,0x42,0xe2,0x3e,0x66,0xbf,0x0b,0xa9,0x7f,0x9c,0xf3,0xfd,0x78,0xe9, + 0xfa,0x98,0x9d,0x10,0x12,0xf7,0x31,0x1b,0x18,0x52,0xff,0x04,0xa7,0x7b,0xa2,0x74, + 0x7d,0xcc,0x06,0x85,0xc4,0x7d,0xcc,0x06,0x87,0xd4,0x1f,0xe4,0xe6,0x62,0xd7,0x90, + 0xb1,0x1c,0x5c,0x37,0x17,0xf1,0xbb,0x4a,0xfb,0xb0,0xa0,0xca,0x39,0x8b,0x5c,0x09, + 0xf9,0x85,0x2e,0xd7,0x2e,0x51,0xae,0x6d,0xd2,0x3e,0xef,0x7d,0x97,0x6b,0xc1,0xbd, + 0x97,0x95,0xf7,0x65,0xf3,0x3d,0x37,0xbf,0x3f,0x2c,0xd3,0xae,0xdf,0xa3,0x7c,0x54, + 0x26,0xbe,0xb8,0x90,0xdb,0x5f,0x5a,0x26,0xbe,0xa4,0x40,0xff,0xcc,0xd6,0xfb,0xf2, + 0x0f,0x32,0x1f,0x97,0xe9,0x07,0x7c,0x5e,0xaa,0x36,0xf7,0xc9,0x7c,0x59,0xa1,0xf5, + 0xd6,0xda,0xbc,0x3b,0xfc,0x65,0x9b,0xf7,0x84,0xc4,0xe1,0x3f,0xd6,0x18,0xdc,0xc3, + 0x9c,0x1a,0x72,0x2f,0x0b,0xce,0xd6,0xaf,0xfb,0x42,0xe2,0xcf,0xda,0xfa,0x1e,0x12, + 0xc3,0x1a,0x37,0x57,0xd8,0xfd,0x21,0xf1,0x89,0x5a,0x57,0x61,0x7f,0x7a,0x28,0x5c, + 0xfd,0x79,0x28,0x6c,0x1e,0xaf,0xc7,0xc3,0x3c,0x5e,0xe0,0x1e,0xce,0x0a,0x30,0xf4, + 0xf1,0xe1,0x30,0xf7,0xf3,0x51,0xf9,0xe9,0x63,0xf3,0x58,0x48,0xdc,0x62,0x63,0x7a, + 0xf8,0xb5,0xd8,0x3c,0x11,0xb2,0x4d,0xc4,0xeb,0x31,0xd9,0x47,0xbb,0xe7,0xc7,0x79, + 0xbb,0x90,0x79,0x12,0x6d,0x49,0x1f,0xc7,0x87,0x67,0x3b,0x78,0xec,0xc9,0x67,0x29, + 0x66,0x16,0xb7,0xa2,0xdb,0x87,0xd7,0xae,0x61,0x43,0xee,0x89,0xa7,0xd7,0xe6,0x14, + 0xaf,0x55,0x9e,0x0a,0x89,0x5b,0x19,0x9d,0xc9,0x02,0x7f,0x3a,0xe4,0x7d,0xb9,0xa7, + 0x74,0x0e,0x02,0x7b,0x26,0x64,0x1b,0xe0,0x46,0xe8,0xde,0xdf,0xec,0x90,0x38,0xfa, + 0x8e,0xfa,0xdc,0x90,0x58,0x43,0x95,0xed,0x02,0x9b,0x1f,0x12,0xe7,0x75,0x57,0x43, + 0xad,0x3f,0xf0,0x1d,0x7d,0x78,0x31,0xf3,0x03,0xbe,0xbd,0xa0,0x98,0xe1,0x1e,0xde, + 0x48,0xb7,0xd7,0x79,0x31,0x24,0x67,0xf5,0x97,0x25,0xf7,0x42,0xa6,0x85,0xfa,0x2b, + 0x21,0xb1,0xa1,0xda,0xcf,0x9a,0xbd,0xd7,0x25,0x57,0xa9,0xb3,0xb7,0x20,0x24,0x67, + 0xfa,0x0b,0xa5,0x7f,0x41,0x9d,0xfe,0x7f,0xa4,0x7f,0x5b,0xa1,0xb9,0xfe,0x3b,0x21, + 0x39,0xd3,0x5f,0x22,0xfd,0x61,0xd2,0xb7,0x3d,0xd3,0x07,0x21,0x7d,0x87,0x7f,0x86, + 0x2d,0x0d,0xd9,0xfe,0x42,0x87,0x7d,0x1a,0xd2,0xe6,0x92,0x30,0x9f,0x87,0xcb,0x43, + 0xea,0xdf,0xaf,0xb9,0xb3,0x22,0x24,0xd6,0x59,0x7b,0xa4,0xf3,0xdc,0x7c,0x00,0xb7, + 0x12,0xb9,0x35,0x62,0x4c,0x57,0xba,0x98,0xfe,0x57,0x7d,0x18,0x5a,0x68,0xbe,0x7f, + 0xfc,0x22,0x24,0x67,0x72,0x5f,0xbb,0xd8,0x7b,0xb9,0x6f,0x42,0x72,0xff,0x92,0xaf, + 0xab,0x42,0x62,0x63,0x94,0xa7,0x80,0x7d,0x1b,0xd2,0xde,0x2a,0x67,0x6f,0xb5,0xec, + 0x9d,0xad,0xeb,0x05,0xb3,0xf7,0x43,0x48,0xce,0xe4,0xd6,0x48,0xee,0x82,0x3a,0xb9, + 0xb5,0x21,0x39,0x93,0x2b,0x46,0x94,0x9b,0x50,0x27,0xd7,0x10,0x91,0x33,0xb9,0xb2, + 0xe4,0x86,0xd5,0xc9,0x05,0x11,0x39,0x93,0x8b,0x25,0x37,0xbc,0x4e,0x2e,0x89,0xc8, + 0x99,0x5c,0x55,0x72,0x76,0xff,0xc0,0xf2,0xf5,0x06,0x11,0xb9,0x89,0x2e,0x5f,0x6f, + 0x14,0x11,0x47,0x1e,0x42,0x3e,0xc3,0xf5,0x38,0xee,0xff,0x5a,0x9e,0xda,0x24,0xe2, + 0x35,0x3a,0xe4,0x2c,0x4f,0x6d,0x1a,0x11,0xb7,0x9c,0xb7,0x79,0xc4,0x73,0xd7,0xef, + 0xd9,0xb7,0x8c,0x78,0x2f,0x02,0xd7,0x1e,0x76,0x4d,0xb0,0x55,0x44,0x59,0x70,0x96, + 0x73,0xb6,0x8e,0x88,0x2f,0x76,0xfd,0x69,0x15,0x11,0x37,0xbd,0x6d,0xa5,0x07,0x5b, + 0xa6,0xd7,0x36,0x22,0xde,0xe4,0xf4,0xb6,0x8b,0x88,0xdb,0x18,0xb7,0x8f,0x68,0x0b, + 0x38,0xe6,0x5f,0xa7,0x28,0x9f,0x7f,0xc8,0xe7,0x3b,0x66,0xf5,0x4e,0x9a,0x7f,0x38, + 0xb6,0x9c,0xd7,0x31,0xa2,0xee,0x18,0xe5,0x3c,0x93,0xe9,0x14,0xe5,0x39,0x6f,0xb3, + 0x2a,0xd7,0x04,0xcc,0x5b,0xc8,0x7b,0xfd,0xce,0xd2,0x9f,0xa6,0xfc,0xdb,0xc7,0xb5, + 0x0b,0x6e,0xe7,0xac,0xec,0x2e,0x9b,0x38,0xee,0xaf,0xfb,0x32,0xbb,0x45,0x9c,0x97, + 0x98,0x6f,0x6b,0xc3,0x3c,0x0f,0x75,0x8b,0xc8,0x59,0x1e,0xea,0x23,0x5d,0xd8,0x18, + 0xad,0xbe,0xfe,0x5a,0xfe,0xb6,0x77,0xf6,0xba,0x47,0x9c,0x6b,0x98,0x47,0x49,0x94, + 0xdb,0xeb,0x11,0x91,0x2b,0x56,0xf3,0x6b,0xb1,0x9e,0x11,0x6d,0x6c,0xea,0xf4,0x7b, + 0x45,0xc4,0xad,0x8c,0x92,0xfe,0x7e,0x11,0x6d,0x80,0xaf,0x64,0x39,0x1c,0x58,0xef, + 0x88,0x39,0x7b,0x67,0xf1,0x78,0x0e,0x80,0x7b,0xfe,0xde,0xdf,0x3e,0x8a,0x1f,0xe4, + 0xbb,0x54,0xd9,0x2f,0xf4,0xbf,0xb7,0xe2,0x01,0xd9,0xf3,0x94,0x63,0x91,0x17,0x2c, + 0xaf,0x1c,0x12,0x31,0x07,0x59,0x5e,0x39,0x34,0x22,0x66,0x79,0xe5,0x5c,0x97,0x57, + 0xc0,0x1d,0x86,0xf9,0xa5,0x36,0x0f,0x73,0xe7,0xc5,0x11,0x51,0x9e,0x2f,0xfc,0xf9, + 0x73,0x64,0x44,0xce,0xe4,0xfe,0x27,0xca,0xf3,0xcf,0x20,0x27,0x77,0x74,0x44,0xce, + 0xf2,0xca,0x31,0x11,0x31,0x9c,0x4f,0x36,0x57,0x8f,0x93,0xee,0x0a,0xb7,0xfe,0xff, + 0x2e,0x22,0xee,0xe7,0xea,0xef,0x23,0xe2,0x36,0x57,0x8f,0x8f,0x68,0xef,0xf7,0xce, + 0x8f,0x3f,0xc8,0xd6,0xaa,0x3a,0x3f,0x4e,0x8c,0xc8,0x59,0x9b,0x27,0x49,0x6e,0xac, + 0x6b,0xf3,0xe4,0x88,0x38,0xf6,0x75,0xa6,0x77,0x4a,0x44,0xdc,0xda,0x6c,0x8a,0x68, + 0xeb,0x14,0xd7,0xe6,0xd0,0x28,0x5f,0x3f,0x7c,0x8c,0x86,0x45,0xe4,0x4c,0xee,0x0c, + 0xc9,0x4d,0xaa,0x93,0x3b,0x33,0x22,0x67,0x72,0xc3,0x25,0x37,0xa8,0x4e,0xee,0x9c, + 0x88,0x9c,0xf9,0x7b,0x9e,0xe4,0x3e,0x77,0xeb,0xfe,0x08,0xe5,0x85,0x7b,0xc2,0xfc, + 0x5e,0xc3,0xc8,0x88,0xb2,0x23,0xa2,0x7c,0xee,0x5e,0x1c,0x71,0x0c,0x97,0x16,0x73, + 0xec,0x92,0x88,0x31,0xc5,0xf3,0x24,0xcb,0x49,0xa3,0x23,0xca,0x5e,0x12,0xe5,0xd8, + 0x98,0x88,0x78,0x93,0xb3,0x77,0x79,0xc4,0xfe,0x7a,0x7b,0x57,0x44,0xec,0x9b,0xb7, + 0x77,0x65,0x44,0xd9,0x2b,0x9c,0xbd,0xab,0x22,0xe2,0xe8,0xdf,0x83,0x9a,0xaf,0x7f, + 0x8d,0xd8,0x0e,0xb8,0xa9,0x8a,0xcb,0xd5,0x11,0xf1,0x26,0x3d,0xa3,0xb4,0xfe,0x5d, + 0x1b,0xb1,0x8f,0xe0,0x91,0x8f,0xaf,0xaa,0xcb,0xc7,0x7f,0x8b,0x78,0x8f,0xf4,0x5a, + 0x97,0x8f,0xaf,0x8f,0x88,0x5b,0x3e,0x1e,0xbb,0x9e,0x7c,0x7c,0xd3,0x7a,0xf2,0xf1, + 0xcd,0x11,0x65,0x6f,0x72,0xe3,0x30,0x2e,0x22,0xee,0xf3,0xf1,0xf8,0x88,0xb8,0xe9, + 0x4d,0x92,0x9e,0xcf,0xc7,0xb7,0x46,0xc4,0xfd,0x1c,0x9f,0x1c,0x11,0xc7,0x39,0x7a, + 0x77,0x5d,0xee,0xbd,0x1d,0xe3,0xad,0x73,0xf4,0x76,0x17,0xbf,0xbb,0x22,0xb6,0x37, + 0xd9,0xe5,0xd3,0x29,0x11,0x71,0xcb,0xc7,0xa6,0x77,0xb7,0xcb,0xc7,0x5b,0x2a,0x1f, + 0xe3,0x7c,0x87,0xfc,0xed,0x51,0xbe,0x1f,0xbe,0x57,0x36,0x2d,0x1f,0x3f,0xe2,0x7c, + 0x01,0x37,0x15,0x7d,0x91,0xcd,0xa9,0x2e,0xff,0x4d,0xd7,0x3c,0x38,0x53,0xe3,0x89, + 0xb6,0x1f,0x91,0xdc,0x03,0x4e,0x6e,0x86,0xe6,0xdf,0xf1,0x9a,0x47,0x5e,0xee,0x11, + 0x97,0xf3,0xe2,0x2a,0x6d,0xa2,0x8d,0x19,0x6a,0xd3,0x72,0xf2,0x13,0x11,0x79,0x9f, + 0x93,0x67,0xaa,0xcf,0x93,0x5d,0x9e,0x9f,0xa5,0x7c,0x33,0xd3,0xcd,0xd7,0xa7,0x22, + 0xe2,0xd7,0x3b,0x9f,0x9e,0x89,0x88,0x5b,0xb1,0xdc,0x3d,0x3b,0x62,0x5b,0xcf,0xb8, + 0xdc,0x3d,0xc7,0xe5,0xee,0xd9,0x75,0xb9,0xfb,0x5c,0xdb,0xf3,0xba,0x7c,0xfc,0x7c, + 0xc4,0xfd,0x9f,0xe5,0xe3,0x17,0x22,0x62,0x96,0x8f,0xff,0xe8,0xf2,0x31,0xb8,0x17, + 0xb3,0x32,0x50,0x76,0x5e,0x74,0xb9,0xe1,0x65,0x9d,0xf3,0x78,0xc6,0x3b,0xce,0xcd, + 0x9b,0x57,0x22,0x72,0xeb,0xf6,0xc4,0x92,0x5b,0x5d,0x68,0x2e,0xb7,0x20,0x22,0x67, + 0xf3,0xf2,0x2d,0xc9,0xe1,0x79,0xab,0xc9,0x2c,0x8c,0x88,0xdb,0x35,0xd5,0xdb,0x11, + 0xb1,0xc1,0xc5,0x3c,0x0f,0xfe,0x3b,0xa2,0xad,0xb7,0x5d,0x9b,0x8b,0x5c,0x7e,0xf3, + 0xb9,0x77,0x71,0x44,0xce,0xe4,0xde,0x73,0xf9,0xd2,0xef,0x41,0xdf,0x8f,0xc8,0xd9, + 0x5a,0xf1,0x41,0x44,0x6c,0x90,0xdb,0x83,0x7e,0x18,0xd1,0xde,0x07,0xae,0x0f,0x1f, + 0x3b,0x7b,0x66,0xeb,0x93,0x88,0xb8,0xf5,0xe1,0xd3,0x88,0xd8,0x89,0xae,0x0f,0xcb, + 0x22,0xda,0xfb,0x34,0xca,0xf5,0x3e,0xd3,0xbe,0xce,0x7c,0xfd,0xc2,0xed,0x0b,0xfd, + 0xb5,0xc1,0x97,0x11,0x39,0xf3,0xf5,0xab,0x88,0xd8,0x44,0xe7,0xeb,0xd7,0x11,0xed, + 0x7d,0xe5,0xf2,0xcc,0x2a,0x97,0x67,0xac,0x8d,0x6f,0x23,0xe2,0xa7,0xd7,0x8d,0xe9, + 0x77,0x11,0x39,0x93,0xfb,0x41,0x72,0x18,0xfb,0x49,0x4e,0xee,0xc7,0x88,0x9c,0xc9, + 0xad,0x95,0x9c,0xbd,0xc7,0x63,0x72,0x3f,0x47,0xe4,0x4c,0xae,0x21,0xa6,0x1c,0xae, + 0x9b,0x7c,0xbb,0xa5,0x98,0x9c,0xc9,0x05,0x92,0x9b,0x56,0x37,0x97,0xc2,0x98,0x9c, + 0xc5,0x20,0x8e,0x39,0x0f,0xfd,0xb5,0x77,0x2a,0x6c,0xb8,0x8b,0x4b,0x25,0xa6,0x6c, + 0xea,0x74,0x37,0x88,0x19,0x2f,0xaf,0xdb,0x52,0x98,0xd7,0xdd,0x30,0xa6,0x6c,0x4b, + 0xa7,0xbb,0x71,0xcc,0x58,0x79,0xdd,0x4d,0x85,0x79,0xdd,0xcd,0x62,0xca,0x6e,0xea, + 0x74,0xb7,0x88,0x39,0x97,0x27,0x3a,0xdd,0xad,0x84,0x8d,0x73,0xba,0x5b,0xc7,0x94, + 0xdd,0xca,0xe9,0x6e,0x13,0x33,0xf6,0x5e,0xb7,0x8d,0x30,0xaf,0xbb,0x6d,0x4c,0xd9, + 0x36,0x4e,0x77,0xbb,0x98,0xe3,0xe1,0x75,0xb7,0x17,0xe6,0x75,0xdb,0xc7,0x94,0xdd, + 0xde,0xe9,0xee,0x18,0x73,0xee,0xfa,0xfe,0x76,0x14,0xe6,0xfb,0xdb,0x29,0xa6,0x6c, + 0x47,0xa7,0xdb,0x39,0xe6,0xf8,0x7a,0xdd,0x5d,0x84,0x79,0xdd,0x5d,0x63,0xca,0xee, + 0xe2,0x74,0x77,0x8b,0x39,0xe6,0x5e,0xb7,0xab,0x30,0xaf,0xdb,0x2d,0xa6,0x2c,0x38, + 0xcb,0xad,0x7b,0xc6,0x1c,0x77,0xc4,0xb1,0x93,0xc3,0xf7,0x8e,0x39,0xa6,0x88,0x11, + 0xda,0x1c,0xad,0x9c,0xbb,0x4f,0x4c,0x6e,0x4f,0x27,0xbb,0x5f,0xcc,0x31,0x44,0x4c, + 0xba,0x39,0xd9,0xde,0x31,0x39,0xc8,0xda,0x9a,0x7f,0x40,0xcc,0x7b,0x45,0x4b,0xdc, + 0xb3,0x8e,0x03,0x63,0xe2,0x66,0xef,0xe0,0x98,0x98,0x15,0x5b,0x57,0xfa,0xc4,0x6c, + 0xff,0x60,0x67,0xaf,0xaf,0xec,0x35,0x39,0x7b,0xfd,0x62,0xe2,0x66,0xef,0xd0,0x98, + 0x98,0x15,0xb3,0x77,0x58,0x4c,0x1f,0xc1,0xdb,0x9a,0x72,0x64,0xcc,0x76,0x0e,0x73, + 0xd8,0x6f,0x63,0xe2,0x78,0x96,0x3d,0x57,0xd8,0xd1,0x31,0x71,0x60,0x26,0x77,0x8c, + 0xfa,0x0a,0xce,0xd6,0xa3,0x01,0x71,0xbe,0x1e,0x81,0xf7,0xeb,0xd1,0x1f,0xb5,0x8e, + 0x0c,0x74,0xbe,0x0e,0x8e,0x79,0xcf,0x62,0x81,0xee,0x49,0xd8,0x39,0x7d,0x72,0x9c, + 0xdf,0x33,0x82,0xdc,0xa9,0x31,0xef,0x6b,0x2c,0xd4,0x7d,0x0b,0xc3,0x87,0xc6,0x94, + 0xb5,0x62,0x7d,0x1d,0x16,0x93,0x3b,0xd5,0xf5,0xeb,0xb4,0x98,0xed,0x0d,0xd3,0x5c, + 0x02,0x76,0x66,0x4c,0x1c,0xcf,0xf3,0xad,0xaf,0xc3,0x85,0xa1,0xaf,0xf3,0x84,0x9d, + 0x13,0x53,0x16,0x9c,0xef,0x0b,0x7e,0x6d,0x8f,0xd0,0xad,0xca,0xfe,0x63,0x9d,0xc4, + 0x73,0xf7,0x81,0x8e,0xeb,0x50,0x25,0x06,0x0e,0xb6,0xc0,0x61,0x3f,0x89,0x35,0xf8, + 0x93,0x2a,0xd7,0xe1,0xd7,0x74,0xaf,0xd2,0xf0,0x4f,0x1d,0xfe,0x51,0xa1,0xf9,0x9a, + 0x7e,0xae,0xb3,0xdd,0xb5,0xca,0x7d,0x00,0xf6,0x2b,0xf0,0xc1,0xfb,0xd4,0x5e,0xed, + 0x82,0xeb,0xe0,0xb8,0xda,0x3b,0xbb,0x55,0xee,0xbd,0xc0,0x7d,0x52,0xc7,0xb5,0xa8, + 0xb2,0x5d,0x70,0x9f,0x8a,0xf3,0xd7,0x78,0xe7,0xb9,0x36,0x76,0xab,0xf2,0x9a,0x10, + 0xd7,0x88,0xf0,0xc5,0xfb,0xd6,0x5a,0xed,0x83,0x6b,0xef,0x38,0xb4,0xb1,0x49,0x95, + 0xd7,0xe2,0xe0,0x36,0xaf,0xe3,0x52,0xb5,0x0f,0xae,0x85,0x38,0x7f,0x1f,0xef,0x7c, + 0xd7,0xc6,0xce,0x6a,0x03,0xf7,0x25,0xe1,0x8b,0xf7,0x6d,0x9b,0x2a,0xef,0x05,0x82, + 0x6b,0xed,0x38,0xb4,0xb1,0xb1,0xf6,0x9d,0xe0,0x36,0xa9,0xe3,0x92,0x2a,0x63,0x0e, + 0x2e,0x15,0x87,0xfd,0xd1,0x34,0xb7,0x3f,0x82,0xcc,0xff,0x66,0xf5,0x69,0xf2,0xa9, + 0x76,0xac,0x7d,0xd5,0x48,0xcd,0xdf,0x25,0x05,0x8e,0x27,0xd4,0x2e,0x8a,0x89,0x4f, + 0xd4,0xfb,0x75,0xeb,0xae,0x81,0x62,0xee,0x2d,0x2e,0x8a,0xf3,0xbd,0xe2,0xa8,0x98, + 0xeb,0xfc,0xc5,0x6e,0xfd,0xbb,0x24,0xe6,0x1e,0x60,0x94,0xe4,0x6d,0x2d,0xbf,0x34, + 0xfe,0xe5,0x35,0xc3,0x65,0xf1,0x2f,0xaf,0x19,0x2e,0x8f,0x29,0x0b,0xce,0xf6,0xfe, + 0x7f,0x8e,0x89,0xfb,0x6b,0x86,0x2b,0x62,0xe2,0xa6,0xf7,0x57,0xe9,0xf9,0x6b,0x86, + 0xab,0x63,0xe2,0xfe,0x9a,0xe1,0x9a,0x98,0xb8,0xf5,0xe1,0x3a,0xf5,0xf5,0x0a,0xc5, + 0x6e,0x82,0x8b,0x1d,0x62,0x7f,0x7d,0x56,0x9f,0xa0,0xd8,0x5d,0x1f,0xe7,0xf1,0xb8, + 0x31,0xa6,0xee,0x35,0x71,0xde,0x9f,0x71,0x31,0xed,0x00,0xb3,0x6b,0x8b,0xf1,0x31, + 0x71,0xbb,0xb6,0x30,0x5b,0x13,0xdc,0x38,0x76,0xaa,0x72,0x9c,0x31,0x36,0x90,0xbf, + 0x5e,0x5c,0x6d,0x2d,0xad,0xb2,0x1d,0x70,0x37,0x8a,0xc3,0x75,0x1b,0xde,0x5b,0xc1, + 0xbb,0x75,0xbd,0xb2,0x9e,0x22,0xe7,0x4e,0x8a,0xf9,0x2e,0xcb,0x25,0x6a,0xdf,0xf2, + 0xee,0xad,0x31,0x39,0xf3,0xfb,0xb6,0x98,0x18,0xec,0x5a,0x7e,0xba,0x33,0x26,0x6e, + 0xc5,0x72,0xd1,0x5d,0x31,0xe7,0xe6,0x9d,0x2e,0x77,0x4e,0x71,0xb9,0xf3,0xae,0xba, + 0xdc,0x69,0x73,0x6c,0x9a,0x9b,0xdb,0x9d,0xab,0x9c,0xfb,0x38,0x17,0xa6,0x28,0x96, + 0xd6,0xef,0x8e,0xea,0x37,0x38,0xc4,0x00,0xdc,0x3d,0xf6,0x8c,0x21,0xe6,0xf3,0x90, + 0x8e,0xba,0x27,0x35,0x43,0xb6,0x67,0xc4,0xf9,0x5c,0x5d,0x56,0xa5,0xdc,0x34,0xbd, + 0xf3,0x89,0xfe,0xe0,0x5d,0xb2,0xe5,0xc2,0xad,0x4c,0x55,0x3f,0x57,0x54,0xc9,0xc1, + 0x67,0xf8,0x65,0xef,0x04,0x3c,0x1a,0x93,0x2b,0x14,0x72,0xec,0x71,0x61,0x45,0x87, + 0x3d,0x29,0xac,0xa1,0xf6,0xae,0x32,0xdf,0xd1,0xf8,0xb1,0xcc,0x67,0x13,0x98,0x3b, + 0x6b,0xdc,0x73,0x23,0xe0,0x3f,0x65,0x65,0x8d,0x9e,0xf5,0xe0,0x78,0xba,0xfa,0x86, + 0xc9,0x09,0xdf,0xa7,0x69,0x4e,0x98,0xcc,0x1a,0xf7,0x3c,0xa8,0x18,0xd0,0xee,0x0c, + 0xbd,0x80,0xfc,0x93,0xde,0x03,0x69,0x0c,0xf2,0x36,0x20,0x53,0xca,0x4a,0xa3,0xde, + 0xfb,0x28,0x05,0xf9,0x35,0x54,0x18,0xb0,0x5f,0x56,0x4f,0x02,0xf6,0xc9,0xea,0xd5, + 0x80,0xfd,0xb1,0xe7,0x1d,0x1b,0x04,0xd4,0x81,0x1c,0x38,0xb4,0xf5,0x79,0xdc,0xfc, + 0x39,0xd8,0x2b,0x59,0xfd,0x43,0x8d,0x03,0x8e,0x8f,0x2f,0x72,0x8e,0xbe,0x1a,0xe7, + 0xef,0x56,0x4e,0xd4,0xf7,0x04,0xe0,0x60,0xf7,0x75,0xc7,0xa1,0x8d,0xb1,0xca,0x29, + 0xe0,0xde,0x88,0xc9,0xe3,0xbd,0x30,0xf3,0xeb,0xad,0x98,0xf6,0xcc,0xaf,0x85,0x31, + 0x31,0x2b,0xa3,0xa4,0xfb,0x76,0x4c,0xfd,0x85,0x6e,0x6e,0xff,0x47,0xe7,0xd9,0xab, + 0xae,0x9f,0xef,0xc4,0xc4,0xcd,0xde,0xa2,0x98,0x98,0x95,0xcb,0x65,0x6f,0x71,0x4c, + 0x9b,0x8b,0xe2,0xfc,0x19,0xce,0xbb,0x31,0x71,0xab,0xbf,0x17,0xb3,0x0f,0xb6,0x97, + 0xfa,0x20,0x26,0xf6,0xae,0xf2,0xfe,0xe7,0x8a,0xcd,0x87,0x4e,0x67,0xa9,0x74,0x2c, + 0x1e,0x9f,0xac,0x27,0x1e,0xd6,0xa7,0x65,0x31,0x79,0xbc,0x57,0x67,0xcf,0x96,0x56, + 0xc4,0xc4,0x1b,0xab,0xb9,0xcd,0x95,0x31,0x71,0xf3,0xe3,0xb3,0x98,0xed,0xac,0xac, + 0xf3,0xe3,0x73,0x77,0x1e,0xee,0x5f,0xa5,0xbf,0x18,0xb7,0xcf,0x34,0x8e,0x36,0xaf, + 0xbf,0x88,0xc9,0x17,0x0a,0x79,0x4e,0xf8,0x2a,0x26,0x6e,0xc5,0xf6,0x2c,0x5f,0xc7, + 0xe4,0x20,0x8f,0x3e,0x01,0xfb,0xc6,0xf5,0x09,0x3c,0xfa,0x74,0xa6,0xbe,0x9f,0x59, + 0x15,0x93,0x3f,0x5c,0xf9,0xe3,0x3b,0xe9,0xee,0xef,0x9e,0xc5,0xe1,0x7c,0x32,0x7e, + 0x75,0x1d,0xdf,0xa0,0x62,0xed,0xff,0x10,0xd3,0xc6,0xea,0x38,0x6f,0xff,0x47,0xd7, + 0xfe,0x0f,0x75,0xed,0xff,0x14,0x93,0x3f,0x59,0xf1,0x5f,0xbb,0x9e,0xf8,0x0f,0x12, + 0x87,0x44,0x5a,0xcf,0xd9,0x73,0xbf,0x62,0x42,0x5d,0xc8,0x9c,0x25,0xdb,0x0d,0x09, + 0x71,0xc4,0x11,0xef,0xba,0x96,0x13,0xf6,0xd7,0x72,0x06,0xb0,0x28,0xa1,0x0f,0x05, + 0x87,0xc5,0xc2,0xbc,0x5c,0x45,0xba,0x0d,0x0e,0x6b,0x29,0xb9,0x06,0x8d,0x0b,0xda, + 0x6c,0x95,0xb0,0x1d,0xd8,0x85,0x1d,0xc3,0xb7,0x49,0x68,0x03,0x58,0x4b,0xe1,0x78, + 0x8f,0xb8,0xb5,0xec,0x42,0x0f,0x32,0x98,0x1f,0x6d,0x12,0xce,0x0f,0xfc,0x62,0x7e, + 0x40,0xff,0xc0,0x2a,0xfb,0x83,0x39,0xf3,0x3e,0xee,0x9d,0x8b,0x83,0x1f,0x07,0x54, + 0xf9,0x7e,0x33,0xb8,0x4e,0x49,0xce,0xa1,0x5b,0xbd,0x95,0xc7,0xc0,0xed,0x21,0xee, + 0x61,0xe5,0xb9,0xed,0x12,0xf2,0xb8,0xde,0xf9,0x36,0x8b,0xd9,0xaf,0xc5,0x5b,0x4e, + 0x01,0xdf,0x2e,0x2b,0xbf,0x96,0x3f,0x38,0xfe,0x5b,0xa6,0x0b,0x7f,0x76,0x48,0xe8, + 0x3b,0xfc,0x1a,0xab,0x78,0x74,0x4c,0x88,0xa3,0x54,0xb2,0xfe,0x01,0x83,0x3f,0x45, + 0x7d,0xf3,0x04,0x7e,0x96,0x3d,0x23,0x49,0xc8,0xc1,0x6f,0xe4,0xb2,0xae,0xae,0x5d, + 0x70,0x3b,0x67,0xa5,0xab,0xda,0xc5,0xf1,0x15,0x6a,0x63,0xd7,0x84,0xef,0x6e,0x43, + 0xf7,0x1a,0xf9,0xd2,0x45,0x6d,0xee,0xaa,0xf8,0x99,0x5e,0x57,0x17,0x3f,0xc4,0x6c, + 0x07,0xf5,0xa7,0x8b,0xec,0x43,0xb6,0x9b,0x64,0xf1,0x6b,0xfb,0x84,0x3d,0x14,0x97, + 0x89,0x85,0xe6,0xe3,0x81,0x38,0x3c,0x29,0xff,0x7f,0x93,0x30,0xee,0x78,0xef,0x1b, + 0xfe,0xf7,0x73,0xfe,0x83,0xdb,0x2b,0x2b,0xdd,0xa5,0xb7,0x97,0xda,0xea,0xa7,0x7a, + 0x77,0x37,0x27,0x7b,0x28,0x86,0x85,0x42,0x1e,0xb3,0x7d,0x14,0xb3,0x46,0xf1,0x26, + 0xdb,0x53,0xb2,0x45,0x27,0xdb,0xcb,0xc9,0xf6,0xac,0xc5,0x9d,0x73,0x62,0x3f,0xe1, + 0x66,0xaf,0x97,0xb3,0xd3,0x5b,0x76,0x1a,0x9c,0x9d,0x03,0x9c,0x9d,0xde,0xce,0xce, + 0x81,0xce,0x0e,0x6c,0x1e,0xe0,0xc6,0xe2,0xe0,0x84,0xef,0xa7,0x1f,0xe8,0xc6,0xa2, + 0xaf,0x6c,0x1f,0x5c,0xd7,0xe7,0x7e,0x6e,0x2c,0x0e,0xaa,0xf2,0x7d,0x77,0xc4,0xa5, + 0xaf,0xe2,0x64,0xe7,0xec,0xa1,0x89,0x9d,0xdb,0x6c,0xe3,0xf0,0x84,0x18,0x74,0x06, + 0x17,0xe9,0xd3,0x11,0x2e,0x0f,0x80,0x47,0x1e,0x38,0x45,0xdc,0x51,0xeb,0xe1,0x1e, + 0xd5,0x98,0x1d,0x9d,0x10,0x83,0xbe,0xbd,0xd7,0x87,0xef,0x20,0xf1,0x4e,0xbd,0xdd, + 0x97,0x3f,0x36,0xa1,0x1c,0xf0,0x25,0x4e,0xf7,0x77,0xd2,0x85,0x7d,0x93,0x3d,0x3e, + 0x21,0x6e,0xb2,0xf6,0xbe,0xcb,0x09,0x09,0xed,0x80,0x47,0x5e,0x03,0xf6,0x07,0xe7, + 0xd7,0x09,0xf2,0xcb,0xf6,0xde,0x83,0x13,0xf2,0xf8,0x1b,0x50,0xe4,0x3a,0x78,0x92, + 0xe4,0x11,0x8b,0xc1,0x49,0x2e,0xdb,0x24,0xd9,0xa2,0x93,0x1d,0xe2,0x64,0x9b,0x5c, + 0x2c,0x3f,0x48,0x68,0xe7,0x32,0x8d,0xcd,0x87,0x09,0x31,0xbc,0xe3,0x5f,0x51,0x5e, + 0xfa,0x28,0xc9,0xf3,0x3c,0xf8,0xd3,0xf5,0x9e,0xf4,0xd2,0x84,0x9c,0xd9,0x5a,0x96, + 0xb0,0x1d,0xb3,0xb5,0x3c,0x21,0xe6,0x6d,0xad,0x70,0xb6,0x96,0x3b,0x5b,0x2b,0x13, + 0x72,0xd8,0x73,0x63,0xff,0x77,0x61,0x42,0xfb,0xc0,0x6f,0xd1,0x3e,0xed,0x4f,0x09, + 0x71,0x9c,0x4b,0x8b,0xdc,0xb9,0x04,0x7c,0x44,0x56,0x16,0x69,0x1e,0x8d,0x70,0xb1, + 0xf8,0x42,0x76,0xfc,0x3b,0x53,0x5f,0x26,0xc4,0x07,0xb9,0x67,0x72,0xdf,0x08,0x1b, + 0xe3,0x9e,0x7b,0xaf,0x4a,0x28,0xfb,0x8d,0xb3,0xf7,0x9d,0xec,0xf9,0x77,0xab,0xbe, + 0x4f,0x88,0x8f,0x71,0xf6,0x7e,0x14,0x36,0xdc,0xd9,0xfb,0x29,0xa1,0xec,0x8f,0xce, + 0xde,0x5a,0xd9,0xf3,0xef,0x5b,0xfd,0x9c,0x10,0xf7,0xfe,0x35,0xa4,0xc4,0xbc,0x7f, + 0xa5,0x94,0xb2,0xe0,0x6c,0x6f,0xd4,0x98,0xd2,0x6f,0xb4,0x05,0xde,0xf6,0x1b,0xa3, + 0x34,0x36,0x56,0x1f,0x9d,0x50,0xd6,0xf6,0x1f,0x97,0x26,0x94,0x19,0xad,0xbc,0x0c, + 0x6c,0x8c,0xfa,0x19,0x8a,0x37,0xdd,0xcb,0x35,0x67,0x4c,0xf7,0xca,0x84,0x98,0xd7, + 0xfd,0x8b,0xd3,0xbd,0x32,0xc9,0xd7,0xfe,0xab,0x13,0xda,0x05,0x3f,0x5d,0x63,0x7d, + 0x4d,0x42,0x1c,0x7b,0x7a,0xc3,0xae,0x93,0x0c,0xb0,0x23,0x74,0x7e,0x5d,0x9f,0x50, + 0xd6,0xd6,0x61,0x60,0x63,0x13,0xca,0x16,0x0a,0xf9,0x75,0xc7,0x8d,0x09,0x65,0xc7, + 0x26,0xf9,0x75,0xc6,0x4d,0x09,0x71,0xbb,0x26,0xb6,0xbd,0xe5,0xcd,0x09,0x39,0x1b, + 0x8f,0xf1,0x9a,0x73,0xfe,0x3d,0xfa,0x09,0x09,0x71,0xc8,0x1e,0xa9,0x38,0x3f,0x5a, + 0x21,0xfe,0x45,0xb5,0xb9,0x3f,0x93,0xe4,0x63,0xd1,0x61,0x93,0xe5,0x63,0xd1,0xf9, + 0x78,0x5b,0x42,0xd9,0xc9,0xce,0xc7,0xdb,0x13,0xe2,0xf5,0x3e,0xde,0x91,0x90,0x33, + 0x1f,0xef,0x92,0x8f,0xfe,0xfd,0xea,0x29,0x09,0xf1,0x3b,0x9c,0x8f,0x33,0x2b,0xc4, + 0x1f,0xad,0x34,0xf7,0xe7,0x5e,0xf9,0xd8,0xe0,0xb0,0xfb,0xe4,0x63,0x83,0xf3,0x71, + 0x5a,0x42,0xd9,0xfb,0x9c,0x8f,0xf7,0x27,0xc4,0xeb,0x7d,0x9c,0x9e,0x90,0x33,0x1f, + 0x1f,0x94,0x8f,0x0d,0xce,0xc7,0x87,0x12,0xe2,0xd3,0x9d,0x8f,0x4f,0x57,0x88,0xc3, + 0xd7,0x06,0x3d,0x7b,0x7b,0xd2,0x9d,0xdb,0x18,0xc7,0x47,0xb1,0xa6,0xea,0xdc,0xc6, + 0xb1,0x5d,0xb7,0x3d,0xa1,0x31,0xc6,0x1a,0x62,0xfc,0x93,0x49,0x7e,0xfd,0x35,0x53, + 0xf3,0x00,0xf9,0xe0,0x09,0xd9,0xb1,0x7e,0xcc,0x4a,0xc8,0xd7,0xf7,0xe3,0xef,0x09, + 0xb9,0xd1,0xf2,0xf9,0x69,0xe5,0x85,0xbf,0x3b,0x9f,0xe7,0x56,0x84,0x6b,0xec,0xe1, + 0xf3,0x7c,0xe7,0x33,0xc6,0x75,0x4e,0x56,0xe6,0xcb,0xa7,0x39,0xce,0xe7,0x79,0x1a, + 0x73,0xf8,0x6c,0xfc,0x7c,0xe7,0xf3,0xb3,0x9a,0x17,0xe8,0xc7,0x3c,0xd9,0x31,0x9f, + 0x9f,0x4b,0xc8,0xd7,0xfb,0xfc,0x7c,0x42,0xce,0x7c,0xfe,0x3f,0xe5,0x9e,0xe7,0x9d, + 0xcf,0xcf,0x55,0x88,0xcf,0xd5,0x5c,0x80,0xcf,0x6f,0x38,0x9f,0x31,0xce,0xaf,0x66, + 0xe5,0x0d,0xf9,0xf4,0xaa,0xf3,0x79,0x81,0xe6,0x00,0x7c,0x36,0xfe,0x0d,0xe7,0xf3, + 0x9b,0x9a,0x27,0xe8,0xc7,0x02,0xd9,0x31,0x9f,0xdf,0x4a,0xc8,0xd7,0xfb,0xbc,0x30, + 0x21,0x67,0x3e,0xff,0x47,0x39,0x6f,0xa1,0xf3,0xf9,0xa5,0x0a,0xf1,0xe7,0x34,0x37, + 0xd0,0xbe,0xe5,0xf8,0x45,0x6a,0x1f,0x72,0x87,0x54,0x39,0xd7,0xb0,0x7f,0xc0,0x7c, + 0x7a,0xc3,0x71,0xfd,0xaa,0xcc,0xaf,0xe0,0x5e,0x12,0x67,0x73,0x34,0x4a,0xc9,0xfb, + 0xb5,0x21,0x4e,0x89,0xdf,0xe6,0xd6,0xde,0x54,0x72,0x3e,0xe7,0x57,0x52,0xe2,0x23, + 0x5d,0x3e,0xae,0xa6,0xd4,0x07,0x67,0xba,0x2d,0xa4,0xdb,0xe0,0xdf,0x5f,0x4f,0x29, + 0xdb,0xc2,0xc9,0x6d,0x92,0xb2,0x1f,0xde,0x97,0x4d,0x53,0xe2,0xde,0x97,0xcd,0x25, + 0xe7,0x7d,0xd9,0x22,0x25,0xee,0x7d,0xd9,0x32,0xa5,0xfe,0x16,0xae,0x8d,0xad,0xa5, + 0xeb,0x7d,0x69,0x95,0x52,0x16,0x9c,0xdd,0x53,0xec,0x14,0xd0,0x47,0x70,0x98,0x27, + 0x9d,0xdd,0xfd,0x0a,0x70,0x3b,0x65,0xa5,0xb3,0xee,0x57,0xe0,0xf8,0x4c,0x7d,0x27, + 0xb8,0xab,0xee,0x57,0x58,0xbd,0x8b,0xee,0x57,0x58,0x7d,0x77,0x77,0xbf,0x02,0x7b, + 0x81,0x3d,0x02,0xea,0x40,0x0e,0x9c,0xf5,0xa7,0xad,0xc6,0xc0,0xaf,0x7f,0xdb,0x0b, + 0xf3,0xeb,0x5f,0xfb,0x94,0xb2,0xe0,0x4c,0xb7,0x83,0xc6,0xc5,0xaf,0xc5,0x3b,0x09, + 0xf3,0x6b,0x71,0xe7,0x94,0xb2,0x3b,0x39,0xdd,0x5d,0x35,0x26,0xbe,0xdd,0x2e,0xc2, + 0x7c,0xbb,0x5d,0x53,0xca,0x76,0x71,0xeb,0x6e,0xb7,0x94,0xfe,0xc0,0x2e,0x78,0xdb, + 0x13,0xed,0x15,0x90,0xb3,0x36,0x7e,0xa3,0x31,0xf5,0x6d,0xec,0x2d,0xcc,0xb7,0xd1, + 0x23,0xa5,0xec,0xde,0x4e,0xb7,0xa7,0xc6,0xd9,0xf7,0x6d,0x7f,0x61,0xbe,0x6f,0xbd, + 0x53,0xca,0xee,0xef,0x74,0x0f,0xd2,0x18,0xfb,0x76,0xfb,0x0a,0xf3,0xed,0xf6,0x4b, + 0x29,0xdb,0xd7,0xf5,0xed,0x90,0x94,0xfe,0xc0,0x6e,0x3f,0xd7,0xb7,0x7d,0x02,0x72, + 0x97,0x6a,0xbf,0x77,0x74,0x4a,0x6c,0x2f,0xb7,0x37,0x1f,0x90,0xb2,0x0e,0xce,0xb0, + 0xdf,0x4b,0xce,0x63,0x03,0x53,0xce,0x87,0xa3,0x65,0x0f,0xd8,0xa0,0x94,0xf8,0x00, + 0x87,0x9d,0x9c,0x52,0x1f,0x98,0x5d,0x63,0x9c,0x92,0x52,0x16,0x1c,0xee,0x71,0x02, + 0x6b,0x4a,0xed,0x1b,0x58,0xf2,0xb8,0x86,0xc4,0x35,0xe1,0x54,0x5d,0xcb,0x9c,0x9a, + 0xf2,0x9e,0x3c,0xbe,0xe9,0xc5,0x77,0xbc,0x97,0xc9,0xd6,0xd0,0x94,0xba,0xa7,0xa6, + 0xf9,0x75,0xcf,0xb0,0x34,0xdf,0xb3,0x82,0x3f,0x43,0xf7,0x65,0x4f,0x4b,0xc9,0xd9, + 0x5e,0xff,0x0c,0xd9,0xc4,0xbb,0xf8,0xcf,0x97,0xf2,0x7b,0x5a,0x67,0xa5,0x94,0x1d, + 0xe3,0x9e,0x81,0x9f,0x9d,0x52,0xfe,0xac,0x34,0xbf,0xaf,0x6c,0xe7,0x14,0x7e,0x91, + 0xbf,0x6a,0xef,0xf2,0x57,0x79,0xdd,0x80,0x7c,0x07,0x1d,0x9c,0x6f,0x0f,0xe9,0x3c, + 0x3d,0x38,0xe0,0x39,0xda,0x52,0xe7,0x69,0x3f,0x77,0x9e,0x82,0xeb,0x9b,0x95,0x7e, + 0xb2,0x89,0xe3,0xf9,0x1a,0xe3,0x43,0x03,0xda,0x6d,0x72,0xef,0x70,0xf7,0x0f,0x88, + 0xe3,0x1a,0xc1,0xd6,0xff,0x23,0x02,0xf6,0x07,0x1c,0xfc,0x3b,0x4a,0xb6,0xf0,0x6b, + 0x7d,0x5e,0x59,0xa5,0xdc,0x62,0xd9,0xad,0x5d,0xcf,0x49,0xae,0x9f,0xeb,0xc7,0x65, + 0x55,0xb6,0x89,0xbe,0x41,0x07,0x36,0xa6,0xd8,0x35,0x57,0xc0,0xbe,0x7c,0xac,0x6f, + 0xe0,0x8e,0x95,0xfe,0xb1,0xae,0x9d,0xcf,0xaa,0x94,0xb3,0xfe,0x1a,0xfe,0xb9,0x70, + 0xcb,0x57,0xeb,0xbe,0x3b,0x08,0xa8,0x73,0x81,0xff,0xee,0x20,0xa0,0xfc,0x20,0xf9, + 0x69,0xf7,0x5c,0x1b,0x9d,0x9f,0x97,0x2a,0xde,0xb8,0x8f,0x0b,0x9f,0x8f,0x75,0xdc, + 0x50,0xc7,0xc1,0xd6,0xb1,0xba,0xc7,0x3a,0x24,0x68,0x7e,0x8f,0xb5,0x29,0xab,0x0f, + 0x91,0xed,0x26,0xc9,0x9c,0x5e,0x77,0xcf,0xf7,0xb4,0xac,0x9c,0x25,0x99,0xd3,0x82, + 0xfc,0x5a,0x13,0xff,0xbb,0x07,0xd7,0x9a,0xeb,0xde,0x95,0x0b,0x88,0xc1,0xdf,0xd3, + 0x25,0x7f,0x56,0x5d,0xfd,0xf4,0x20,0xbf,0x97,0x33,0xa4,0x4a,0x1d,0xd8,0x3c,0x5b, + 0x6d,0x9c,0xa4,0x7b,0xbc,0xe7,0x04,0xf9,0xf5,0xe5,0x90,0x2a,0xaf,0x2f,0x2d,0xe7, + 0x9f,0x1b,0x90,0x3f,0x5b,0xfe,0x9e,0xef,0xfc,0x05,0x77,0x5e,0x56,0xce,0x57,0x7b, + 0xe7,0xb9,0x7b,0xd4,0x17,0x4a,0x0f,0xd7,0x99,0xa8,0xff,0x49,0x6d,0x20,0x56,0x17, + 0xca,0x4f,0xd3,0x3b,0xdf,0xc5,0xf2,0x9a,0x2a,0x65,0xe0,0xfb,0x9f,0x64,0x1f,0xed, + 0x5e,0xe4,0xda,0xc5,0x73,0x83,0x91,0x59,0xfd,0x22,0xe9,0xe3,0xd8,0xe6,0xeb,0x25, + 0x75,0xf7,0xdf,0x4d,0xe6,0xa2,0x20,0xdf,0x97,0x8c,0x0e,0xf8,0xec,0x01,0xed,0x42, + 0x7e,0xa4,0xfc,0x19,0x23,0xd9,0x31,0x6e,0x7e,0xfd,0xb7,0x4a,0x79,0xf8,0x7e,0xa9, + 0x9e,0x57,0xd8,0x18,0x0e,0x71,0x7e,0x5f,0x25,0xbf,0x31,0x67,0xd0,0x87,0x31,0x8e, + 0x1b,0x5d,0xa5,0x2e,0xb8,0xff,0x8a,0x5b,0xf7,0x6e,0xa0,0xbe,0x6f,0xc5,0xf7,0x93, + 0x36,0x47,0xaf,0x0c,0xa8,0x03,0x6e,0x48,0x91,0x36,0xfe,0xe2,0xc6,0xe8,0x4a,0xdd, + 0xbf,0x44,0x5c,0xae,0x0d,0x9a,0x7f,0x3b,0x78,0x0d,0x7c,0x97,0x7f,0xd7,0xe8,0xbb, + 0x5b,0x7c,0x37,0xb4,0xb4,0x42,0x1f,0xbf,0xd4,0x3a,0x6f,0xf8,0x27,0x15,0xda,0x06, + 0x5f,0x72,0xfb,0x89,0x11,0xe9,0x2f,0xbf,0xef,0xba,0x3c,0x25,0xee,0x8b,0x7d,0xab, + 0xf4,0xe7,0x94,0xbc,0xff,0x56,0xe9,0x2f,0x29,0x71,0xff,0xad,0xd2,0x5f,0x53,0xe2, + 0x7e,0x3f,0x73,0x75,0x4a,0xdc,0x7f,0xab,0x74,0xad,0xe4,0xfc,0x7e,0xe6,0xba,0x94, + 0xb8,0xff,0x56,0xe9,0x6f,0x29,0xf5,0xaf,0x73,0xfb,0x99,0x1b,0xa4,0xeb,0xaf,0x9d, + 0xc7,0xa6,0xc4,0xfd,0xb7,0x4a,0x37,0xa6,0xd4,0x1f,0xeb,0x74,0x6f,0x96,0xae,0xff, + 0x56,0x69,0x5c,0x4a,0xdc,0x7f,0xab,0x34,0x3e,0xa5,0xfe,0x38,0xa7,0x7b,0x71,0xfa, + 0xcb,0xef,0xbb,0x6e,0x4d,0x89,0xfb,0x62,0x31,0x9b,0x9c,0x92,0xf7,0x31,0xbb,0x23, + 0x25,0xee,0x63,0x76,0x57,0x4a,0xdc,0xc7,0x6c,0x4a,0x4a,0xdc,0xc7,0xec,0x1e,0xc9, + 0xf9,0x98,0xdd,0x9b,0x12,0xf7,0x31,0x9b,0x9a,0x52,0xff,0x5e,0xe7,0xfb,0x34,0xe9, + 0xfa,0x98,0xdd,0x9f,0x12,0xf7,0x31,0x9b,0x9e,0x52,0xff,0x7e,0xa7,0xfb,0xa0,0x74, + 0x7d,0xcc,0x1e,0x4a,0x89,0xfb,0x98,0x3d,0x9c,0x52,0xff,0xa1,0x34,0xbf,0xdf,0x75, + 0x49,0xca,0x58,0x82,0xc3,0xb3,0x4f,0x7c,0x93,0x7f,0x49,0x9a,0x9f,0x1f,0x4f,0x6b, + 0x6f,0x82,0x67,0xbf,0xf6,0x5c,0xf7,0x99,0x94,0xff,0x9b,0x0b,0x1c,0xde,0x4b,0xc1, + 0xfd,0xe1,0xd9,0x29,0xbf,0xe7,0x6f,0x72,0xdf,0xdd,0xfe,0x33,0x25,0x6e,0x6b,0xeb, + 0x9c,0x94,0xd8,0x50,0xfd,0x4f,0x17,0xcb,0xa5,0x73,0x53,0x72,0xa6,0x37,0xaf,0x4e, + 0x6f,0x7e,0x4a,0xac,0xfe,0xdb,0x8e,0x67,0x53,0x72,0xa6,0xf7,0x7c,0x9d,0xde,0x0b, + 0x29,0xb1,0xfa,0x6f,0x3d,0x5e,0x4c,0xc9,0xd9,0xbb,0x43,0x2f,0xa5,0xec,0xd3,0xc8, + 0x42,0xde,0x9f,0x97,0xd5,0x9f,0x97,0x9c,0xfd,0x57,0x52,0xe2,0xf6,0x2e,0xdf,0x6b, + 0xd2,0x1b,0xed,0xbf,0x01,0x4a,0x29,0xf7,0x5a,0xda,0xfc,0x9d,0xc2,0x05,0x29,0x39, + 0x8b,0xe1,0x9b,0x29,0xff,0x9f,0xcb,0xd3,0xce,0x8f,0x85,0x29,0x71,0xef,0xc7,0xdb, + 0xf2,0x63,0xa1,0xf3,0xe3,0xdf,0x29,0x71,0xf3,0xe3,0x1d,0xe9,0x8d,0x76,0x7b,0xc8, + 0x45,0x29,0xe5,0xde,0x49,0xf3,0x67,0xf6,0x8b,0x53,0xe2,0xfe,0x99,0xfd,0xbb,0x29, + 0x71,0x8c,0x3d,0xfe,0xbf,0xc3,0x83,0x85,0xfc,0xb9,0xf7,0xfb,0x29,0xff,0xe7,0x03, + 0xe2,0xb5,0x20,0xcd,0x9f,0x7b,0x7f,0x90,0x92,0xb3,0xbe,0x7c,0x94,0xd2,0x0e,0xae, + 0x25,0xe7,0xdb,0x77,0x47,0x29,0xe5,0x3e,0x72,0x73,0x69,0x59,0x4a,0x1c,0xe3,0x66, + 0xf7,0xeb,0x97,0xa7,0x1c,0xff,0x65,0xda,0x23,0x02,0x5b,0x99,0xe6,0xcf,0xc1,0x97, + 0xa7,0xf9,0x33,0x68,0x5b,0xdb,0x6e,0x0f,0x98,0xaf,0x4f,0xd4,0xfa,0xd9,0xb5,0x92, + 0xe7,0xe6,0x95,0x3a,0xd7,0x6c,0x6d,0xdd,0x7d,0x3d,0x9c,0xad,0xad,0xa5,0x0a,0x75, + 0x21,0x83,0x5c,0x1e,0x57,0xf2,0x5c,0x0e,0xae,0x31,0x2b,0xc0,0x6a,0x7b,0x91,0x4a, + 0xde,0xdf,0xbd,0xa5,0x03,0x5d,0xbb,0x86,0xea,0x51,0x21,0x6e,0x32,0x3d,0x2b,0x6c, + 0xcf,0xcb,0xf4,0xaa,0x10,0xb7,0xfd,0xf1,0xfe,0x15,0x62,0xd0,0xb5,0x7d,0x6e,0xef, + 0x0a,0xf1,0x1b,0x1a,0xf3,0x3d,0xf3,0x01,0x95,0x7c,0xcf,0x0c,0x1e,0x7b,0xe6,0x1b, + 0x1a,0xf3,0x7d,0xf0,0x81,0x95,0x7c,0x1f,0x0c,0x59,0xdb,0x07,0x1f,0x54,0x21,0x67, + 0xf1,0xef,0x53,0x21,0x36,0xdc,0xcd,0xd7,0xbe,0x15,0xfe,0xdf,0x99,0x3e,0xc2,0xb1, + 0xbe,0x5a,0x9f,0xf1,0x6b,0x6b,0xe8,0x23,0xda,0x63,0x61,0x4d,0xeb,0xab,0xd8,0xcc, + 0x50,0x1c,0xd3,0x0a,0xc7,0xe4,0x1f,0x7a,0x9e,0xb2,0xb1,0x8b,0x23,0xb8,0x4a,0x56, + 0x36,0x92,0xcd,0x4a,0x25,0xff,0x46,0xa0,0x85,0xc6,0xe6,0xf6,0x20,0xbf,0x17,0xd5, + 0xb2,0xc2,0x31,0x02,0x67,0xb9,0x6c,0xc3,0x0a,0xdb,0x07,0x07,0xff,0x36,0x96,0xad, + 0x8d,0xea,0xea,0x1b,0x3b,0x7f,0x1f,0xad,0x52,0x0f,0xed,0xc1,0x6f,0xc8,0x3e,0x20, + 0x7f,0x37,0xab,0xf3,0xb7,0x8d,0xf3,0x17,0xdc,0xe6,0x59,0x69,0x2d,0x9b,0x9b,0x3b, + 0x3f,0xb6,0x94,0x1f,0x6d,0x4a,0x79,0x1f,0xb6,0x76,0x7d,0xb0,0x7b,0x26,0xad,0x2a, + 0xbc,0xce,0x00,0x67,0xe7,0xe3,0x36,0x15,0xea,0xb7,0x92,0xcf,0x6d,0x64,0xbf,0x75, + 0x5d,0xbd,0x8d,0xeb,0xc3,0xe3,0x55,0xea,0x6d,0xae,0x3e,0x40,0xd6,0xf2,0x76,0xdb, + 0x0a,0xfb,0x08,0x99,0x21,0x7a,0x4e,0xd1,0xce,0xcd,0xf5,0xb6,0x95,0xfc,0x9b,0x92, + 0xda,0xfb,0x9b,0x9a,0xb3,0xb3,0x1d,0xb6,0xa3,0xe6,0xf0,0xec,0x42,0xfe,0x6e,0x65, + 0x87,0x0a,0xf1,0x61,0xee,0x3d,0xca,0x8e,0x15,0xea,0x83,0xb3,0x73,0xb0,0x53,0x85, + 0xb8,0xad,0x41,0x9d,0x2b,0x6c,0xbf,0xe0,0xd6,0x9b,0x9d,0x2b,0x94,0xeb,0xec,0xe4, + 0x76,0x95,0x5c,0xd1,0x3d,0x73,0xf9,0x55,0x85,0xb2,0xe0,0x0e,0xcf,0x5a,0xc4,0x3a, + 0x7c,0x6f,0xc0,0xbd,0x11,0xb8,0x46,0xfd,0x7f,0xa2,0x06,0xfd,0x5f,0x1a,0xc4,0xeb, + 0x5a,0xed,0xb1,0xa6,0xba,0x3d,0xd6,0xf7,0xda,0x63,0x8d,0xd3,0xfd,0x1a,0xc3,0x7f, + 0xd0,0x1e,0xeb,0x7b,0xb5,0xeb,0xf5,0xaf,0xd5,0x3e,0x11,0x72,0xef,0x56,0xd9,0x2e, + 0xc6,0x00,0x3a,0x53,0xdd,0xbe,0xf6,0x41,0xe5,0x1c,0xfb,0x0e,0xe1,0x61,0xb7,0xef, + 0x03,0xf7,0x50,0x56,0x1e,0x96,0xcd,0x87,0xdc,0xff,0x3d,0x99,0x11,0xf0,0xff,0x51, + 0x4c,0x73,0xeb,0xe2,0x23,0x01,0xf1,0xcb,0xed,0xdb,0xdd,0x80,0xd8,0xe7,0x2e,0x2f, + 0x3f,0x16,0x10,0x37,0x3b,0x8f,0xcb,0xce,0x44,0x67,0xe7,0x89,0x80,0xb8,0xd9,0x79, + 0x32,0x20,0xe6,0xed,0xcc,0x0c,0x88,0xdb,0xff,0x47,0x99,0x15,0xd0,0xf6,0x4c,0x9d, + 0x73,0xc0,0xfe,0x11,0xf0,0xff,0x76,0xcc,0xd2,0xf5,0x0e,0xfe,0xef,0xd2,0x6c,0xfd, + 0xcf,0xa5,0xc1,0x59,0x1d,0xc7,0x90,0x79,0x57,0xfb,0x6f,0xeb,0xe7,0xc3,0x41,0xf3, + 0xff,0x8d,0x82,0xdf,0x35,0x59,0x84,0xf7,0xcc,0xca,0xff,0x03,0xc9,0xa0,0xdc,0x9e, + 0x90,0x56,0x00,0x00 }; // Generated from: @@ -710,19 +745,15 @@ constexpr uint8_t kEtcToBc_comp_00000000[] = { // return uvec2(flip_endian(v . y), flip_endian(v . x)); // } // -// uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, int scale) +// uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, bool transparent) // { // vec3 dir = maxColor - minColor; // float distMin = dot(minColor, dir); // float distMax = dot(maxColor, dir); // float dist = dot(color, dir); -// uint ind = uint(clamp(int((dist - distMin)/(distMax - distMin)* scale + 0.5f), 0, scale)); +// int ind = int(round(clamp((dist - distMin)/(distMax - distMin), 0.0, 1.0)*(transparent ? 2.0 : 3.0))); // -// ind = - ind & 3; -// ind ^= uint(ind < 2); -// ind += scale; -// ind -= 3; -// return ind; +// return bitfieldExtract(transparent ? 0x18u : 0x2du, ind * 2, 2); // } // // void ComputeMaxMinColor(uvec3 rgbColor, inout uvec3 minColor, inout uvec3 maxColor){ @@ -733,30 +764,25 @@ constexpr uint8_t kEtcToBc_comp_00000000[] = { // dx = ivec3(rgbColor)- avg; // } // else { -// dx = ivec3(rgbColor)- ivec3((subgroupClusteredAdd(rgbColor, 16)+ 8)>> 4); +// dx = ivec3(rgbColor)- ivec3(subgroupClusteredAdd(rgbColor, 16)+ 8 >> 4); // } -// float cov0 = float(subgroupClusteredAdd(dx . r * dx . r, 16)); -// float cov1 = float(subgroupClusteredAdd(dx . r * dx . g, 16)); -// float cov2 = float(subgroupClusteredAdd(dx . r * dx . b, 16)); -// float cov3 = float(subgroupClusteredAdd(dx . g * dx . g, 16)); -// float cov4 = float(subgroupClusteredAdd(dx . g * dx . b, 16)); -// float cov5 = float(subgroupClusteredAdd(dx . b * dx . b, 16)); -// +// vec3 cov0 = vec3(subgroupClusteredAdd(dx . r * dx, 16)); +// vec3 cov1 = vec3(subgroupClusteredAdd(dx . ggb * dx . gbb, 16)); // vec3 vg = vec3(subgroupClusteredMax(rgbColor, 16)- subgroupClusteredMin(rgbColor, 16)); -// float eigenvalue = 0.0f; // +// mat3 covMat = mat3(cov0, +// vec3(cov0 . y, cov1 . xy), +// vec3(cov0 . z, cov1 . yz)); +// +// float eigenvalue = 0.0f; // for(int i = 0;i < 4;i ++){ -// float r = dot(vec3(cov0, cov1, cov2), vg); -// float g = dot(vec3(cov1, cov3, cov4), vg); -// float b = dot(vec3(cov2, cov4, cov5), vg); -// vg = vec3(r, g, b); +// vg = covMat * vg; // eigenvalue = sqrt(dot(vg, vg)); // if(eigenvalue > 0.0f){ // float invNorm = 1.0f / eigenvalue; // vg *= invNorm; // } // } -// // const float kDefaultLuminanceThreshold = 4.0f * 255; // const float kQuantizeRange = 0.512f; // @@ -770,20 +796,19 @@ constexpr uint8_t kEtcToBc_comp_00000000[] = { // float dist = dot(vec3(rgbColor), vg); // float min_dist = subgroupClusteredMin(dist, 16); // float max_dist = subgroupClusteredMax(dist, 16); -// uint min_index = subgroupClusteredMax(dist == min_dist ? gl_SubgroupInvocationID : 0, 16); -// uint max_index = subgroupClusteredMax(dist == max_dist ? gl_SubgroupInvocationID : 0, 16); -// minColor = subgroupShuffle(rgbColor, min_index); -// maxColor = subgroupShuffle(rgbColor, max_index); +// uvec2 indices = uvec2(dist == min_dist ? gl_SubgroupInvocationID : 0, +// dist == max_dist ? gl_SubgroupInvocationID : 0); +// uvec2 minMaxIndex = subgroupClusteredMax(indices, 16); +// minColor = subgroupShuffle(rgbColor, minMaxIndex . x); +// maxColor = subgroupShuffle(rgbColor, minMaxIndex . y); // } // // uint GetIndicesAlpha(int alpha, int minAlpha, int maxAlpha) // { // float dist = float(maxAlpha - minAlpha); -// uint ind = uint(float(alpha - minAlpha)/ dist * 7.0f + 0.5f); +// int ind = int(round(clamp((alpha - minAlpha)/ dist * 7.0f, 0.0, 7.0))); // -// ind = - ind & 7; -// ind ^= int(2 > ind); -// return ind; +// return bitfieldExtract(0x2345671u, ind * 4, 4); // } // // void ComputeMaxMin(int alpha, inout int minAlpha, inout int maxAlpha){ @@ -797,21 +822,45 @@ constexpr uint8_t kEtcToBc_comp_00000000[] = { // if(minValue != maxValue) // indices = GetIndicesAlpha(value, minValue, maxValue); // -// uint indices0 = pid < 5 ? indices <<(3 * pid + 16): 0x0; -// uint indices1 = pid > 5 ? indices <<(3 * pid - 16): 0x0; -// if(pid == 5){ -// indices0 |=(indices & 0x1)<< 31; -// indices1 |=(indices & 0x6)>> 1; -// } -// uint mask0 = subgroupClusteredOr(indices0, 16); -// uint mask1 = subgroupClusteredOr(indices1, 16); +// uvec2 mask = uvec2(pid <= 5 ? indices <<(16 + 3 * pid): 0x0, +// pid >= 5 ?(indices << 29)>>(45 - 3 * pid): 0x0); +// +// mask = subgroupClusteredOr(mask, 16); +// return uvec2((maxValue & 0xff)|((minValue & 0xff)<< 8)| mask . x, mask . y); +// } +// +// uvec3 scaleColorToRGB565(uvec3 color){ +// return uvec3(round(vec3(color)* vec3(31.0 / 255.0, 63.0 / 255.0, 31.0 / 255.0))); +// } // -// return uvec2((maxValue & 0xff)|((minValue & 0xff)<< 8)| mask0, mask1); +// uvec3 convertRGB565ToRGB888(uvec3 color){ +// return uvec3(color . x << 3 |(color . x >> 2), +// color . y << 2 |(color . y >> 4), +// color . z << 3 |(color . z >> 2)); // } // -// uint packColorToRGB565(uvec3 color){ -// uvec3 quant = uvec3(round(vec3(color)* vec3(31.0 / 255.0, 63.0 / 255.0, 31.0 / 255.0))); -// return(quant . r << 11)|(quant . g << 5)| quant . b; +// uint packRGB565(uvec3 color565){ +// return color565 . r << 11 |(color565 . g << 5)| color565 . b; +// } +// +// void modifyMinMax(inout uvec3 minColor, inout uvec3 maxColor){ +// uvec3 minColor565 = scaleColorToRGB565(minColor); +// uvec3 maxColor565 = scaleColorToRGB565(maxColor); +// if(all(equal(minColor565, maxColor565))){ +// uvec3 simulatedColor = convertRGB565ToRGB888(minColor565); +// ivec3 signMax = sign(ivec3(maxColor)- ivec3(simulatedColor)); +// ivec3 signMin = sign(ivec3(minColor)- ivec3(simulatedColor)); +// bvec3 needCorrect = greaterThan(signMax * signMin, ivec3(0, 0, 0)); +// bvec3 positive = greaterThan(signMin, ivec3(0, 0, 0)); +// maxColor565 . r += needCorrect . r && positive . r ? 1 : 0; +// maxColor565 . g += needCorrect . g && positive . g ? 1 : 0; +// maxColor565 . b += needCorrect . b && positive . b ? 1 : 0; +// minColor565 . r -= needCorrect . r && ! positive . r ? 1 : 0; +// minColor565 . g -= needCorrect . g && ! positive . g ? 1 : 0; +// minColor565 . b -= needCorrect . b && ! positive . b ? 1 : 0; +// } +// minColor = minColor565; +// maxColor = maxColor565; // } // // void swap(inout uint a, inout uint b){ @@ -854,12 +903,15 @@ constexpr uint8_t kEtcToBc_comp_00000000[] = { // if(controlFlag) // { // ComputeMaxMinColor(uvec3(result . r, result . g, result . b), minColor, maxColor); -// -// uint minColor565 = packColorToRGB565(minColor); -// uint maxColor565 = packColorToRGB565(maxColor); +// modifyMinMax(minColor, maxColor); +// uint minColor565 = packRGB565(minColor); +// uint maxColor565 = packRGB565(maxColor); // // if(minColor565 != maxColor565){ -// indices = GetIndicesRGB(vec3(result . r, result . g, result . b), vec3(minColor), vec3(maxColor), nonOpaque ? 2 : 3); +// indices = GetIndicesRGB(vec3(result . r, result . g, result . b), +// vec3(convertRGB565ToRGB888(minColor)), +// vec3(convertRGB565ToRGB888(maxColor)), +// nonOpaque); // } // bool flip = maxColor565 < minColor565; // if(flip){ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000001.inc b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000001.inc index 0eeec21b7a3d..9c7b1df66a31 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000001.inc +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/gen/EtcToBc.comp.00000001.inc @@ -10,219 +10,211 @@ #pragma once constexpr uint8_t kEtcToBc_comp_00000001[] = { - 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0x6d,0x59,0x7b,0x70,0x56,0xd5, - 0x11,0xff,0xee,0x9e,0x93,0x84,0x57,0x11,0x0d,0xf8,0x82,0x2a,0x68,0x75,0xea,0x80, - 0x98,0xa9,0x8a,0xe9,0x28,0x56,0x43,0xc7,0x38,0xe2,0x03,0xc9,0x8c,0x1a,0xdb,0xc1, - 0x07,0xa4,0x95,0x0a,0x28,0x03,0x46,0x44,0x12,0xe5,0x21,0x44,0x41,0xa1,0x23,0xd5, - 0x8a,0x56,0x44,0x2d,0x3e,0x5b,0xe9,0x1f,0xb5,0xa3,0x40,0xb5,0x82,0x46,0x05,0xac, - 0xd5,0x50,0xa2,0x06,0xcd,0x88,0x68,0x6b,0x14,0x6b,0x1c,0x84,0xf8,0xa2,0x67,0xbf, - 0xdf,0x6f,0xf9,0x36,0x9f,0xc9,0xcc,0x9d,0xfb,0xed,0x6f,0xf7,0xb7,0x67,0xcf,0x9e, - 0x73,0x76,0xef,0xbd,0x09,0x72,0x74,0x59,0x2e,0x64,0xb9,0x3e,0xb9,0x5e,0xb9,0xfe, - 0x25,0xb9,0xfc,0xdf,0x81,0x39,0xc9,0x65,0xbc,0x8f,0xe4,0x7d,0x34,0xef,0x63,0xd2, - 0xbd,0x6f,0xae,0x34,0xaf,0xaf,0x3e,0xb7,0xe6,0xdc,0x91,0x33,0x66,0x4e,0x1a,0x79, - 0xd2,0xc9,0x15,0xca,0xeb,0x9f,0x0b,0x79,0xbe,0xea,0x0e,0xc8,0x95,0xe5,0xd4,0x5d, - 0x4c,0xd7,0xd4,0x2b,0x26,0x4f,0x53,0x7c,0x6b,0xba,0xda,0xd2,0x35,0x20,0xf1,0x63, - 0xde,0x5f,0x2e,0x77,0x06,0xed,0xf5,0x3a,0x3b,0x31,0x4e,0x46,0x08,0xb9,0xa3,0x79, - 0x37,0x2c,0x23,0x16,0x1d,0x26,0xc4,0x7a,0x39,0x2c,0x10,0xeb,0xe7,0xb0,0x48,0x6c, - 0x80,0xc3,0x4a,0x88,0x0d,0x74,0x58,0x29,0xb1,0x43,0x1d,0x56,0x46,0x6c,0x88,0xce, - 0x37,0x79,0xb7,0x71,0xab,0x93,0xd7,0xad,0xf9,0x5c,0xe4,0x72,0x87,0x53,0x6e,0xa3, - 0x3c,0x98,0xf2,0xe6,0x14,0xf4,0x51,0x9c,0x87,0xc9,0xc3,0x9c,0x3c,0x4c,0xba,0xeb, - 0x55,0x1e,0xc6,0xb9,0xea,0x58,0x2a,0x1f,0x46,0xdd,0xb1,0x02,0xdf,0x2a,0x97,0xa7, - 0x08,0x34,0x86,0x61,0xc9,0x26,0x30,0x9e,0x41,0xc9,0x46,0xe3,0x1f,0x4a,0x7f,0x87, - 0x24,0xb9,0x8c,0x73,0x92,0x3c,0x1e,0xf3,0x79,0x2a,0xe3,0xa5,0xf6,0xbd,0x69,0x9f, - 0x51,0xdf,0x87,0xba,0xde,0xe4,0x0f,0xe0,0x6f,0xe3,0x0f,0xa4,0x5e,0x7d,0x0e,0x27, - 0xff,0x84,0x74,0x1d,0xef,0xe4,0x0a,0xae,0xc1,0x11,0xc9,0x9b,0xe5,0xb4,0x94,0x7e, - 0x4a,0x7b,0xb8,0xd4,0xef,0x28,0xea,0xd5,0xfe,0x54,0xca,0xa7,0x10,0x33,0xbf,0x95, - 0xce,0xfe,0xa7,0xce,0xdf,0x70,0xce,0xfb,0x34,0xce,0x7b,0x20,0xf7,0xaa,0xe1,0x55, - 0x9c,0x9f,0xf9,0x39,0x8b,0xeb,0x6b,0x72,0x35,0xf7,0x8f,0xc9,0xe3,0xb9,0x27,0x4c, - 0xae,0xe1,0xfe,0x31,0xb9,0x96,0xfb,0xc8,0xe4,0x09,0xdc,0x4b,0x26,0x4f,0x4c,0xd7, - 0x91,0x4e,0xae,0x63,0xfe,0x34,0x9f,0xd7,0x31,0xee,0xe8,0xe2,0xab,0xa7,0xbf,0x21, - 0x49,0xbe,0x3e,0xdd,0xaf,0x23,0x66,0xfc,0x59,0xf9,0x73,0x95,0xcb,0x8d,0x48,0x99, - 0x57,0xdd,0x0d,0xf4,0x39,0x81,0xb1,0xcf,0x72,0xb6,0xb3,0x8b,0x72,0x76,0x23,0xcf, - 0x81,0x71,0xe7,0x90,0x5b,0x49,0xdb,0x1b,0x9d,0x6d,0x43,0x51,0x9e,0x1a,0xb9,0xd6, - 0xc6,0xbd,0x89,0x36,0x35,0xd4,0xdd,0xe8,0x74,0x37,0x53,0x57,0xc1,0xb8,0xbc,0xdf, - 0xb9,0x3c,0x13,0x66,0x3b,0xcf,0xc5,0xdf,0x48,0xbd,0xd9,0xce,0x4f,0x57,0x1f,0x67, - 0xbb,0xc0,0xc5,0x5b,0x4d,0xbd,0xe9,0x6e,0xe1,0x78,0x95,0xf4,0xe3,0x75,0x0b,0xc9, - 0xab,0xe9,0x41,0xb7,0x88,0xb1,0xda,0xf8,0xb3,0x9d,0xae,0xa9,0x68,0x8e,0x5e,0x77, - 0xab,0x9b,0x63,0xb1,0xee,0x36,0xc7,0xab,0x2c,0xd2,0x2d,0x66,0x2c,0x15,0x4e,0x67, - 0xf3,0x5d,0xc2,0x3d,0x6b,0xb6,0xb7,0x13,0x6b,0x20,0xc7,0xfb,0xb9,0xc3,0xe5,0xb7, - 0x91,0xf9,0x30,0xdd,0x52,0x37,0xdf,0xca,0xfd,0xba,0xf2,0xfc,0x7e,0x5a,0xc6,0x3d, - 0x33,0x87,0x6b,0x78,0x33,0xd7,0x60,0x01,0x73,0xb8,0x90,0x39,0x69,0xe2,0x1c,0x6f, - 0x63,0xcc,0xb7,0x73,0xcc,0xa5,0x3c,0x73,0x77,0x72,0x3f,0x5c,0xef,0xe2,0x5f,0xa3, - 0x7b,0xe6,0x9b,0x7d,0xfb,0x4c,0x7e,0x3a,0x5d,0xfb,0x42,0x41,0xff,0x37,0x95,0x13, - 0xe9,0xe0,0x54,0x11,0xd6,0xb3,0xd6,0xa8,0x4e,0x7f,0x6f,0xc8,0xcf,0xfc,0xbb,0x2a, - 0x93,0x37,0xe6,0xe5,0x9b,0xc6,0x98,0xbc,0x05,0xa9,0xf9,0x99,0x9e,0x9b,0x37,0x79, - 0xd6,0x03,0x63,0x69,0xe1,0x5e,0x7d,0x93,0xf5,0xa2,0x85,0xbd,0x25,0x73,0xe7,0xaa, - 0x95,0xe7,0xda,0xf4,0x6d,0xae,0xce,0x6d,0xe7,0x6f,0x5f,0x3f,0xda,0x8b,0xce,0xe5, - 0xce,0x7c,0x0f,0x2b,0xc8,0xbb,0x78,0x8e,0x4d,0xde,0xc3,0x78,0x34,0x3e,0xc9,0xe0, - 0xcb,0xf3,0xcb,0x32,0xd4,0x19,0x5d,0x23,0xd5,0xf7,0xca,0x50,0xa3,0x5a,0x79,0xbe, - 0x55,0x6f,0xb6,0x7d,0xd2,0xef,0x7d,0x2e,0x37,0xa3,0x34,0xb8,0x5c,0xfb,0x19,0xfb, - 0x6b,0x5b,0x86,0xdc,0x9b,0x5c,0x97,0x15,0x6a,0x8e,0xca,0x4d,0x59,0xf7,0x9a,0xbc, - 0x9c,0xfe,0x34,0xb6,0x27,0xd3,0xef,0xd1,0x8c,0xfd,0xb0,0xa4,0x7d,0x85,0xb6,0x6c, - 0xf5,0xfb,0xff,0x32,0xde,0x07,0xa7,0x59,0xbd,0x9a,0x04,0xb5,0xd3,0x5c,0x6d,0xa2, - 0x42,0xb1,0x53,0x29,0x6f,0x26,0xa6,0xfa,0xb7,0x32,0xd4,0x9c,0xde,0xf4,0x7f,0xa4, - 0xc0,0x7f,0x56,0xe4,0x5f,0xf2,0x3d,0x01,0x9c,0xa1,0x02,0x4c,0x6d,0x4f,0xa5,0x3c, - 0x8c,0x98,0xcd,0xe9,0x18,0xc1,0xb3,0xc1,0x88,0x24,0xe9,0x3a,0x6b,0xff,0x53,0xac, - 0x8a,0x35,0x7d,0x44,0x9a,0x81,0xe6,0xe4,0xd5,0x88,0x9c,0xb6,0x12,0xd3,0x5a,0xba, - 0x29,0xe2,0x3c,0xd4,0x39,0x6c,0x73,0xc4,0xf9,0xa9,0x70,0x6b,0xb2,0x25,0x22,0xf7, - 0xfe,0xca,0xd2,0xfc,0xf5,0x4c,0xb5,0x44,0xfc,0x56,0xbb,0x8e,0x58,0xc8,0xed,0x0f, - 0x4a,0xd0,0xf3,0x46,0x25,0xbf,0xc2,0x35,0xcf,0x71,0x2f,0xec,0x4d,0x48,0x09,0xf7, - 0x9c,0x9e,0x97,0xda,0x80,0x75,0x33,0xf9,0x2f,0x52,0x90,0x75,0x6f,0xee,0xcc,0xba, - 0xcb,0x5f,0x50,0xde,0x93,0xbc,0x55,0x31,0x1f,0x5f,0xa7,0xdf,0xba,0x6f,0xc6,0x08, - 0xfc,0xeb,0x7d,0x34,0xcf,0xc4,0x79,0x82,0x7d,0x7f,0x41,0x62,0x29,0xef,0x7c,0x01, - 0x76,0x9e,0x14,0xd6,0x74,0x01,0xf3,0x34,0x4e,0xa0,0xd7,0x7c,0x9d,0x99,0x30,0x3d, - 0x03,0x17,0x0a,0xce,0x85,0xfa,0x1f,0xcd,0xbc,0x8f,0x17,0xe0,0x2f,0x24,0x1b,0x95, - 0x6b,0x04,0x98,0x9e,0x8f,0x66,0x62,0x17,0x11,0xdb,0xe9,0xb0,0x4b,0x04,0xb6,0x55, - 0x1c,0x53,0xb1,0x5a,0xf2,0x54,0x77,0x21,0xb1,0x5f,0x08,0x62,0xc9,0xe5,0x6b,0x11, - 0xb0,0x5f,0x0a,0x70,0xb5,0x1f,0x9f,0x10,0x8d,0x77,0x75,0x04,0x6e,0xb6,0x36,0xce, - 0x65,0x1c,0x67,0x97,0x1b,0xe7,0x72,0xca,0x97,0xb9,0x71,0xae,0x24,0x37,0x73,0xe3, - 0x4c,0x14,0xe0,0x97,0xbb,0x71,0x1e,0x8b,0xc0,0x57,0x47,0xd8,0xda,0x38,0xbf,0x12, - 0xcc,0x53,0xcf,0xb9,0xe5,0xe2,0x2a,0x62,0xba,0xaf,0xc6,0x31,0xaf,0x93,0x05,0xb6, - 0xaa,0xbb,0x99,0xd8,0xd5,0x02,0xbf,0xaa,0x9b,0xc3,0xe7,0xa8,0xa9,0x02,0x5c,0x73, - 0xaf,0xcf,0x2f,0x7f,0xcc,0xf0,0x8c,0x53,0xe1,0x72,0xbf,0x3a,0x03,0x3e,0x87,0x7b, - 0xed,0x91,0x0c,0x98,0x71,0x1e,0x25,0xa7,0xc6,0x71,0x1e,0xcb,0x80,0x1b,0xe7,0xf1, - 0x0c,0xd8,0x38,0xee,0xfb,0x27,0x32,0xf8,0x51,0xfc,0xa9,0x84,0x69,0x3d,0xf8,0x53, - 0x86,0x78,0x54,0xb7,0x22,0xf1,0xb4,0x3e,0xfc,0x99,0xb8,0xee,0xbd,0x35,0x3c,0xbc, - 0x5f,0x25,0x9d,0xe2,0x4f,0xa5,0x4b,0x31,0xdd,0x7f,0xfa,0xbb,0x2b,0xdd,0xab,0xb8, - 0x1f,0x15,0xdf,0xc0,0xb1,0xfe,0x4a,0xbf,0x7a,0xfe,0x9a,0x89,0x3d,0x43,0x4c,0xcf, - 0x9f,0xae,0x8d,0xc6,0xb8,0x2e,0x03,0x9e,0xe3,0x1a,0x2a,0xb6,0x3e,0xc3,0xbc,0x54, - 0x67,0x76,0xcf,0xd1,0xce,0xd6,0x50,0xb1,0xe7,0x33,0xd8,0xaa,0xce,0xb8,0x1b,0xc9, - 0x55,0xcc,0xec,0x9a,0x33,0xe0,0xeb,0x32,0xe4,0x4a,0xeb,0xd7,0x16,0xd6,0x2e,0xf3, - 0xff,0xcf,0x0c,0x31,0xfb,0x3d,0xf2,0x06,0x73,0xee,0xd7,0xfd,0xcd,0x0c,0x78,0x5d, - 0xae,0x90,0xe7,0x96,0x0c,0xb8,0xc5,0xb0,0x35,0x83,0xbf,0x16,0xe7,0x7f,0x1b,0xfd, - 0xe7,0x5c,0xfc,0xad,0x19,0x6c,0xb7,0x71,0x5d,0xb5,0x7e,0xbe,0xcd,0x75,0xad,0xe3, - 0xba,0xaa,0xdd,0x3b,0xc4,0x8d,0xd7,0x96,0x81,0xab,0xf8,0xa4,0x64,0xa3,0xf5,0x79, - 0x3b,0xe7,0x74,0x99,0xd6,0xa2,0x74,0x7f,0x97,0x58,0x5b,0x56,0x38,0x07,0x33,0x04, - 0x78,0x96,0xdf,0xb3,0xa8,0x7b,0x0d,0x02,0xdc,0x5f,0x2f,0xd0,0x47,0xa3,0x40,0xaf, - 0xfd,0xaa,0x99,0xd8,0x5c,0x01,0xbe,0x25,0x16,0xfc,0xce,0x17,0xe0,0xb9,0x7c,0xef, - 0x06,0xb6,0x40,0x80,0x97,0xb9,0xf1,0x17,0xd2,0x2e,0x73,0x76,0x8b,0x04,0xb8,0xf6, - 0xc1,0x17,0x89,0x35,0x09,0xf8,0x8b,0xdc,0x19,0xbe,0x8d,0x5c,0x71,0xdc,0xc5,0x02, - 0xbc,0xd5,0x71,0x97,0x08,0xf8,0x8b,0x1d,0xf7,0x0e,0x72,0x83,0xe3,0x2e,0x15,0xe0, - 0xa7,0x39,0xee,0x32,0x01,0x7f,0xa9,0xe3,0xd6,0x33,0x67,0x39,0x97,0xb3,0xdf,0x09, - 0x70,0x7f,0x59,0xce,0xee,0x12,0xe8,0x7d,0xce,0xee,0x11,0xe0,0x3e,0x67,0xf7,0x0a, - 0x70,0x9f,0xb3,0xfb,0x04,0xb8,0xcf,0xd9,0xfd,0xb4,0xf3,0x39,0x5b,0x29,0xc0,0x7d, - 0xce,0x1e,0x10,0xf0,0x57,0xba,0xd8,0x1f,0x24,0xd7,0xe7,0xec,0x21,0x01,0xee,0x73, - 0xf6,0xb0,0x80,0xff,0x90,0xe3,0xae,0x26,0xd7,0xe7,0xec,0x11,0x01,0xee,0x73,0xf6, - 0xa8,0x80,0xaf,0x3a,0xab,0x83,0xb3,0x04,0xb9,0x54,0xdd,0xe9,0xc9,0x83,0xf6,0x36, - 0xc5,0xec,0x7c,0x3c,0x2b,0xa8,0x75,0x7a,0x7e,0xe7,0x11,0x5b,0x2b,0xe8,0xa5,0xcf, - 0xba,0xba,0xb8,0x4e,0x70,0x16,0x2a,0x5d,0x8d,0x5b,0x2f,0xc0,0x9f,0x48,0x36,0x5a, - 0xab,0xfe,0x2e,0xc0,0x4e,0x63,0xaf,0x7c,0x45,0x0a,0xf5,0x4a,0x75,0xcf,0xa5,0x6b, - 0x23,0xeb,0xd3,0x73,0xf4,0xad,0xef,0x74,0xcf,0x0b,0x7a,0x6e,0x95,0xf3,0xfd,0x0f, - 0x01,0x6e,0xe7,0xfa,0x05,0x01,0xf6,0x6a,0xd2,0xaa,0xbc,0x41,0x80,0x9d,0xc5,0xe7, - 0x6a,0xad,0x7d,0xaf,0xd0,0xf7,0x46,0xe7,0xfb,0xc5,0x1e,0x7c,0xbf,0x24,0xc0,0x37, - 0x25,0x49,0xe5,0x66,0x01,0x66,0xbe,0x6c,0xcc,0x97,0x05,0x3a,0xef,0x5b,0xef,0xbb, - 0x53,0x66,0x55,0xff,0x5a,0x44,0x1c,0x3a,0x97,0x97,0x39,0x37,0x1b,0x77,0x53,0x0f, - 0xe3,0x6e,0x16,0xe0,0x36,0xee,0x16,0x01,0x36,0x9e,0xbd,0xc3,0xc6,0x7d,0x4d,0xa0, - 0x33,0xde,0xeb,0x45,0xbc,0x7f,0x09,0xb0,0xda,0x22,0xde,0x1b,0x02,0xdd,0x06,0xae, - 0x63,0x8b,0x60,0x2d,0xf5,0xdd,0xc4,0xe2,0xda,0xca,0xb8,0x5a,0x9c,0xff,0x7f,0x0b, - 0xf0,0x66,0xab,0x85,0xe4,0xe9,0x3b,0xb3,0x8d,0xf9,0x96,0xc0,0xae,0x55,0xba,0xd7, - 0xdb,0xb7,0x05,0x3a,0xdb,0x3b,0x6d,0x82,0x67,0xb1,0x67,0x5d,0x1c,0xef,0x0a,0x70, - 0x1f,0xc7,0x7b,0x8c,0xe3,0x5d,0x17,0x47,0xbb,0x00,0xb7,0x38,0xde,0x27,0x6f,0xa2, - 0xab,0xf9,0x3b,0x04,0x76,0xef,0x4b,0xe1,0x99,0xe0,0x03,0x01,0x5e,0xe5,0xe2,0xda, - 0x29,0xc0,0x75,0xcf,0xeb,0xf3,0xdd,0xb2,0xfc,0xd8,0xa5,0xf9,0xf7,0xd8,0xff,0x08, - 0x9e,0xf9,0x34,0x5f,0x6f,0x4b,0xa1,0xb6,0xff,0x57,0xa0,0xb3,0xb9,0x74,0x08,0xfc, - 0xe8,0x7b,0xdf,0x4b,0xc4,0x3e,0x11,0xd8,0x75,0xb8,0x33,0xb4,0x4b,0xb0,0x17,0xaa, - 0x5d,0x3f,0xf9,0x4c,0x80,0xeb,0xfa,0xd8,0xf9,0xf8,0x5c,0xb0,0xb6,0x4b,0x78,0x3e, - 0xba,0xdc,0xf9,0x50,0x5d,0xa7,0x3e,0xd7,0x70,0x9f,0x75,0x3a,0xff,0xbb,0x05,0xe3, - 0xbe,0xe6,0xb0,0x2f,0x05,0xb8,0xed,0xfd,0x2e,0xf2,0xf6,0x48,0x77,0xb9,0xcb,0xed, - 0xd7,0xd7,0x23,0x78,0x9d,0xf4,0xb7,0x47,0x0a,0xf1,0x7e,0x23,0x88,0x59,0x6d,0x1e, - 0xe3,0x19,0xd3,0x82,0xa3,0xe7,0x76,0x0d,0xdf,0x7f,0x0d,0x8f,0xc4,0x9f,0xe6,0xbb, - 0x64,0xbf,0xf4,0x94,0xac,0x78,0xaf,0x80,0xda,0x78,0x3c,0xfd,0x29,0x5f,0x6d,0x95, - 0xa7,0xef,0x4f,0xfd,0xc8,0xdb,0xc0,0xf7,0xca,0x6b,0xf8,0x5e,0xd5,0x3f,0x80,0x6b, - 0xf2,0x00,0xf2,0x9a,0x52,0x6c,0x2a,0x1f,0x18,0x60,0xa3,0xf8,0x2d,0xc4,0xca,0x03, - 0x70,0xf5,0x39,0x97,0xd8,0xc0,0x00,0x5c,0xdf,0x51,0xa7,0x71,0x4d,0x07,0x05,0xe0, - 0xfa,0x5c,0xa9,0xef,0x0f,0x6b,0x23,0xb0,0x16,0xbe,0x20,0x58,0x7d,0xfb,0x98,0xbd, - 0xbe,0xd1,0x9d,0xd7,0x8e,0x0c,0xb8,0xad,0xdf,0x27,0x19,0x30,0xab,0x6f,0xbb,0xdc, - 0xf3,0x98,0xea,0x3e,0x4d,0xd7,0x2e,0x3e,0x8f,0x7d,0xea,0xfa,0xc6,0xe0,0x80,0xbe, - 0x15,0x5c,0xdf,0x3a,0x26,0x00,0xf7,0x97,0xf5,0xad,0x63,0x03,0xf4,0xbe,0x6f,0x1d, - 0x17,0x80,0xfb,0xbe,0x35,0x3c,0x00,0xf7,0x7d,0x6b,0x44,0x00,0xee,0xfb,0xd6,0x48, - 0xda,0xf9,0xbe,0x75,0x42,0x00,0xee,0xfb,0x56,0x45,0x00,0x5f,0x75,0xc6,0xfd,0x09, - 0xb9,0xbe,0x6f,0x9d,0x18,0x80,0xfb,0xbe,0x75,0x52,0x00,0xff,0x44,0xc7,0x1d,0x45, - 0xae,0xef,0x5b,0xa7,0x04,0xe0,0xbe,0x6f,0x55,0x06,0xf0,0x4f,0x71,0xdc,0x23,0x98, - 0x33,0x71,0x39,0x1b,0x1d,0x80,0xfb,0xcb,0x72,0x76,0x7a,0x80,0xde,0xe7,0xec,0xcc, - 0x00,0xdc,0xe7,0x6c,0x4c,0x00,0xee,0x73,0xf6,0xf3,0x00,0xdc,0xe7,0xec,0x2c,0xda, - 0xf9,0x9c,0x55,0x07,0xe0,0x3e,0x67,0x67,0x07,0xf0,0xab,0x5d,0xec,0xe7,0x90,0xeb, - 0x73,0x36,0x36,0x00,0xf7,0x39,0x3b,0x37,0x80,0x3f,0xd6,0x71,0xcf,0x27,0xd7,0xe7, - 0xec,0x82,0x00,0xdc,0xe7,0x6c,0x5c,0x00,0x5f,0x75,0xd6,0xeb,0x87,0x06,0xe4,0x52, - 0x75,0x5a,0xf7,0xf4,0xbd,0x55,0x31,0xdd,0xab,0xd3,0x43,0xf7,0x5e,0xfc,0xeb,0x24, - 0x4f,0x09,0xd8,0xab,0xfa,0xdb,0xea,0xf2,0x55,0x01,0xef,0xbb,0xbe,0x6f,0x4d,0x0e, - 0xc0,0xad,0xb6,0xfe,0x26,0x00,0xb3,0x5e,0x7c,0x75,0x00,0xe6,0x7b,0xf1,0x74,0xfa, - 0x9e,0xe2,0x7c,0x4f,0xed,0xc1,0xf7,0xb4,0x00,0xdc,0xfa,0xcc,0x35,0x01,0x58,0x71, - 0x2f,0xbe,0x36,0x40,0xe7,0x7d,0xeb,0xdd,0x6a,0xdb,0xd6,0x88,0x38,0x74,0x2e,0xd7, - 0x72,0x6e,0x36,0xee,0x8c,0x1e,0xc6,0x9d,0x19,0x80,0xdb,0xb8,0xd7,0x05,0x60,0xc5, - 0xbd,0xb8,0x3e,0x40,0x67,0xbc,0x59,0x45,0xbc,0x1b,0x02,0xb0,0xe2,0x5e,0x3c,0x3b, - 0x40,0x67,0x31,0x34,0x30,0x06,0xdf,0x77,0x1b,0x03,0x70,0xf3,0x35,0x37,0x00,0x2b, - 0xee,0xb1,0xf3,0x02,0x74,0xe6,0x6b,0x11,0x7d,0xf9,0xde,0xd9,0x14,0x80,0x5b,0x9f, - 0x5c,0x1c,0x80,0xf9,0x3e,0xb9,0x24,0x00,0xf7,0x7d,0xf2,0xf6,0x00,0x5c,0xf7,0x8b, - 0x7e,0x17,0xf1,0x7d,0x72,0x59,0xc0,0xb7,0x12,0x9d,0xcb,0xbc,0x50,0xe8,0x93,0xbf, - 0x0d,0xd0,0x59,0x9f,0xbc,0x33,0xc0,0x8f,0xef,0x93,0xcb,0x03,0xec,0x54,0x67,0x3d, - 0xeb,0xae,0x80,0x75,0xf2,0x7d,0xf2,0xee,0x00,0xdc,0xf7,0xc9,0x7b,0x02,0xf2,0x6e, - 0x7d,0x72,0x95,0xdb,0xbb,0xaa,0x5b,0x91,0xae,0x95,0xdc,0x03,0x2b,0x9c,0xff,0x3f, - 0x04,0x8c,0x5b,0xef,0xb0,0xfb,0x03,0x70,0xdb,0x97,0xab,0xc8,0x5b,0x19,0xba,0xcb, - 0xab,0xdc,0x5e,0xda,0x16,0xc1,0x5b,0x41,0x7f,0x6a,0x6b,0xf1,0x3e,0x1c,0x10,0xb3, - 0xda,0x58,0xdf,0x5b,0xe3,0xfa,0x9e,0xea,0xad,0xef,0x59,0x3f,0x7b,0x3a,0xc0,0xc6, - 0xfa,0xd9,0x33,0x01,0x98,0xef,0x67,0x6b,0x03,0x70,0xdf,0xcf,0xd6,0x05,0xe0,0xbe, - 0x9f,0xad,0x0f,0xc0,0xad,0x9f,0x35,0x47,0x60,0x6b,0xf9,0x9d,0x44,0xe7,0x64,0x3d, - 0x48,0xef,0xbb,0xf9,0x2d,0xfa,0x9d,0x08,0x1b,0x7d,0x1e,0x50,0xce,0x2a,0x9e,0x67, - 0xdd,0x17,0x5f,0x65,0x78,0x2f,0xb7,0xf7,0xe3,0x6f,0x33,0xd8,0xeb,0xdf,0x15,0x19, - 0x72,0x52,0x1e,0x0b,0xdf,0x56,0x55,0xaf,0x35,0x70,0x12,0x75,0x83,0x7a,0xd0,0xd9, - 0x5a,0x6e,0x0b,0xe0,0xc2,0x26,0xe4,0xb6,0xbb,0xb5,0x54,0x5d,0x6b,0xba,0xb6,0x73, - 0x0d,0x5a,0xdd,0x9e,0x1a,0x42,0x8e,0x72,0x2d,0x8f,0x3f,0x8c,0xc0,0xcd,0x66,0x68, - 0xc4,0x78,0xde,0x66,0x58,0x04,0x6e,0xb9,0x3e,0x3a,0x02,0x53,0xae,0xe5,0xfa,0x47, - 0x11,0xb8,0x7e,0xcf,0xb5,0x5c,0x1f,0x13,0x81,0x6b,0xae,0xa7,0x32,0x2f,0xc7,0x46, - 0xe0,0x8d,0x94,0x7f,0x1c,0x81,0xd9,0x79,0x3a,0x2e,0x02,0xd3,0xef,0xc0,0x4f,0x72, - 0xbe,0xc3,0x23,0xbe,0x79,0x1d,0xe7,0x9e,0xa3,0x46,0x44,0xe0,0x0d,0x7c,0x8e,0xb2, - 0xbc,0x1f,0x1f,0xa1,0x7b,0xc9,0x7a,0x72,0x04,0x4f,0x71,0x5d,0x47,0xcb,0xcb,0x76, - 0xee,0x4d,0xb5,0x69,0x8b,0xe8,0x03,0xba,0xb6,0x6a,0xaf,0x39,0x5b,0xc3,0xb1,0xdf, - 0x0b,0x58,0xcb,0x3a,0x7e,0x2f,0xfa,0xc8,0xe5,0x5a,0x75,0xed,0xe9,0xfa,0x90,0x3e, - 0xdb,0x43,0xe1,0x3b,0xdd,0x8e,0x80,0xf5,0xfb,0x2a,0x2b,0x7c,0x6f,0xf9,0x20,0x00, - 0xaf,0x77,0x7d,0x68,0x67,0xc0,0xf8,0x1f,0xf0,0xec,0x7c,0x44,0x5f,0x1f,0x16,0xc9, - 0x1f,0xb9,0x78,0xb7,0x47,0xf0,0xda,0xd9,0xbf,0xd4,0xd6,0x72,0xf5,0x71,0x51,0xbc, - 0x9d,0x2e,0x5e,0xd5,0x75,0xa4,0xeb,0x73,0xfa,0xec,0x70,0xf1,0xee,0x72,0xf1,0xce, - 0x23,0xf6,0x59,0x00,0xee,0xe3,0xfd,0x1f,0xe3,0xfd,0x8c,0xf1,0x75,0xd2,0xd7,0xe7, - 0x45,0x72,0xa7,0x8b,0xf7,0xbd,0x08,0x5e,0x07,0xe3,0x55,0xdb,0xc7,0x19,0xef,0xee, - 0xa2,0x78,0xb3,0x58,0x88,0x57,0x75,0x5f,0x6a,0x1d,0x88,0xf0,0xa9,0xbf,0x6d,0x9f, - 0xec,0x65,0x1c,0x55,0x2e,0xb6,0xae,0x00,0x7c,0xa2,0xeb,0xe9,0x5f,0x07,0xe4,0xab, - 0xcb,0x71,0xbf,0x25,0x57,0xff,0x97,0x60,0xb5,0xfd,0xbb,0x00,0xbc,0xc1,0x71,0xf5, - 0x83,0xb7,0xc6,0xfe,0x1d,0xe7,0x66,0x71,0xe8,0xdd,0xe6,0xb6,0x83,0x36,0xf9,0x3c, - 0x47,0xc4,0x6b,0xba,0xf7,0x23,0xc6,0x56,0xdd,0xd7,0x9c,0xcb,0x55,0x19,0x74,0xc1, - 0x9d,0x6f,0xb5,0xd3,0x1c,0x9b,0xae,0xc4,0xe9,0x76,0x50,0x67,0xef,0x6f,0x65,0x3c, - 0xc3,0xcb,0xb3,0x02,0xd6,0x9b,0x67,0x5a,0xb1,0x8d,0xc4,0xfa,0x44,0xe0,0xd5,0x9c, - 0x8f,0x62,0x7d,0x23,0xf8,0xaa,0xb3,0xf3,0xd2,0x2f,0x02,0xb7,0x39,0xf7,0x8f,0xc0, - 0x34,0x3e,0x7b,0x06,0x1a,0x10,0x81,0x6b,0x5c,0x17,0x24,0x4f,0xfa,0x1c,0x98,0x09, - 0xfe,0x57,0xa0,0xba,0xc8,0xff,0xb1,0xf0,0xf5,0x24,0xbf,0x8e,0xa5,0xd2,0xfd,0x39, - 0xbe,0x44,0xff,0x57,0xc2,0xf7,0xa7,0x12,0x29,0xd4,0xc5,0xbe,0x82,0xba,0x98,0xb9, - 0xba,0xb8,0xd0,0xcd,0xbf,0xaf,0x74,0xaf,0x8b,0x4d,0x3d,0xe8,0xac,0x2e,0x9e,0x13, - 0xc1,0x6d,0x62,0x5d,0x1c,0xe7,0xf6,0x92,0xea,0xc6,0xea,0x9c,0xb8,0x86,0x63,0x5d, - 0xcd,0x5b,0x4a,0xce,0x42,0x57,0xf3,0x96,0x45,0xe0,0xfb,0xfb,0x71,0xc4,0x78,0xde, - 0x66,0x79,0x04,0x6e,0x75,0xf1,0xae,0x08,0x6c,0x99,0xab,0x8b,0x77,0x47,0xe0,0xbe, - 0x2e,0xfe,0x3e,0x02,0xf7,0x75,0xf1,0x9e,0x08,0xdc,0xea,0xe2,0xbd,0x11,0x98,0xed, - 0xd9,0xfb,0x22,0x30,0x5f,0x17,0xef,0x67,0x5d,0xbc,0xcf,0xd5,0xc5,0x95,0x11,0x78, - 0x71,0x5d,0x7c,0x20,0x42,0x67,0x75,0xf1,0xc1,0x08,0xde,0x03,0xac,0x8b,0x96,0x97, - 0x71,0x6e,0x6f,0x77,0xb2,0x2e,0xea,0x7a,0x3d,0xc8,0xfc,0x69,0x5e,0x2f,0x8d,0xdd, - 0x6b,0x60,0x4d,0x92,0x6b,0xc9,0xd7,0xdf,0x56,0x53,0x2e,0x8a,0xdf,0xaf,0x81,0x17, - 0x47,0xe0,0xbe,0xa6,0x5c,0x12,0x31,0xd6,0xc5,0x8c,0xe5,0x52,0xfa,0xaa,0x2d,0x92, - 0x2f,0x75,0xb1,0x7d,0x11,0xc1,0xab,0x61,0x8c,0xb5,0x8c,0xad,0x2e,0x76,0xaf,0x77, - 0x13,0x92,0x3c,0x89,0xfc,0x09,0x2e,0xb6,0x2b,0xe2,0xf7,0xeb,0xdd,0x95,0x11,0xb8, - 0x8f,0x6d,0x22,0x63,0xbb,0x92,0xb1,0xd4,0xd1,0xd7,0xa4,0x22,0xb9,0xce,0xc5,0xb6, - 0x3b,0x82,0x37,0x81,0xb1,0x4d,0x62,0x6c,0x33,0x8b,0x6a,0xdb,0xe4,0x24,0xcf,0x24, - 0x7f,0xb2,0x5b,0xeb,0xab,0x39,0xa6,0xaf,0x6d,0x53,0x22,0x70,0x5f,0xdb,0xa6,0x45, - 0xe4,0x61,0x8a,0xe3,0x5e,0x4b,0xae,0xaf,0x6d,0xd3,0x23,0x70,0x5f,0xdb,0x66,0x44, - 0xc4,0x39,0x9d,0xf3,0xb0,0x38,0x66,0xba,0x79,0x74,0xd1,0x46,0xe7,0xa6,0xf6,0x93, - 0x9d,0x6e,0x2f,0xc7,0x56,0xdd,0x34,0xea,0xac,0x7e,0xd5,0xbb,0x33,0xba,0xb7,0xa8, - 0xb6,0xcd,0x72,0xba,0xae,0xa2,0xda,0x36,0x9b,0xe7,0xd0,0xd7,0xb6,0x39,0x3c,0x97, - 0xbe,0xb6,0x35,0x44,0xe0,0xbe,0xb6,0x35,0x46,0xf0,0x1b,0x5c,0x6d,0xbb,0x29,0x02, - 0xb7,0x39,0xcf,0x8d,0xc0,0xea,0x5d,0x6d,0x9b,0x1f,0x81,0xcf,0x72,0xb5,0xed,0x00, - 0x41,0x5d,0x9b,0x1f,0x0b,0xff,0x5b,0xb4,0xda,0xa6,0xb9,0xb2,0x3a,0x56,0xca,0xef, - 0x40,0xca,0xe9,0x57,0x82,0x9a,0xa8,0xbd,0x41,0xf9,0x9a,0x47,0xeb,0x71,0x07,0x0a, - 0x9e,0x05,0xed,0xd9,0xbb,0xdc,0xd5,0x46,0xd5,0x1d,0x94,0xae,0x72,0xfa,0x3c,0xc8, - 0x7d,0x1f,0x1e,0xc8,0xef,0xc3,0x4b,0xdc,0x3b,0xd6,0x20,0x01,0xbe,0x90,0x73,0x3a, - 0x58,0x80,0xb5,0xbb,0xf7,0x8f,0x43,0x04,0xb8,0xf9,0x39,0x94,0x7e,0x1a,0x9c,0x9f, - 0xc3,0x04,0xb8,0xf9,0x39,0x5c,0x80,0x79,0x3f,0x83,0x05,0xb8,0xfd,0x7f,0x6d,0x88, - 0xc0,0xf7,0x60,0x7e,0xe3,0x52,0xec,0x08,0xc1,0xff,0x7d,0x86,0xf0,0xbd,0x49,0xff, - 0xcf,0x7d,0x14,0xff,0xc7,0x3d,0x31,0xc9,0xfa,0x5b,0x6d,0x34,0x3f,0x9a,0x3b,0x9b, - 0x67,0xb9,0x74,0xff,0xdf,0x9a,0xde,0xbf,0x4d,0x99,0xae,0x4c,0xd7,0xff,0x01,0xd2, - 0xfc,0xad,0x6f,0xa8,0x27,0x00,0x00 + 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x02,0xff,0x6d,0x59,0x69,0x90,0x55,0xd5, + 0x11,0xbe,0xa7,0xcf,0x61,0x06,0x90,0xb8,0x1b,0xd7,0x88,0x8a,0x55,0x56,0x14,0x70, + 0x0a,0x11,0x06,0x18,0xd4,0x8c,0xcb,0x58,0x81,0x52,0xc3,0xb8,0x11,0x17,0x16,0x67, + 0x52,0x6a,0x4a,0x4c,0x04,0x05,0x65,0x15,0x05,0x91,0x45,0x88,0x18,0x93,0xa0,0xfe, + 0x88,0x29,0x51,0x5c,0x71,0xc1,0xad,0x34,0x61,0x1d,0x04,0x37,0x12,0x31,0x8e,0x80, + 0x14,0xd1,0x10,0xa3,0x65,0x2c,0x0b,0x63,0x89,0x46,0x9d,0x9c,0x7e,0xdf,0xd7,0xbc, + 0x7e,0xcf,0x79,0x55,0xb7,0xee,0xed,0xaf,0x97,0xd3,0xa7,0x4f,0x9f,0xee,0x73,0xef, + 0x8b,0xd2,0xab,0xb6,0x88,0xa1,0xe8,0x5e,0x74,0x2d,0xd6,0xa7,0xa2,0xf4,0xdb,0xaf, + 0x90,0x22,0xf0,0xde,0x97,0xf7,0xa1,0xbc,0x9f,0x9e,0xef,0x7b,0x15,0x35,0x25,0x7e, + 0xd3,0xf0,0xe6,0xe1,0x7d,0xc7,0x4f,0x68,0xe9,0xdb,0xff,0xe4,0x3a,0xd5,0xdb,0xbb, + 0x88,0x25,0x7d,0xe5,0xed,0x53,0xd4,0x16,0x5d,0xf2,0x5d,0x4d,0x5e,0x33,0xe6,0xaa, + 0x71,0x8a,0xbf,0x9d,0xaf,0x6d,0xf9,0xda,0x37,0xeb,0xa7,0x92,0xbd,0xa2,0x38,0x8d, + 0xf2,0x7a,0x9d,0x9d,0x35,0x4e,0x86,0x0b,0x45,0x2f,0xde,0x0d,0x0b,0xc4,0x92,0xc3, + 0x84,0x58,0x57,0x87,0x45,0x62,0x3d,0x1c,0x96,0x88,0xed,0xeb,0xb0,0x2e,0xc4,0x0e, + 0x74,0x58,0x0d,0xb1,0x43,0x1c,0x56,0x4b,0xec,0x08,0x9d,0x6f,0xb6,0x6e,0xe3,0x36, + 0x65,0xab,0x6f,0x97,0x62,0x51,0x14,0x87,0x91,0xde,0x46,0xfa,0x70,0xd2,0x2f,0x64, + 0xa7,0x8f,0xe1,0x3c,0x8c,0x3e,0xda,0xd1,0x7b,0x4b,0x25,0x5f,0xe9,0xa3,0x39,0x57, + 0x1d,0x4b,0xe9,0x43,0xc9,0x3b,0x40,0x60,0x5b,0xe9,0x03,0xb2,0x07,0xea,0xc3,0xd1, + 0x59,0x26,0xd2,0x9f,0x83,0xb2,0x8c,0xfa,0x7f,0x14,0xed,0x1d,0x9c,0xe9,0x5a,0xce, + 0x49,0x4a,0x78,0x2a,0xc5,0xa9,0x96,0x97,0xca,0x77,0xa3,0x7c,0x20,0xbf,0x3b,0x79, + 0xdd,0xa8,0xbf,0x2f,0x9f,0x4d,0xff,0x40,0xf2,0xd5,0xe6,0x09,0xd4,0x3f,0x31,0x5f, + 0x7d,0x1c,0x5d,0xc7,0x35,0x38,0x32,0x5b,0xb3,0x98,0xd6,0xd0,0x4e,0x4d,0x27,0x97, + 0xda,0x1d,0x40,0xbe,0xca,0x0f,0x21,0x3d,0x90,0x98,0xd9,0xad,0x77,0xf2,0x83,0x9c, + 0xbd,0x13,0x38,0xef,0x06,0xce,0xfb,0x40,0xe6,0xaa,0xe1,0x8d,0x9c,0x9f,0xd9,0x39, + 0x8b,0xeb,0x6b,0x74,0x13,0xf3,0xc7,0xe8,0x11,0xcc,0x09,0xa3,0x9b,0x99,0x3f,0x46, + 0x8f,0x64,0x1e,0x19,0x7d,0x39,0x73,0xc9,0xe8,0x2b,0xf2,0xd5,0xd3,0xd1,0xad,0x8c, + 0x9f,0xc6,0xf3,0x7a,0xfa,0x9d,0x9c,0x7f,0x37,0xd0,0xde,0x11,0x99,0x9e,0x98,0xef, + 0xd7,0x13,0x33,0xfd,0x49,0xa5,0x7d,0x55,0x14,0xbd,0x73,0xe4,0x95,0x77,0x23,0x6d, + 0x5e,0x4e,0xdf,0x27,0x39,0xd9,0x9b,0xaa,0x62,0x36,0x99,0xfb,0xc0,0x74,0xa7,0x50, + 0xb7,0x9e,0xb2,0x93,0x9d,0xec,0xd4,0xaa,0x38,0x4d,0xe3,0x5a,0x9b,0xee,0x74,0xca, + 0x34,0x93,0x37,0xd9,0xf1,0x66,0x90,0x57,0x47,0xbf,0xbc,0xdd,0x9b,0xb9,0x27,0x4c, + 0x76,0xa6,0xf3,0x7f,0x1a,0xf9,0x26,0x7b,0x4b,0xbe,0xba,0x3b,0xd9,0x5b,0x9d,0xbf, + 0x4d,0xe4,0x1b,0x6f,0x16,0xc7,0xab,0xa7,0x1d,0xcf,0x9b,0x4d,0xbd,0xe6,0x4e,0x78, + 0xb7,0xd1,0x57,0x1b,0xff,0x26,0xc7,0x9b,0x53,0x35,0x47,0xcf,0xbb,0xdd,0xcd,0xb1, + 0x9a,0x37,0xd7,0xe9,0xd5,0x57,0xf1,0xe6,0xd1,0x97,0x3a,0xc7,0xb3,0xf9,0xce,0x67, + 0xce,0x9a,0xec,0x02,0x62,0x53,0xa9,0xe3,0xed,0xdc,0xe1,0xe2,0x3b,0x8d,0xf1,0x30, + 0xde,0x42,0x37,0xdf,0xfa,0x3d,0xbc,0x03,0x4a,0xf9,0xb4,0x88,0x39,0x33,0x85,0x6b, + 0x38,0x83,0x6b,0x70,0x2b,0x63,0x38,0x9b,0x31,0x99,0xc3,0x39,0xce,0xa5,0xcf,0x0b, + 0x38,0xe6,0x42,0xee,0xb9,0xc5,0xcc,0x87,0x89,0xce,0xff,0xe5,0x9a,0x33,0xdf,0x74, + 0x74,0x18,0xfd,0x6c,0xbe,0x3a,0x62,0x99,0xff,0x9c,0xd2,0x59,0xe9,0x87,0xb9,0x22, + 0xbc,0xcc,0x5a,0xa3,0x3c,0x7d,0x5e,0x53,0x9a,0xf9,0x77,0x8d,0x46,0xaf,0x2d,0xd1, + 0xd3,0x4f,0x37,0xfa,0x75,0x84,0xe6,0x54,0xdd,0x37,0x6f,0x71,0xaf,0x47,0xfa,0xb2, + 0x99,0xb9,0xfa,0x16,0xeb,0xc5,0x66,0xf6,0x96,0xe0,0xf6,0x55,0x3b,0xf7,0xb5,0xf1, + 0xb7,0xb9,0x3a,0xf7,0x1e,0x9f,0x7d,0xfd,0xd8,0x51,0xb5,0x2f,0x77,0x96,0x7a,0x58, + 0x99,0xfe,0x94,0xfb,0xd8,0xe8,0x2f,0xe9,0x8f,0xfa,0x27,0x01,0xb6,0xbc,0x7e,0x6d, + 0x40,0x9d,0xd1,0x35,0x52,0x7e,0xd7,0x80,0x1a,0xd5,0xce,0xfd,0xad,0x7c,0x93,0xed, + 0x9e,0x9f,0x3b,0x5c,0x6c,0x06,0xa8,0x73,0xc5,0x8e,0xd3,0x8c,0xae,0x0f,0x08,0xc6, + 0x9e,0x5a,0x97,0xe9,0x5f,0x5f,0xd8,0x5f,0x8c,0x1e,0x1d,0x2a,0x6b,0xd0,0x75,0x99, + 0xfe,0x91,0x93,0x9f,0x10,0x2a,0x6b,0xf4,0x74,0x8e,0xa7,0xbe,0xff,0x21,0x3f,0x0f, + 0xe5,0xdc,0x0e,0xcd,0xdc,0x67,0x39,0x97,0x2e,0x45,0xe5,0x8f,0x2e,0xe4,0xde,0x16, + 0x8b,0xe7,0x32,0xa1,0x72,0x1a,0xcb,0xe7,0xc9,0x50,0x6c,0x08,0xe9,0x17,0x88,0x29, + 0xbf,0x2d,0xa0,0x26,0x75,0xa3,0xfd,0x1e,0x02,0xfb,0xa1,0xca,0xbe,0x94,0x7a,0x06, + 0x74,0x7e,0x20,0xc0,0x54,0x76,0x08,0xe9,0xbd,0xa5,0x32,0x06,0xfb,0x0b,0xce,0x0e, + 0xbd,0x33,0xa5,0x79,0xa0,0xfd,0x51,0xb1,0x46,0xd6,0xfc,0xde,0x79,0x06,0x9a,0xaf, + 0x8b,0x12,0x62,0xde,0x4e,0x4c,0x6b,0xed,0x6f,0x12,0xf6,0x4b,0xab,0xc3,0xee,0x4c, + 0xd8,0x5f,0x75,0x6e,0xcd,0x16,0x27,0xac,0x8d,0xbf,0x42,0x9e,0xbf,0xee,0xb9,0x25, + 0x09,0xcf,0x2a,0xf7,0x68,0x2a,0xc7,0xb6,0x2d,0xa1,0x27,0x0e,0xc8,0x76,0x85,0x39, + 0x51,0x30,0x57,0x76,0x67,0xa4,0x0b,0x73,0x52,0xf7,0xd3,0x99,0x11,0x7b,0xca,0xe8, + 0xfb,0xa4,0x4c,0x6b,0xee,0xfe,0x2d,0x54,0xd2,0x3b,0x48,0x7f,0x99,0xad,0xf5,0x65, + 0x3c,0xfe,0x97,0x9f,0x35,0xaf,0x4e,0x14,0xd8,0xd7,0xfb,0x50,0xee,0x99,0x41,0x82, + 0x7d,0x71,0x6e,0xd6,0x52,0xbd,0xc1,0x02,0x6c,0x90,0x94,0xd7,0xf4,0x56,0xc6,0xa9, + 0x41,0xc0,0xd7,0x78,0xfd,0x24,0x63,0xba,0x47,0x86,0x0a,0xf6,0x8d,0xda,0x1f,0xca, + 0xb8,0x9f,0x22,0xc0,0x57,0x67,0x19,0xa5,0x4f,0x15,0x60,0xba,0x7f,0xd6,0x13,0x6b, + 0x24,0xb6,0xd3,0x61,0x67,0x08,0x64,0x1b,0x39,0xa6,0x62,0x67,0x52,0x4f,0x79,0x3f, + 0x23,0xd6,0x24,0xf0,0xa5,0x28,0xd5,0x2a,0x60,0x67,0x0b,0x70,0x95,0x1f,0x91,0x11, + 0xf5,0xf7,0xca,0x04,0xdc,0x64,0x6d,0x9c,0x61,0x1c,0xe7,0x53,0x37,0xce,0x70,0xd2, + 0xc3,0xdc,0x38,0xe7,0x50,0x37,0xb8,0x71,0xce,0x15,0xe0,0xc3,0xdd,0x38,0xbf,0x4c, + 0xc0,0xaf,0x4c,0x90,0xb5,0x71,0x46,0x08,0xe6,0xa9,0x75,0xc0,0x62,0x71,0x3e,0x31, + 0xcd,0xab,0xf3,0x18,0xd7,0x0b,0x04,0xb2,0xca,0x9b,0x41,0xec,0x22,0x81,0x5d,0xe5, + 0x4d,0xe1,0x39,0x6b,0xa4,0x00,0xd7,0xd8,0xeb,0xf9,0xe6,0xce,0x80,0x33,0x50,0x9d, + 0x8b,0xfd,0xe2,0x00,0x7c,0x0a,0x73,0xed,0xae,0x00,0xcc,0x74,0x7e,0x4b,0x9d,0x66, + 0xa7,0x73,0x77,0x00,0x6e,0x3a,0xbf,0x0b,0xc0,0xce,0x63,0xde,0xff,0x3e,0xc0,0x8e, + 0xe2,0x4f,0x64,0x4c,0xeb,0xc1,0x92,0x00,0x7f,0x94,0xb7,0x24,0xeb,0x69,0x7d,0xb8, + 0x87,0xb8,0xe6,0xde,0x7d,0xdc,0xbc,0x5f,0x67,0x9e,0xe2,0xf7,0xe6,0x4b,0x31,0xcd, + 0x3f,0x7d,0xfe,0x4a,0xdf,0x1b,0x98,0x8f,0x8a,0xaf,0xe1,0x58,0xf7,0xd3,0xae,0xee, + 0xbf,0xf5,0xc4,0x96,0x12,0xd3,0xfd,0xa7,0x6b,0xa3,0x3e,0x2e,0x0b,0xc0,0x0b,0xae, + 0xa1,0x62,0x0f,0x07,0xcc,0x4b,0x79,0x26,0xf7,0x28,0xe5,0x6c,0x0d,0x15,0x7b,0x2c, + 0x40,0x56,0x79,0xa6,0xfb,0x24,0x75,0x15,0x33,0xb9,0x67,0x02,0xf0,0x65,0x01,0xb1, + 0xd2,0xfa,0xf5,0x22,0x6b,0x97,0xd9,0x7f,0x29,0xc0,0x67,0x9f,0x23,0x7f,0x61,0xcc, + 0xfd,0xba,0xaf,0x0c,0xc0,0x5b,0x8b,0x72,0x9c,0x57,0x05,0xe0,0xe6,0xc3,0xea,0x00, + 0x7b,0xab,0x9c,0xfd,0xb5,0xb4,0x5f,0x38,0xff,0xd7,0x05,0xc8,0xae,0xe5,0xba,0x6a, + 0xfd,0x5c,0xcf,0x75,0x6d,0xe5,0xba,0xaa,0xdc,0x2b,0xc4,0x4d,0x6f,0x43,0x80,0xae, + 0xe2,0x2d,0x59,0x46,0xeb,0xf3,0x46,0xce,0x69,0x94,0xd6,0xa2,0x7c,0x7f,0x95,0xd8, + 0x86,0x50,0xde,0x07,0xa3,0x04,0x78,0x28,0xe5,0x2c,0xea,0xde,0x55,0x02,0xdc,0x5f, + 0xab,0x69,0xe3,0x6a,0x01,0x5f,0xfb,0xd9,0x7a,0x62,0xd7,0x08,0xf0,0xc5,0xa9,0x6c, + 0xf7,0x5a,0x01,0x5e,0x94,0x7a,0x3b,0xb0,0x5f,0x09,0xf0,0x5a,0x37,0xfe,0x75,0x94, + 0x0b,0x4e,0x6e,0xbc,0x00,0xd7,0x3e,0xb9,0x8e,0xd8,0x04,0x81,0xfe,0x78,0xb7,0x87, + 0x6f,0xa0,0xae,0x38,0xdd,0x89,0x02,0xbc,0xdd,0xe9,0x4e,0x12,0xe8,0x4f,0x74,0xba, + 0x37,0x51,0x37,0x3a,0xdd,0xc9,0x02,0xbc,0xc1,0xe9,0x4e,0x11,0xe8,0x4f,0x76,0xba, + 0x63,0x19,0xb3,0xc2,0xc5,0xec,0x66,0x01,0xee,0x2f,0x8b,0xd9,0x4c,0x01,0xdf,0xc7, + 0x6c,0x96,0x00,0xf7,0x31,0xbb,0x4d,0x80,0xfb,0x98,0xcd,0x11,0xe0,0x3e,0x66,0x73, + 0x29,0xe7,0x63,0x36,0x4f,0x80,0xfb,0x98,0xcd,0x17,0xe8,0xcf,0x73,0xbe,0xdf,0x41, + 0x5d,0x1f,0xb3,0x85,0x02,0xdc,0xc7,0x6c,0x91,0x40,0x7f,0xa1,0xd3,0xbd,0x93,0xba, + 0x3e,0x66,0x8b,0x05,0xb8,0x8f,0xd9,0x5d,0x02,0x7d,0xe5,0x59,0x1d,0x6c,0x11,0xc4, + 0x52,0x79,0xa7,0x64,0x0b,0xda,0xdb,0x14,0xb3,0xfd,0xb1,0x54,0x50,0xeb,0x74,0xff, + 0xce,0x24,0xf6,0xa0,0xa0,0x97,0x2e,0x75,0x75,0xf1,0x21,0xc1,0x5e,0xa8,0x77,0x35, + 0x6e,0x99,0x00,0x7f,0x24,0xcb,0x68,0xad,0x7a,0x58,0x80,0x35,0xb0,0x57,0xae,0x90, + 0x72,0xbd,0x52,0xde,0x23,0xf9,0x5a,0xce,0xfa,0xf4,0x08,0x6d,0xeb,0x3b,0xdf,0xa3, + 0x82,0x9e,0xdb,0xe8,0x6c,0x3f,0x26,0xc0,0x6d,0x5f,0x3f,0x2e,0xc0,0x36,0x66,0xae, + 0xd2,0x4f,0x08,0xb0,0xb3,0x78,0xee,0xd6,0xda,0xb7,0x82,0xb6,0x97,0x3b,0xdb,0x4f, + 0x76,0x62,0xfb,0x29,0x01,0xfe,0x6a,0xa6,0x94,0x7e,0x5a,0x80,0x99,0x2d,0x1b,0xf3, + 0x19,0x01,0xcf,0xdb,0xd6,0xfb,0x17,0x39,0xb2,0xa5,0x3e,0x90,0xe0,0x87,0xce,0xe5, + 0x19,0xce,0xcd,0xc6,0x7d,0xae,0x93,0x71,0x9f,0x17,0xe0,0x36,0xee,0x0b,0x02,0x6c, + 0x04,0x7b,0x87,0x8d,0xfb,0xa2,0x80,0x67,0x7a,0x2f,0x55,0xe9,0xbd,0x2c,0xc0,0x46, + 0x56,0xe9,0xfd,0x59,0xc0,0x5b,0xc3,0x75,0x5c,0x29,0x58,0x4b,0x7d,0x77,0x31,0xbf, + 0x56,0xd1,0xaf,0x95,0xce,0xfe,0x6a,0x01,0xbe,0xde,0xea,0x23,0xf5,0xf4,0x9d,0xda, + 0xc6,0x5c,0x27,0x90,0x5b,0x2b,0x95,0xf5,0xb6,0x4d,0xc0,0xb3,0xdc,0x79,0x45,0x70, + 0x16,0x5b,0xea,0xfc,0xd8,0x28,0xc0,0xbd,0x1f,0xaf,0xd2,0x8f,0x8d,0xce,0x8f,0xd7, + 0x04,0xb8,0xf9,0xf1,0x06,0xf5,0xae,0x70,0x35,0xff,0x4d,0x81,0xdc,0x1b,0x52,0x3e, + 0x13,0x6c,0x12,0xe0,0x8d,0xce,0xaf,0xbf,0x0a,0x70,0xcd,0x79,0x3d,0xdf,0x2d,0x2a, + 0x8d,0x5d,0x53,0x7a,0xcf,0xdd,0x2c,0x38,0xf3,0x69,0xbc,0xda,0xa4,0x5c,0xdb,0xdf, + 0x16,0xf0,0x6c,0x2e,0xef,0x08,0xec,0xe8,0x7b,0x61,0x1b,0xb1,0x76,0x81,0xdc,0x3b, + 0x6e,0x0f,0x6d,0x11,0xe4,0x42,0x93,0xeb,0x27,0x5b,0x05,0xb8,0xae,0x8f,0xed,0x8f, + 0xf7,0x04,0x6b,0x3b,0x9f,0xfb,0x63,0xa7,0xdb,0x1f,0xca,0xdb,0x9e,0xaf,0x0f,0x98, + 0x67,0xdb,0x9d,0xfd,0x7f,0x08,0xc6,0x7d,0xd1,0x61,0xef,0x0b,0x70,0xcb,0xfd,0x9d, + 0xd4,0xfb,0x40,0x2a,0xe9,0x9d,0x2e,0x5f,0xef,0x4e,0xd0,0xdb,0x4e,0x7b,0x1f,0x48, + 0xd9,0xdf,0x7f,0x0b,0x7c,0x56,0x99,0x65,0xdc,0x63,0x9f,0x08,0xf6,0xf4,0x72,0xbe, + 0x1f,0x1b,0xfe,0x19,0xf1,0x67,0xf9,0xae,0xd9,0x23,0x9f,0x92,0x15,0xff,0x2f,0x6b, + 0x63,0x1f,0xda,0x53,0x7d,0x95,0x55,0x3d,0x7d,0x9f,0xda,0x4d,0xbd,0x35,0x7c,0xef, + 0xbc,0x96,0xef,0x59,0x5f,0x0b,0x74,0x8d,0xfe,0x86,0x7a,0x73,0xb2,0x6f,0x4a,0x7f, + 0x2b,0x90,0x51,0x7c,0x16,0xb1,0x0e,0x01,0xae,0x36,0x6f,0x26,0xa6,0x05,0x52,0x71, + 0x7d,0x87,0x1d,0xc7,0x35,0x0d,0x11,0xb8,0x9e,0x2b,0xf5,0xfd,0x61,0x6a,0x02,0xb6, + 0x84,0x2f,0x08,0x56,0xdf,0xde,0x61,0xaf,0x9f,0xe6,0xf6,0x6b,0x7b,0x00,0x6e,0xeb, + 0xf7,0x6e,0x00,0x66,0xf5,0x6d,0xab,0x3b,0x8f,0x29,0x6f,0x4b,0xbe,0xb6,0xf2,0x3c, + 0xb6,0xc5,0xf5,0x8d,0xda,0x88,0xbe,0x15,0x5d,0xdf,0xda,0x2f,0x02,0xf7,0x97,0xf5, + 0xad,0xfd,0x23,0xf8,0xbe,0x6f,0x1d,0x14,0x81,0xfb,0xbe,0x75,0x70,0x04,0xee,0xfb, + 0xd6,0x21,0x11,0xb8,0xef,0x5b,0x87,0x51,0xce,0xf7,0xad,0xc3,0x23,0x70,0xdf,0xb7, + 0x8e,0x88,0xd0,0x57,0x9e,0xe9,0x1e,0x49,0x5d,0xdf,0xb7,0x7a,0x46,0xe0,0xbe,0x6f, + 0x1d,0x15,0xa1,0xdf,0xd3,0xe9,0x1e,0x43,0x5d,0xdf,0xb7,0x7a,0x45,0xe0,0xbe,0x6f, + 0x1d,0x1b,0xa1,0xdf,0xcb,0xe9,0x76,0x67,0xcc,0xc4,0xc5,0xec,0xc7,0x11,0xb8,0xbf, + 0x2c,0x66,0xc7,0x47,0xf0,0x7d,0xcc,0xfa,0x44,0xe0,0x3e,0x66,0x27,0x46,0xe0,0x3e, + 0x66,0x75,0x11,0xb8,0x8f,0x59,0x3f,0xca,0xf9,0x98,0x9d,0x14,0x81,0xfb,0x98,0xf5, + 0x8f,0xd0,0x3f,0xc9,0xf9,0x3e,0x80,0xba,0x3e,0x66,0x03,0x23,0x70,0x1f,0xb3,0xfa, + 0x08,0xfd,0x81,0x4e,0x77,0x30,0x75,0x7d,0xcc,0x86,0x44,0xe0,0x3e,0x66,0x0d,0x11, + 0xfa,0xca,0xb3,0x5e,0xdf,0x23,0x22,0x96,0xca,0xd3,0xba,0xa7,0xef,0xad,0x8a,0x69, + 0xae,0x5e,0x16,0x2b,0x7b,0x71,0x73,0xa6,0x2f,0x8e,0xc8,0x55,0x7d,0xb6,0xba,0x7c, + 0x7e,0xc4,0xfb,0xae,0xef,0x5b,0x17,0x44,0xe0,0x56,0x5b,0x2f,0x8c,0xc0,0xac,0x17, + 0x5f,0x14,0x81,0xf9,0x5e,0x7c,0x19,0x6d,0x5f,0xec,0x6c,0x8f,0xec,0xc4,0xf6,0xcf, + 0x23,0x70,0xeb,0x33,0x97,0x44,0x60,0xd5,0xbd,0xf8,0xd2,0x08,0x9e,0xb7,0xad,0x77, + 0xab,0x6d,0xf7,0x24,0xf8,0xa1,0x73,0xb9,0x94,0x73,0xb3,0x71,0x47,0x75,0x32,0xee, + 0xe8,0x08,0xdc,0xc6,0x1d,0x13,0x81,0x55,0xf7,0xe2,0xb1,0x11,0x3c,0xd3,0x6b,0xa9, + 0xd2,0x6b,0x8d,0xc0,0xaa,0x7b,0xf1,0x2f,0x22,0x78,0xe6,0xc3,0x55,0xf4,0xc1,0xf7, + 0xdd,0xab,0x23,0x70,0xb3,0x75,0x4d,0x04,0x56,0xdd,0x63,0xc7,0x45,0xf0,0xcc,0xd6, + 0x78,0xda,0xf2,0xbd,0x73,0x42,0x04,0x6e,0x7d,0x72,0x62,0x04,0xe6,0xfb,0xe4,0xa4, + 0x08,0xdc,0xf7,0xc9,0x1b,0x23,0x70,0xcd,0x17,0xfd,0x2e,0xe2,0xfb,0xe4,0x94,0x88, + 0x6f,0x25,0x3a,0x97,0x71,0xb1,0xdc,0x27,0xa7,0x46,0xf0,0xac,0x4f,0x4e,0x8f,0xb0, + 0xe3,0xfb,0xe4,0x8c,0x08,0x39,0xe5,0x59,0xcf,0x9a,0x19,0xb1,0x4e,0xbe,0x4f,0xde, + 0x12,0x81,0xfb,0x3e,0x39,0x2b,0x22,0xee,0xd6,0x27,0x17,0xb8,0xdc,0x55,0xde,0xec, + 0x7c,0xcd,0x63,0x0e,0xcc,0x76,0xf6,0x6f,0x8f,0x18,0x77,0xac,0xc3,0xe6,0x46,0xe0, + 0x96,0x97,0x0b,0xa8,0x37,0x2f,0x56,0xd2,0x0b,0x5c,0x2e,0xdd,0x97,0xa0,0x37,0x9b, + 0xf6,0x54,0xd6,0xfc,0x5d,0x14,0xe1,0xb3,0xca,0x58,0xdf,0xbb,0x37,0x96,0xfb,0x9e, + 0xf2,0xad,0xef,0x59,0x3f,0xbb,0x3f,0x42,0xc6,0xfa,0xd9,0x03,0x11,0x98,0xef,0x67, + 0x0f,0x46,0xe0,0xbe,0x9f,0x3d,0x14,0x81,0xfb,0x7e,0xb6,0x2c,0x02,0xb7,0x7e,0x76, + 0x7b,0x02,0x36,0x95,0xdf,0x49,0x74,0x4e,0xd6,0x83,0xf4,0xfe,0x05,0xbf,0x55,0xff, + 0x31,0x41,0x46,0xcf,0x03,0xaa,0xb3,0x80,0xfb,0x59,0xf3,0xe2,0xc3,0x80,0xf7,0x72, + 0x7b,0x3f,0xfe,0x38,0x40,0x5e,0x7f,0x63,0x02,0x62,0xf2,0x59,0x2c,0x7f,0x7b,0x55, + 0xbe,0xd6,0xc0,0x16,0xf2,0x76,0x75,0xc2,0xb3,0xb5,0x5c,0x19,0xa1,0xbb,0x8b,0x75, + 0xa8,0xcd,0xad,0xa5,0xf2,0x56,0xe5,0xab,0x8d,0x6b,0xb0,0xca,0xe5,0xd4,0x57,0xd4, + 0x51,0xdd,0x3d,0xe7,0x84,0x08,0xdc,0x64,0xbe,0x8d,0x18,0xcf,0xcb,0x7c,0x17,0x81, + 0x5b,0xac,0xf5,0x43,0xa0,0x62,0xaa,0x6b,0xb1,0x0e,0x09,0xb8,0x7e,0xef,0xd5,0x35, + 0x54,0x4c,0x92,0x7d,0xc7,0x06,0x5f,0xbf,0xfd,0x82,0x8f,0xb3,0x4b,0x4c,0xe5,0xff, + 0x4b,0x55,0xd6,0xd6,0x23,0x25,0xf0,0x2c,0xdf,0x6a,0x12,0xb0,0x66,0x77,0x76,0xae, + 0x4d,0xf8,0x76,0x5c,0x43,0x5c,0xd7,0xc8,0xe6,0xdc,0xc6,0xbc,0x53,0xb9,0xfb,0x13, + 0x6a,0xbc,0xae,0x9b,0xea,0x68,0x3c,0x9e,0x62,0x1c,0x5f,0x89,0x58,0xa7,0xd1,0xfc, + 0x16,0xb4,0xc9,0xc5,0x51,0x79,0x1b,0xf2,0xf5,0x26,0x6d,0x6e,0x88,0xe5,0x6f,0x70, + 0xaf,0x71,0x6d,0x3e,0x0c,0xe5,0x6f,0x29,0xaf,0xb3,0x87,0x29,0xcf,0x7a,0xcc,0x1b, + 0x11,0xe3,0xbf,0xce,0x7d,0xb1,0x89,0xb6,0xde,0xac,0xa2,0x37,0x39,0x7f,0xff,0x94, + 0xa0,0xb7,0x81,0xbd,0x49,0x65,0x1f,0xa7,0xbf,0x6f,0x55,0xf9,0xbb,0xcd,0xf9,0xab, + 0xbc,0xcd,0xf9,0xda,0x4a,0x9b,0x9b,0x9d,0x1f,0x7f,0xa7,0x1f,0xd7,0x85,0xf2,0x1c, + 0xda,0xdd,0x1c,0x66,0x12,0x7b,0x37,0xe2,0xfb,0x7a,0xbb,0xab,0x79,0x5b,0x22,0xf4, + 0xdf,0xa5,0xcf,0xdb,0x68,0x7f,0x6b,0x15,0xbd,0xcd,0xcd,0xe1,0x81,0x04,0xbd,0xcd, + 0x9c,0xc3,0x56,0xd7,0x4f,0xb7,0x47,0xcc,0x51,0x65,0xae,0x0c,0xf8,0x96,0xbb,0xc3, + 0xe5,0xfa,0x76,0xc6,0xd1,0xde,0x57,0xde,0x67,0xce,0x4e,0x0f,0x65,0xec,0x9f,0xcc, + 0x61,0xc5,0xd6,0x12,0xdb,0x19,0x81,0x37,0xb1,0x9f,0x2b,0xf6,0xaf,0x08,0xfd,0x9d, + 0x7e,0x5f,0x46,0xe0,0x76,0x36,0xf8,0x28,0x62,0xfc,0xc2,0x9d,0x03,0x3e,0x8e,0x90, + 0xfb,0xc8,0xc9,0x7d,0x42,0xb9,0xe0,0xbe,0x87,0xfe,0x27,0x42,0x56,0x79,0xe7,0xe6, + 0x11,0xf5,0x7c,0xf4,0x29,0xbf,0xa1,0x2b,0x2f,0xf1,0xbf,0x07,0xe1,0xdc,0x74,0xcd, + 0x3e,0xaf,0x3a,0xdf,0xee,0xca,0xd7,0xe7,0xac,0x2d,0xbb,0x5c,0xbd,0xd8,0xcd,0x7a, + 0x11,0x5c,0xbd,0x38,0x27,0x95,0xe3,0xb4,0xbb,0xaa,0x5e,0x9c,0xd7,0x09,0xcf,0xea, + 0xc5,0x91,0x09,0xba,0x90,0x89,0xc5,0xb1,0xa9,0xec,0x83,0xf2,0x7a,0xe6,0x4b,0x31, + 0xf5,0x41,0x9f,0xad,0x16,0x5c,0x44,0x1d,0xd5,0xb5,0x5a,0x70,0x71,0x02,0x6e,0x32, + 0x97,0x24,0x8c,0xe7,0x65,0x2e,0x4d,0xc0,0xad,0x5e,0x5c,0x9e,0x80,0xa9,0xae,0xd5, + 0x8b,0x51,0x09,0xb8,0xaf,0x17,0xa3,0x5d,0xbd,0x18,0xd5,0x49,0xbd,0x18,0xe3,0xea, + 0xc5,0x68,0x57,0x2f,0xc6,0x26,0xf0,0xac,0x5e,0xb4,0x24,0x60,0xbe,0x5e,0xb4,0xb2, + 0x5e,0xb4,0xb8,0x7a,0x61,0x73,0xd6,0xbb,0xe5,0xee,0x53,0xac,0x17,0xba,0x16,0xad, + 0x8c,0x4d,0xe9,0x3f,0x8a,0x54,0x59,0x1b,0x8e,0xcb,0x74,0x1f,0xea,0x1f,0x97,0xca, + 0xfb,0xea,0xf8,0xf4,0xfd,0xda,0x70,0x42,0xc2,0x7a,0x28,0xcf,0xf6,0x64,0xef,0x84, + 0xb1,0x94,0x57,0xfa,0xc6,0x4c,0x5b,0x7d,0xaa,0xe8,0xbe,0xce,0xb7,0xa7,0x13,0xf4, + 0x8e,0xa3,0x8f,0x7d,0xe8,0xdb,0xe0,0x54,0x59,0x07,0xfa,0x65,0x7a,0x10,0xf5,0xfb, + 0xb9,0x31,0xfb,0x73,0x4c,0x5f,0x07,0x06,0xa4,0xef,0xd7,0x81,0x81,0x09,0x75,0x40, + 0x79,0x56,0x07,0xea,0x13,0xf4,0x07,0xd2,0xbf,0xc1,0xb4,0x3f,0xa8,0x8a,0x1e,0xec, + 0xfc,0x5d,0x91,0xa0,0xd7,0x8f,0xfe,0xaa,0xac,0xed,0x9d,0x86,0x84,0xf9,0xac,0x70, + 0x75,0xe0,0x14,0x97,0xc3,0x0d,0xa9,0xb2,0x0e,0x9c,0xc6,0x5c,0xf4,0x75,0xa0,0x91, + 0xb9,0xe9,0xeb,0xc0,0xe9,0x09,0xb8,0xaf,0x03,0x67,0x24,0xe8,0x2b,0xcf,0xea,0xc0, + 0x99,0x09,0xf8,0x9e,0xff,0x6a,0x12,0xc6,0xf7,0x75,0xe0,0xec,0x04,0xb9,0x26,0x27, + 0xf7,0x53,0xca,0xf9,0x3a,0x30,0x2c,0x41,0x56,0x79,0x56,0x07,0xbe,0x09,0xa8,0x01, + 0xc3,0x52,0xf9,0xff,0x29,0xab,0x03,0x1a,0x2f,0xdb,0xf3,0x9f,0xf3,0x3c,0xa1,0x3a, + 0xeb,0x12,0xea,0x87,0xd6,0x52,0xd5,0xd7,0x58,0x3e,0xcc,0x3d,0xfc,0x1d,0xcf,0x13, + 0x76,0x7e,0x2b,0xdc,0x77,0x0e,0xe5,0x75,0x70,0x00,0xb5,0xd9,0xe1,0xfe,0x47,0x09, + 0xfc,0xc6,0x38,0xdf,0x9d,0xd3,0x45,0x80,0xcf,0xe6,0x9c,0xa2,0x00,0xdb,0xe1,0xce, + 0xb0,0x49,0x80,0x9b,0x9d,0x2e,0xb4,0x33,0xd5,0xd9,0xa9,0x11,0xe0,0x66,0xa7,0x56, + 0x80,0x79,0x3b,0x5d,0x05,0xb8,0xfd,0x47,0xd3,0x4d,0x60,0xbb,0x2b,0xbf,0x93,0x28, + 0xb6,0x97,0xe0,0xbf,0x83,0x6e,0x3c,0x7b,0xeb,0x7f,0xa5,0xfb,0xf0,0x7f,0xd2,0x2b, + 0x32,0xad,0xcf,0x2a,0xb3,0x8e,0xb9,0x66,0xf3,0x2c,0xa4,0xf2,0xff,0x19,0xbd,0x7f, + 0x9b,0x23,0x5d,0x9f,0xaf,0xff,0x03,0xa4,0xb0,0x5e,0xa3,0x0c,0x26,0x00,0x00 }; // Generated from: @@ -494,19 +486,15 @@ constexpr uint8_t kEtcToBc_comp_00000001[] = { // return uvec2(flip_endian(v . y), flip_endian(v . x)); // } // -// uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, int scale) +// uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, bool transparent) // { // vec3 dir = maxColor - minColor; // float distMin = dot(minColor, dir); // float distMax = dot(maxColor, dir); // float dist = dot(color, dir); -// uint ind = uint(clamp(int((dist - distMin)/(distMax - distMin)* scale + 0.5f), 0, scale)); +// int ind = int(round(clamp((dist - distMin)/(distMax - distMin), 0.0, 1.0)*(transparent ? 2.0 : 3.0))); // -// ind = - ind & 3; -// ind ^= uint(ind < 2); -// ind += scale; -// ind -= 3; -// return ind; +// return bitfieldExtract(transparent ? 0x18u : 0x2du, ind * 2, 2); // } // // void ComputeMaxMinColor(uvec3 rgbColor, inout uvec3 minColor, inout uvec3 maxColor){ @@ -517,30 +505,25 @@ constexpr uint8_t kEtcToBc_comp_00000001[] = { // dx = ivec3(rgbColor)- avg; // } // else { -// dx = ivec3(rgbColor)- ivec3((subgroupClusteredAdd(rgbColor, 16)+ 8)>> 4); +// dx = ivec3(rgbColor)- ivec3(subgroupClusteredAdd(rgbColor, 16)+ 8 >> 4); // } -// float cov0 = float(subgroupClusteredAdd(dx . r * dx . r, 16)); -// float cov1 = float(subgroupClusteredAdd(dx . r * dx . g, 16)); -// float cov2 = float(subgroupClusteredAdd(dx . r * dx . b, 16)); -// float cov3 = float(subgroupClusteredAdd(dx . g * dx . g, 16)); -// float cov4 = float(subgroupClusteredAdd(dx . g * dx . b, 16)); -// float cov5 = float(subgroupClusteredAdd(dx . b * dx . b, 16)); -// +// vec3 cov0 = vec3(subgroupClusteredAdd(dx . r * dx, 16)); +// vec3 cov1 = vec3(subgroupClusteredAdd(dx . ggb * dx . gbb, 16)); // vec3 vg = vec3(subgroupClusteredMax(rgbColor, 16)- subgroupClusteredMin(rgbColor, 16)); -// float eigenvalue = 0.0f; // +// mat3 covMat = mat3(cov0, +// vec3(cov0 . y, cov1 . xy), +// vec3(cov0 . z, cov1 . yz)); +// +// float eigenvalue = 0.0f; // for(int i = 0;i < 4;i ++){ -// float r = dot(vec3(cov0, cov1, cov2), vg); -// float g = dot(vec3(cov1, cov3, cov4), vg); -// float b = dot(vec3(cov2, cov4, cov5), vg); -// vg = vec3(r, g, b); +// vg = covMat * vg; // eigenvalue = sqrt(dot(vg, vg)); // if(eigenvalue > 0.0f){ // float invNorm = 1.0f / eigenvalue; // vg *= invNorm; // } // } -// // const float kDefaultLuminanceThreshold = 4.0f * 255; // const float kQuantizeRange = 0.512f; // @@ -554,20 +537,19 @@ constexpr uint8_t kEtcToBc_comp_00000001[] = { // float dist = dot(vec3(rgbColor), vg); // float min_dist = subgroupClusteredMin(dist, 16); // float max_dist = subgroupClusteredMax(dist, 16); -// uint min_index = subgroupClusteredMax(dist == min_dist ? gl_SubgroupInvocationID : 0, 16); -// uint max_index = subgroupClusteredMax(dist == max_dist ? gl_SubgroupInvocationID : 0, 16); -// minColor = subgroupShuffle(rgbColor, min_index); -// maxColor = subgroupShuffle(rgbColor, max_index); +// uvec2 indices = uvec2(dist == min_dist ? gl_SubgroupInvocationID : 0, +// dist == max_dist ? gl_SubgroupInvocationID : 0); +// uvec2 minMaxIndex = subgroupClusteredMax(indices, 16); +// minColor = subgroupShuffle(rgbColor, minMaxIndex . x); +// maxColor = subgroupShuffle(rgbColor, minMaxIndex . y); // } // // uint GetIndicesAlpha(int alpha, int minAlpha, int maxAlpha) // { // float dist = float(maxAlpha - minAlpha); -// uint ind = uint(float(alpha - minAlpha)/ dist * 7.0f + 0.5f); +// int ind = int(round(clamp((alpha - minAlpha)/ dist * 7.0f, 0.0, 7.0))); // -// ind = - ind & 7; -// ind ^= int(2 > ind); -// return ind; +// return bitfieldExtract(0x2345671u, ind * 4, 4); // } // // void ComputeMaxMin(int alpha, inout int minAlpha, inout int maxAlpha){ @@ -581,21 +563,45 @@ constexpr uint8_t kEtcToBc_comp_00000001[] = { // if(minValue != maxValue) // indices = GetIndicesAlpha(value, minValue, maxValue); // -// uint indices0 = pid < 5 ? indices <<(3 * pid + 16): 0x0; -// uint indices1 = pid > 5 ? indices <<(3 * pid - 16): 0x0; -// if(pid == 5){ -// indices0 |=(indices & 0x1)<< 31; -// indices1 |=(indices & 0x6)>> 1; -// } -// uint mask0 = subgroupClusteredOr(indices0, 16); -// uint mask1 = subgroupClusteredOr(indices1, 16); +// uvec2 mask = uvec2(pid <= 5 ? indices <<(16 + 3 * pid): 0x0, +// pid >= 5 ?(indices << 29)>>(45 - 3 * pid): 0x0); // -// return uvec2((maxValue & 0xff)|((minValue & 0xff)<< 8)| mask0, mask1); +// mask = subgroupClusteredOr(mask, 16); +// return uvec2((maxValue & 0xff)|((minValue & 0xff)<< 8)| mask . x, mask . y); // } // -// uint packColorToRGB565(uvec3 color){ -// uvec3 quant = uvec3(round(vec3(color)* vec3(31.0 / 255.0, 63.0 / 255.0, 31.0 / 255.0))); -// return(quant . r << 11)|(quant . g << 5)| quant . b; +// uvec3 scaleColorToRGB565(uvec3 color){ +// return uvec3(round(vec3(color)* vec3(31.0 / 255.0, 63.0 / 255.0, 31.0 / 255.0))); +// } +// +// uvec3 convertRGB565ToRGB888(uvec3 color){ +// return uvec3(color . x << 3 |(color . x >> 2), +// color . y << 2 |(color . y >> 4), +// color . z << 3 |(color . z >> 2)); +// } +// +// uint packRGB565(uvec3 color565){ +// return color565 . r << 11 |(color565 . g << 5)| color565 . b; +// } +// +// void modifyMinMax(inout uvec3 minColor, inout uvec3 maxColor){ +// uvec3 minColor565 = scaleColorToRGB565(minColor); +// uvec3 maxColor565 = scaleColorToRGB565(maxColor); +// if(all(equal(minColor565, maxColor565))){ +// uvec3 simulatedColor = convertRGB565ToRGB888(minColor565); +// ivec3 signMax = sign(ivec3(maxColor)- ivec3(simulatedColor)); +// ivec3 signMin = sign(ivec3(minColor)- ivec3(simulatedColor)); +// bvec3 needCorrect = greaterThan(signMax * signMin, ivec3(0, 0, 0)); +// bvec3 positive = greaterThan(signMin, ivec3(0, 0, 0)); +// maxColor565 . r += needCorrect . r && positive . r ? 1 : 0; +// maxColor565 . g += needCorrect . g && positive . g ? 1 : 0; +// maxColor565 . b += needCorrect . b && positive . b ? 1 : 0; +// minColor565 . r -= needCorrect . r && ! positive . r ? 1 : 0; +// minColor565 . g -= needCorrect . g && ! positive . g ? 1 : 0; +// minColor565 . b -= needCorrect . b && ! positive . b ? 1 : 0; +// } +// minColor = minColor565; +// maxColor = maxColor565; // } // // void swap(inout uint a, inout uint b){ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/src/EtcToBc.comp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/src/EtcToBc.comp index f291481a4b75..75d7f07b4bed 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/src/EtcToBc.comp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/shaders/src/EtcToBc.comp @@ -99,13 +99,13 @@ uvec2 flip_endian(uvec2 v) } #if SUBGROUP_OP -uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, int scale) +uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, bool transparent) { vec3 dir = maxColor - minColor; float distMin = dot(minColor, dir); float distMax = dot(maxColor, dir); float dist = dot(color, dir); - uint ind = uint(clamp(int( (dist - distMin) / (distMax - distMin) * scale + 0.5f), 0, scale)); + int ind = int(round( clamp((dist - distMin) / (distMax - distMin), 0.0, 1.0) * (transparent ? 2.0 : 3.0))); // BC1 index mapping // color0: maxColor @@ -126,11 +126,7 @@ uint GetIndicesRGB(vec3 color, vec3 minColor, vec3 maxColor, int scale) // 0 -> 0 // 1 -> 2 // 2 -> 1 - ind = -ind & 3; - ind ^= uint( ind < 2 ); - ind += scale; - ind -= 3; - return ind; + return bitfieldExtract( transparent ? 0x18u : 0x2du, ind * 2, 2); } // Select end point using PCA @@ -142,31 +138,27 @@ void ComputeMaxMinColor(uvec3 rgbColor, inout uvec3 minColor, inout uvec3 maxCol dx = ivec3(rgbColor) - avg; } else { - dx = ivec3(rgbColor) - ivec3((subgroupClusteredAdd(rgbColor, 16)+8)>>4); + dx = ivec3(rgbColor) - ivec3(subgroupClusteredAdd(rgbColor, 16) + 8 >> 4); } - float cov0 = float(subgroupClusteredAdd(dx.r*dx.r, 16)); - float cov1 = float(subgroupClusteredAdd(dx.r*dx.g, 16)); - float cov2 = float(subgroupClusteredAdd(dx.r*dx.b, 16)); - float cov3 = float(subgroupClusteredAdd(dx.g*dx.g, 16)); - float cov4 = float(subgroupClusteredAdd(dx.g*dx.b, 16)); - float cov5 = float(subgroupClusteredAdd(dx.b*dx.b, 16)); - - vec3 vg = vec3(subgroupClusteredMax(rgbColor, 16) - subgroupClusteredMin(rgbColor, 16)); + vec3 cov0 = vec3(subgroupClusteredAdd(dx.r * dx, 16)); + vec3 cov1 = vec3(subgroupClusteredAdd(dx.ggb * dx.gbb, 16)); + vec3 vg = vec3(subgroupClusteredMax(rgbColor, 16) - subgroupClusteredMin(rgbColor, 16)); + + // Then build the matrix. + mat3 covMat = mat3(cov0, // rr, rg, rb + vec3(cov0.y, cov1.xy), // rg, gg, gb + vec3(cov0.z, cov1.yz)); // rb, gb, bb + // normalized power iteration. + // power iteration at some special case maybe wrong. float eigenvalue = 0.0f; - - // unroll ? compiler should do for( int i = 0; i<4; i++ ) { - float r = dot(vec3(cov0, cov1, cov2), vg); - float g = dot(vec3(cov1, cov3, cov4), vg); - float b = dot(vec3(cov2, cov4, cov5), vg); - vg = vec3(r, g, b); + vg = covMat * vg; eigenvalue = sqrt(dot(vg, vg)); if( eigenvalue > 0.0f ) { float invNorm = 1.0f/eigenvalue; vg *= invNorm; } } - const float kDefaultLuminanceThreshold = 4.0f * 255; const float kQuantizeRange = 0.512f; @@ -180,16 +172,17 @@ void ComputeMaxMinColor(uvec3 rgbColor, inout uvec3 minColor, inout uvec3 maxCol float dist = dot(vec3(rgbColor), vg); float min_dist = subgroupClusteredMin(dist, 16); float max_dist = subgroupClusteredMax(dist, 16); - uint min_index = subgroupClusteredMax(dist == min_dist? gl_SubgroupInvocationID : 0, 16); - uint max_index = subgroupClusteredMax(dist == max_dist? gl_SubgroupInvocationID : 0, 16); - minColor = subgroupShuffle(rgbColor, min_index); - maxColor = subgroupShuffle(rgbColor, max_index); + uvec2 indices = uvec2(dist == min_dist? gl_SubgroupInvocationID : 0, + dist == max_dist? gl_SubgroupInvocationID : 0); + uvec2 minMaxIndex = subgroupClusteredMax(indices, 16); + minColor = subgroupShuffle(rgbColor, minMaxIndex.x); + maxColor = subgroupShuffle(rgbColor, minMaxIndex.y); } uint GetIndicesAlpha(int alpha, int minAlpha, int maxAlpha) { float dist = float(maxAlpha-minAlpha); - uint ind = uint(float(alpha - minAlpha)/dist*7.0f + 0.5f); + int ind = int(round(clamp((alpha - minAlpha)/dist*7.0f, 0.0, 7.0))); // 0 : maxAlpha // 1 : minAlpha // 2 : 6/7*maxAlpha + 1/7*minAlpha; @@ -200,17 +193,14 @@ uint GetIndicesAlpha(int alpha, int minAlpha, int maxAlpha) // 7 : 1/7*maxAlpha + 6/7*minAlpha; // so the mapping is // 0 -> 1 - // 7 -> 0 // 1 -> 7 // 2 -> 6 // 3 -> 5 // 4 -> 4 // 5 -> 3 // 6 -> 2 - - ind = -ind & 7; - ind ^= int(2 > ind); - return ind; + // 7 -> 0 + return bitfieldExtract(0x2345671u, ind * 4, 4); } void ComputeMaxMin(int alpha, inout int minAlpha, inout int maxAlpha) { @@ -224,25 +214,52 @@ uvec2 EncodeBC4(int value, uint pid) { if( minValue != maxValue ) indices = GetIndicesAlpha(value, minValue, maxValue); - uint indices0 = pid<5 ? indices<<(3*pid+16) : 0x0; - uint indices1 = pid>5 ? indices<<(3*pid-16) : 0x0; - if( pid == 5 ) { - indices0 |= (indices&0x1)<<31; - indices1 |= (indices&0x6)>>1; - } - uint mask0 = subgroupClusteredOr( indices0, 16); - uint mask1 = subgroupClusteredOr( indices1, 16); + uvec2 mask = uvec2( pid <= 5 ? indices << ( 16 + 3 * pid ) : 0x0, + pid >= 5 ? ( indices << 29 ) >> ( 45 - 3 * pid ) : 0x0 ); - return uvec2((maxValue & 0xff) | ((minValue & 0xff) << 8) | mask0, mask1); + mask = subgroupClusteredOr( mask, 16); + return uvec2((maxValue & 0xff) | ((minValue & 0xff) << 8) | mask.x, mask.y); } #endif -uint packColorToRGB565(uvec3 color) { - uvec3 quant = uvec3(round(vec3(color) * vec3(31.0/255.0, 63.0/255.0, 31.0/255.0))); - return (quant.r << 11) | (quant.g << 5) | quant.b; +uvec3 scaleColorToRGB565(uvec3 color) { + return uvec3(round(vec3(color) * vec3(31.0/255.0, 63.0/255.0, 31.0/255.0))); +} + +// This function simulate hardware behavior. +// only a few number not equal to golden reference. +uvec3 convertRGB565ToRGB888(uvec3 color) { + return uvec3(color.x << 3 | (color.x >> 2), + color.y << 2 | (color.y >> 4), + color.z << 3 | (color.z >> 2)); } +uint packRGB565(uvec3 color565) { + return color565.r << 11 | ( color565.g << 5 ) | color565.b; +} + +//This change tries to change one endpoint to an adjacent one (not optimal) in RGB565, +//so that all the colors are interpolated from these two endpoints. +void modifyMinMax(inout uvec3 minColor, inout uvec3 maxColor) { + uvec3 minColor565 = scaleColorToRGB565(minColor); + uvec3 maxColor565 = scaleColorToRGB565(maxColor); + if( all(equal(minColor565, maxColor565)) ) { + uvec3 simulatedColor = convertRGB565ToRGB888(minColor565); + ivec3 signMax = sign(ivec3(maxColor) - ivec3(simulatedColor)); + ivec3 signMin = sign(ivec3(minColor) - ivec3(simulatedColor)); + bvec3 needCorrect = greaterThan(signMax * signMin, ivec3(0, 0, 0)); + bvec3 positive = greaterThan(signMin, ivec3(0, 0, 0)); + maxColor565.r += needCorrect.r && positive.r ? 1 : 0; + maxColor565.g += needCorrect.g && positive.g ? 1 : 0; + maxColor565.b += needCorrect.b && positive.b ? 1 : 0; + minColor565.r -= needCorrect.r && !positive.r ? 1 : 0; + minColor565.g -= needCorrect.g && !positive.g ? 1 : 0; + minColor565.b -= needCorrect.b && !positive.b ? 1 : 0; + } + minColor = minColor565; + maxColor = maxColor565; +} void swap( inout uint a, inout uint b) { uint t = a; @@ -250,7 +267,6 @@ void swap( inout uint a, inout uint b) { b = t; } - void main() { ivec2 coord = build_coord(); @@ -293,12 +309,15 @@ void main() if( controlFlag ) { ComputeMaxMinColor(uvec3(result.r, result.g, result.b), minColor, maxColor); - - uint minColor565 = packColorToRGB565(minColor); - uint maxColor565 = packColorToRGB565(maxColor); + modifyMinMax(minColor, maxColor); + uint minColor565 = packRGB565(minColor); + uint maxColor565 = packRGB565(maxColor); if( minColor565 != maxColor565 ) { - indices = GetIndicesRGB(vec3(result.r, result.g, result.b), vec3(minColor), vec3(maxColor), nonOpaque ? 2: 3); + indices = GetIndicesRGB(vec3(result.r, result.g, result.b), + vec3(convertRGB565ToRGB888(minColor)), + vec3(convertRGB565ToRGB888(maxColor)), + nonOpaque); } bool flip = maxColor565 < minColor565; if( flip ) { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/spv_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/spv_utils.cpp index 497a6def2421..97f09d3753e3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/spv_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/spv_utils.cpp @@ -1532,7 +1532,7 @@ TransformationState SpirvPerVertexTrimmer::transformTypeStruct(const SpirvIDDisc // Change the definition of the gl_PerVertex struct by stripping unused fields at the end. const uint32_t memberCount = maxMembers + 1; - memberList->resize(memberCount); + memberList->resize_down(memberCount); spirv::WriteTypeStruct(blobOut, id, *memberList); @@ -1647,7 +1647,7 @@ void SpirvInactiveVaryingRemover::modifyEntryPointInterfaceList( } // Update the number of interface variables. - interfaceList->resize(writeIndex); + interfaceList->resize_down(writeIndex); } TransformationState SpirvInactiveVaryingRemover::transformTypePointer( @@ -2215,7 +2215,8 @@ void SpirvTransformFeedbackCodeGenerator::writeIntConstant(const SpirvIDDiscover if (mIntNIds.size() <= value) { - mIntNIds.resize(value + 1); + // This member never resized down, so new elements can't have previous values. + mIntNIds.resize_maybe_value_reuse(value + 1); } else if (mIntNIds[value].valid()) { @@ -2275,7 +2276,10 @@ void SpirvTransformFeedbackCodeGenerator::writePendingDeclarations( ids.ivec4Id()); } - mIntNIds.resize(4); + ASSERT(mIntNIds.empty()); + // All new elements initialized later after the resize. Additionally mIntNIds was always empty + // before this resize, so previous value reuse is not possible. + mIntNIds.resize_maybe_value_reuse(4); mIntNIds[0] = ids.int0Id(); for (int n = 1; n < 4; ++n) { @@ -4519,7 +4523,7 @@ TransformationState SpirvVertexAttributeAliasingTransformer::transformEntryPoint } // Update the number of interface variables. - interfaceList.resize(writeIndex); + interfaceList.resize_down(writeIndex); // Write the entry point with the aliasing attributes removed. spirv::WriteEntryPoint(mSpirvBlobOut, executionModel, mEntryPointId, name, interfaceList); @@ -4763,7 +4767,7 @@ void SpirvVertexAttributeAliasingTransformer::transformLoadHelper(spirv::IdRef p { spirv::LiteralIntegerList swizzle = {spirv::LiteralInteger(0), spirv::LiteralInteger(1), spirv::LiteralInteger(2), spirv::LiteralInteger(3)}; - swizzle.resize(aliasingInfo->attributeComponentCount); + swizzle.resize_down(aliasingInfo->attributeComponentCount); spirv::WriteVectorShuffle(mSpirvBlobOut, typeId, resultId, loadResultId, loadResultId, swizzle); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp index 3b24caeff582..9d3aa8830bd4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp @@ -3356,7 +3356,10 @@ void GraphicsPipelineDesc::initializePipelineVertexInputState( } if (context->getFeatures().supportsExtendedDynamicState2.enabled) { - dynamicStateListOut->push_back(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE); + if (!context->getFeatures().forceStaticPrimitiveRestartState.enabled) + { + dynamicStateListOut->push_back(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE); + } } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp index 22c337f609a6..e2aa2f8bbd68 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp @@ -337,6 +337,7 @@ void RendererVk::ensureCapsInitialized() const mNativeExtensions.textureStorageEXT = true; mNativeExtensions.drawBuffersEXT = true; mNativeExtensions.fragDepthEXT = true; + mNativeExtensions.conservativeDepthEXT = true; mNativeExtensions.framebufferBlitANGLE = true; mNativeExtensions.framebufferBlitNV = true; mNativeExtensions.framebufferMultisampleANGLE = true; @@ -899,6 +900,9 @@ void RendererVk::ensureCapsInitialized() const // // Note that this exception for gl_Position does not apply to MAX_VERTEX_OUTPUT_COMPONENTS and // similar limits. + // + // Note also that the reserved components are for transform feedback capture only, so they don't + // apply to the _input_ component limit. const GLint reservedVaryingVectorCount = reservedVaryingComponentCount / 4 + 1; const GLint maxVaryingCount = @@ -907,8 +911,7 @@ void RendererVk::ensureCapsInitialized() const LimitToInt((maxVaryingCount / kComponentsPerVector) - reservedVaryingVectorCount); mNativeCaps.maxVertexOutputComponents = LimitToInt(limitsVk.maxVertexOutputComponents) - reservedVaryingComponentCount; - mNativeCaps.maxFragmentInputComponents = - LimitToInt(limitsVk.maxFragmentInputComponents) - reservedVaryingComponentCount; + mNativeCaps.maxFragmentInputComponents = LimitToInt(limitsVk.maxFragmentInputComponents); mNativeCaps.maxTransformFeedbackInterleavedComponents = gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; @@ -994,43 +997,6 @@ void RendererVk::ensureCapsInitialized() const // expect r32ui instead. mNativeExtensions.shaderImageAtomicOES = true; - // Geometry shaders are required for ES 3.2. - if (mPhysicalDeviceFeatures.geometryShader) - { - bool geometryShaderEnabled = mFeatures.supportsTransformFeedbackExtension.enabled && - (mFeatures.supportsPrimitivesGeneratedQuery.enabled || - mFeatures.exposeNonConformantExtensionsAndVersions.enabled); - mNativeExtensions.geometryShaderEXT = geometryShaderEnabled; - mNativeExtensions.geometryShaderOES = geometryShaderEnabled; - mNativeCaps.maxFramebufferLayers = LimitToInt(limitsVk.maxFramebufferLayers); - - // Use "undefined" which means APP would have to set gl_Layer identically. - mNativeCaps.layerProvokingVertex = GL_UNDEFINED_VERTEX_EXT; - - mNativeCaps.maxGeometryInputComponents = - LimitToInt(limitsVk.maxGeometryInputComponents) - reservedVaryingComponentCount; - mNativeCaps.maxGeometryOutputComponents = - LimitToInt(limitsVk.maxGeometryOutputComponents) - reservedVaryingComponentCount; - mNativeCaps.maxGeometryOutputVertices = LimitToInt(limitsVk.maxGeometryOutputVertices); - mNativeCaps.maxGeometryTotalOutputComponents = - LimitToInt(limitsVk.maxGeometryTotalOutputComponents); - if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics) - { - mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Geometry] = - mNativeCaps.maxCombinedShaderOutputResources; - mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] = - maxCombinedAtomicCounterBuffers; - } - mNativeCaps.maxGeometryShaderInvocations = - LimitToInt(limitsVk.maxGeometryShaderInvocations); - - // Reserve a uniform buffer binding for the geometry stage - if (geometryShaderEnabled) - { - maxCombinedUniformBuffers -= kReservedPerStageDefaultUniformBindingCount; - } - } - // Tessellation shaders are required for ES 3.2. if (mPhysicalDeviceFeatures.tessellationShader) { @@ -1055,7 +1021,8 @@ void RendererVk::ensureCapsInitialized() const mNativeCaps.maxTessEvaluationInputComponents = LimitToInt(limitsVk.maxTessellationEvaluationInputComponents); mNativeCaps.maxTessEvaluationOutputComponents = - LimitToInt(limitsVk.maxTessellationEvaluationOutputComponents); + LimitToInt(limitsVk.maxTessellationEvaluationOutputComponents) - + reservedVaryingComponentCount; // There is 1 default uniform binding used per tessellation stages. mNativeCaps.maxCombinedUniformBlocks = LimitToInt( @@ -1083,6 +1050,50 @@ void RendererVk::ensureCapsInitialized() const } } + // Geometry shaders are required for ES 3.2. + if (mPhysicalDeviceFeatures.geometryShader) + { + bool geometryShaderEnabled = mFeatures.supportsTransformFeedbackExtension.enabled && + (mFeatures.supportsPrimitivesGeneratedQuery.enabled || + mFeatures.exposeNonConformantExtensionsAndVersions.enabled); + mNativeExtensions.geometryShaderEXT = geometryShaderEnabled; + mNativeExtensions.geometryShaderOES = geometryShaderEnabled; + mNativeCaps.maxFramebufferLayers = LimitToInt(limitsVk.maxFramebufferLayers); + + // Use "undefined" which means APP would have to set gl_Layer identically. + mNativeCaps.layerProvokingVertex = GL_UNDEFINED_VERTEX_EXT; + + mNativeCaps.maxGeometryInputComponents = LimitToInt(limitsVk.maxGeometryInputComponents); + mNativeCaps.maxGeometryOutputComponents = + LimitToInt(limitsVk.maxGeometryOutputComponents) - reservedVaryingComponentCount; + mNativeCaps.maxGeometryOutputVertices = LimitToInt(limitsVk.maxGeometryOutputVertices); + mNativeCaps.maxGeometryTotalOutputComponents = + LimitToInt(limitsVk.maxGeometryTotalOutputComponents); + if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics) + { + mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Geometry] = + mNativeCaps.maxCombinedShaderOutputResources; + mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] = + maxCombinedAtomicCounterBuffers; + } + mNativeCaps.maxGeometryShaderInvocations = + LimitToInt(limitsVk.maxGeometryShaderInvocations); + + // Cap maxGeometryInputComponents by maxVertexOutputComponents and + // maxTessellationEvaluationOutputComponents; there can't be more inputs than there are + // outputs in the previous stage. + mNativeCaps.maxGeometryInputComponents = + std::min(mNativeCaps.maxGeometryInputComponents, + std::min(mNativeCaps.maxVertexOutputComponents, + mNativeCaps.maxTessEvaluationOutputComponents)); + + // Reserve a uniform buffer binding for the geometry stage + if (geometryShaderEnabled) + { + maxCombinedUniformBuffers -= kReservedPerStageDefaultUniformBindingCount; + } + } + mNativeCaps.maxCombinedUniformBlocks = maxCombinedUniformBuffers; mNativeCaps.maxUniformBufferBindings = maxCombinedUniformBuffers; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.cpp index 9789bce50465..aefce16e526a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.cpp @@ -925,42 +925,6 @@ char GetStoreOpShorthand(RenderPassStoreOp storeOp) } } -template -void RecycleCommandBufferHelper(VkDevice device, - std::vector *freeList, - CommandBufferHelperT **commandBufferHelper, - priv::SecondaryCommandBuffer *commandBuffer) -{ - freeList->push_back(*commandBufferHelper); -} - -template -void RecycleCommandBufferHelper(VkDevice device, - std::vector *freeList, - CommandBufferHelperT **commandBufferHelper, - VulkanSecondaryCommandBuffer *commandBuffer) -{ - CommandPool *pool = (*commandBufferHelper)->getCommandPool(); - - pool->freeCommandBuffers(device, 1, commandBuffer->ptr()); - commandBuffer->releaseHandle(); - SafeDelete(*commandBufferHelper); -} - -[[maybe_unused]] void ResetSecondaryCommandBuffer( - std::vector *resetList, - priv::SecondaryCommandBuffer &&commandBuffer) -{ - commandBuffer.reset(); -} - -[[maybe_unused]] void ResetSecondaryCommandBuffer( - std::vector *resetList, - VulkanSecondaryCommandBuffer &&commandBuffer) -{ - resetList->push_back(std::move(commandBuffer)); -} - bool IsClear(UpdateSource updateSource) { return updateSource == UpdateSource::Clear || @@ -1439,10 +1403,9 @@ CommandBufferHelperCommon::CommandBufferHelperCommon() CommandBufferHelperCommon::~CommandBufferHelperCommon() {} -void CommandBufferHelperCommon::initializeImpl(CommandPool *commandPool) +void CommandBufferHelperCommon::initializeImpl() { mCommandAllocator.init(); - mCommandPool = commandPool; } void CommandBufferHelperCommon::resetImpl() @@ -1450,6 +1413,103 @@ void CommandBufferHelperCommon::resetImpl() mCommandAllocator.resetAllocator(); } +template +angle::Result CommandBufferHelperCommon::attachCommandPoolImpl(Context *context, + SecondaryCommandPool *commandPool) +{ + if constexpr (!DerivedT::ExecutesInline()) + { + DerivedT *derived = static_cast(this); + ASSERT(commandPool != nullptr); + ASSERT(mCommandPool == nullptr); + ASSERT(!derived->getCommandBuffer().valid()); + + mCommandPool = commandPool; + + ANGLE_TRY(derived->initializeCommandBuffer(context)); + } + return angle::Result::Continue; +} + +template +angle::Result CommandBufferHelperCommon::detachCommandPoolImpl( + Context *context, + SecondaryCommandPool **commandPoolOut) +{ + if constexpr (!DerivedT::ExecutesInline()) + { + DerivedT *derived = static_cast(this); + ASSERT(mCommandPool != nullptr); + ASSERT(derived->getCommandBuffer().valid()); + + if constexpr (!kIsRenderPassBuffer) + { + ASSERT(!derived->getCommandBuffer().empty()); + ANGLE_TRY(derived->endCommandBuffer(context)); + } + + *commandPoolOut = mCommandPool; + mCommandPool = nullptr; + } + ASSERT(mCommandPool == nullptr); + return angle::Result::Continue; +} + +template +void CommandBufferHelperCommon::releaseCommandPoolImpl() +{ + if constexpr (!DerivedT::ExecutesInline()) + { + DerivedT *derived = static_cast(this); + ASSERT(mCommandPool != nullptr); + + if (derived->getCommandBuffer().valid()) + { + ASSERT(derived->getCommandBuffer().empty()); + mCommandPool->collect(&derived->getCommandBuffer()); + } + + mCommandPool = nullptr; + } + ASSERT(mCommandPool == nullptr); +} + +template +void CommandBufferHelperCommon::attachAllocatorImpl(SecondaryCommandMemoryAllocator *allocator) +{ + if constexpr (DerivedT::ExecutesInline()) + { + auto &commandBuffer = static_cast(this)->getCommandBuffer(); + mCommandAllocator.attachAllocator(allocator); + commandBuffer.attachAllocator(mCommandAllocator.getAllocator()); + } +} + +template +SecondaryCommandMemoryAllocator *CommandBufferHelperCommon::detachAllocatorImpl() +{ + SecondaryCommandMemoryAllocator *result = nullptr; + if constexpr (DerivedT::ExecutesInline()) + { + auto &commandBuffer = static_cast(this)->getCommandBuffer(); + commandBuffer.detachAllocator(mCommandAllocator.getAllocator()); + result = mCommandAllocator.detachAllocator(commandBuffer.empty()); + } + return result; +} + +template +void CommandBufferHelperCommon::assertCanBeRecycledImpl() +{ + DerivedT *derived = static_cast(this); + ASSERT(mCommandPool == nullptr); + ASSERT(!mCommandAllocator.hasAllocatorLinks()); + // Vulkan secondary command buffers must be invalid (collected). + ASSERT(DerivedT::ExecutesInline() || !derived->getCommandBuffer().valid()); + // ANGLEs Custom secondary command buffers must be empty (reset). + ASSERT(!DerivedT::ExecutesInline() || derived->getCommandBuffer().empty()); +} + void CommandBufferHelperCommon::bufferWrite(ContextVk *contextVk, VkAccessFlags writeAccessType, PipelineStage writeStage, @@ -1559,24 +1619,31 @@ OutsideRenderPassCommandBufferHelper::OutsideRenderPassCommandBufferHelper() {} OutsideRenderPassCommandBufferHelper::~OutsideRenderPassCommandBufferHelper() {} -angle::Result OutsideRenderPassCommandBufferHelper::initialize(Context *context, - CommandPool *commandPool) +angle::Result OutsideRenderPassCommandBufferHelper::initialize(Context *context) { - initializeImpl(commandPool); + initializeImpl(); return initializeCommandBuffer(context); } angle::Result OutsideRenderPassCommandBufferHelper::initializeCommandBuffer(Context *context) { + // Skip initialization in the Pool-detached state. + if (!ExecutesInline() && mCommandPool == nullptr) + { + return angle::Result::Continue; + } return mCommandBuffer.initialize(context, mCommandPool, false, mCommandAllocator.getAllocator()); } -angle::Result OutsideRenderPassCommandBufferHelper::reset(Context *context) +angle::Result OutsideRenderPassCommandBufferHelper::reset( + Context *context, + SecondaryCommandBufferCollector *commandBufferCollector) { resetImpl(); - // Reset and re-initialize the command buffer - context->getRenderer()->resetOutsideRenderPassCommandBuffer(std::move(mCommandBuffer)); + // Collect/Reset the command buffer + commandBufferCollector->collectCommandBuffer(std::move(mCommandBuffer)); + mIsCommandBufferEnded = false; // Invalidate the queue serial here. We will get a new queue serial after commands flush. mQueueSerial = QueueSerial(); @@ -1640,33 +1707,81 @@ void OutsideRenderPassCommandBufferHelper::imageWrite(ContextVk *contextVk, image->setQueueSerial(mQueueSerial); } -angle::Result OutsideRenderPassCommandBufferHelper::flushToPrimary(Context *context, - PrimaryCommandBuffer *primary) +angle::Result OutsideRenderPassCommandBufferHelper::flushToPrimary( + Context *context, + PrimaryCommandBuffer *primary, + SecondaryCommandBufferCollector *commandBufferCollector) { ANGLE_TRACE_EVENT0("gpu.angle", "OutsideRenderPassCommandBufferHelper::flushToPrimary"); ASSERT(!empty()); + RendererVk *renderer = context->getRenderer(); + // Commands that are added to primary before beginRenderPass command - executeBarriers(context->getRenderer()->getFeatures(), primary); + executeBarriers(renderer->getFeatures(), primary); - ANGLE_TRY(mCommandBuffer.end(context)); + // When using Vulkan secondary command buffers and "asyncCommandQueue" is enabled, command + // buffer MUST be already ended in the detachCommandPool() (called in the CommandProcessor). + // After the detach, nothing is written to the buffer (the barriers above are written directly + // to the primary buffer). + // Note: RenderPass Command Buffers are explicitly ended in the endRenderPass(). + if (ExecutesInline() || !renderer->isAsyncCommandQueueEnabled()) + { + ANGLE_TRY(endCommandBuffer(context)); + } + ASSERT(mIsCommandBufferEnded); mCommandBuffer.executeCommands(primary); // Restart the command buffer. - return reset(context); + return reset(context, commandBufferCollector); +} + +angle::Result OutsideRenderPassCommandBufferHelper::endCommandBuffer(Context *context) +{ + ASSERT(ExecutesInline() || mCommandPool != nullptr); + ASSERT(mCommandBuffer.valid()); + ASSERT(!mIsCommandBufferEnded); + + ANGLE_TRY(mCommandBuffer.end(context)); + mIsCommandBufferEnded = true; + + return angle::Result::Continue; +} + +angle::Result OutsideRenderPassCommandBufferHelper::attachCommandPool( + Context *context, + SecondaryCommandPool *commandPool) +{ + return attachCommandPoolImpl(context, commandPool); +} + +angle::Result OutsideRenderPassCommandBufferHelper::detachCommandPool( + Context *context, + SecondaryCommandPool **commandPoolOut) +{ + return detachCommandPoolImpl(context, + commandPoolOut); +} + +void OutsideRenderPassCommandBufferHelper::releaseCommandPool() +{ + releaseCommandPoolImpl(); } void OutsideRenderPassCommandBufferHelper::attachAllocator( SecondaryCommandMemoryAllocator *allocator) { - mCommandAllocator.attachAllocator(allocator); - getCommandBuffer().attachAllocator(mCommandAllocator.getAllocator()); + attachAllocatorImpl(allocator); } SecondaryCommandMemoryAllocator *OutsideRenderPassCommandBufferHelper::detachAllocator() { - getCommandBuffer().detachAllocator(mCommandAllocator.getAllocator()); - return mCommandAllocator.detachAllocator(getCommandBuffer().empty()); + return detachAllocatorImpl(); +} + +void OutsideRenderPassCommandBufferHelper::assertCanBeRecycled() +{ + assertCanBeRecycledImpl(); } void OutsideRenderPassCommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk) @@ -1700,18 +1815,25 @@ RenderPassCommandBufferHelper::~RenderPassCommandBufferHelper() mFramebuffer.setHandle(VK_NULL_HANDLE); } -angle::Result RenderPassCommandBufferHelper::initialize(Context *context, CommandPool *commandPool) +angle::Result RenderPassCommandBufferHelper::initialize(Context *context) { - initializeImpl(commandPool); + initializeImpl(); return initializeCommandBuffer(context); } angle::Result RenderPassCommandBufferHelper::initializeCommandBuffer(Context *context) { + // Skip initialization in the Pool-detached state. + if (!ExecutesInline() && mCommandPool == nullptr) + { + return angle::Result::Continue; + } return getCommandBuffer().initialize(context, mCommandPool, true, mCommandAllocator.getAllocator()); } -angle::Result RenderPassCommandBufferHelper::reset(Context *context) +angle::Result RenderPassCommandBufferHelper::reset( + Context *context, + SecondaryCommandBufferCollector *commandBufferCollector) { resetImpl(); @@ -1739,10 +1861,10 @@ angle::Result RenderPassCommandBufferHelper::reset(Context *context) ASSERT(CheckSubpassCommandBufferCount(getSubpassCommandBufferCount())); - // Reset and re-initialize the command buffers + // Collect/Reset the command buffers for (uint32_t subpass = 0; subpass < getSubpassCommandBufferCount(); ++subpass) { - context->getRenderer()->resetRenderPassCommandBuffer(std::move(mCommandBuffers[subpass])); + commandBufferCollector->collectCommandBuffer(std::move(mCommandBuffers[subpass])); } mCurrentSubpassCommandBufferIndex = 0; @@ -2320,7 +2442,7 @@ angle::Result RenderPassCommandBufferHelper::endRenderPassCommandBuffer(ContextV angle::Result RenderPassCommandBufferHelper::nextSubpass(ContextVk *contextVk, RenderPassCommandBuffer **commandBufferOut) { - if (RenderPassCommandBuffer::ExecutesInline()) + if (ExecutesInline()) { // When using ANGLE secondary command buffers, the commands are inline and are executed on // the primary command buffer. This means that vkCmdNextSubpass can be intermixed with the @@ -2415,9 +2537,11 @@ void RenderPassCommandBufferHelper::invalidateRenderPassStencilAttachment( getRenderPassWriteCommandCount()); } -angle::Result RenderPassCommandBufferHelper::flushToPrimary(Context *context, - PrimaryCommandBuffer *primary, - const RenderPass *renderPass) +angle::Result RenderPassCommandBufferHelper::flushToPrimary( + Context *context, + PrimaryCommandBuffer *primary, + const RenderPass *renderPass, + SecondaryCommandBufferCollector *commandBufferCollector) { ANGLE_TRACE_EVENT0("gpu.angle", "RenderPassCommandBufferHelper::flushToPrimary"); ASSERT(mRenderPassStarted); @@ -2451,8 +2575,8 @@ angle::Result RenderPassCommandBufferHelper::flushToPrimary(Context *context, // Run commands inside the RenderPass. constexpr VkSubpassContents kSubpassContents = - RenderPassCommandBuffer::ExecutesInline() ? VK_SUBPASS_CONTENTS_INLINE - : VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; + ExecutesInline() ? VK_SUBPASS_CONTENTS_INLINE + : VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; primary->beginRenderPass(beginInfo, kSubpassContents); for (uint32_t subpass = 0; subpass < getSubpassCommandBufferCount(); ++subpass) @@ -2466,7 +2590,7 @@ angle::Result RenderPassCommandBufferHelper::flushToPrimary(Context *context, primary->endRenderPass(); // Restart the command buffer. - return reset(context); + return reset(context, commandBufferCollector); } void RenderPassCommandBufferHelper::updateRenderPassForResolve( @@ -2544,18 +2668,46 @@ void RenderPassCommandBufferHelper::growRenderArea(ContextVk *contextVk, mStencilAttachment.onRenderAreaGrowth(contextVk, mRenderArea); } +angle::Result RenderPassCommandBufferHelper::attachCommandPool(Context *context, + SecondaryCommandPool *commandPool) +{ + ASSERT(!mRenderPassStarted); + ASSERT(getSubpassCommandBufferCount() == 1); + return attachCommandPoolImpl(context, commandPool); +} + +void RenderPassCommandBufferHelper::detachCommandPool(SecondaryCommandPool **commandPoolOut) +{ + ASSERT(mRenderPassStarted); + angle::Result result = + detachCommandPoolImpl(nullptr, commandPoolOut); + ASSERT(result == angle::Result::Continue); +} + +void RenderPassCommandBufferHelper::releaseCommandPool() +{ + ASSERT(!mRenderPassStarted); + ASSERT(getSubpassCommandBufferCount() == 1); + releaseCommandPoolImpl(); +} + void RenderPassCommandBufferHelper::attachAllocator(SecondaryCommandMemoryAllocator *allocator) { ASSERT(CheckSubpassCommandBufferCount(getSubpassCommandBufferCount())); - mCommandAllocator.attachAllocator(allocator); - getCommandBuffer().attachAllocator(mCommandAllocator.getAllocator()); + attachAllocatorImpl(allocator); } SecondaryCommandMemoryAllocator *RenderPassCommandBufferHelper::detachAllocator() { ASSERT(CheckSubpassCommandBufferCount(getSubpassCommandBufferCount())); - getCommandBuffer().detachAllocator(mCommandAllocator.getAllocator()); - return mCommandAllocator.detachAllocator(getCommandBuffer().empty()); + return detachAllocatorImpl(); +} + +void RenderPassCommandBufferHelper::assertCanBeRecycled() +{ + ASSERT(!mRenderPassStarted); + ASSERT(getSubpassCommandBufferCount() == 1); + assertCanBeRecycledImpl(); } void RenderPassCommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk) @@ -2622,8 +2774,8 @@ void RenderPassCommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk) } // CommandBufferRecycler implementation. -template -void CommandBufferRecycler::onDestroy() +template +void CommandBufferRecycler::onDestroy() { std::unique_lock lock(mMutex); for (CommandBufferHelperT *commandBufferHelper : mCommandBufferHelperFreeList) @@ -2631,19 +2783,15 @@ void CommandBufferRecycler::onDestroy() SafeDelete(commandBufferHelper); } mCommandBufferHelperFreeList.clear(); - - ASSERT(mSecondaryCommandBuffersToReset.empty()); } -template void CommandBufferRecycler::onDestroy(); -template void -CommandBufferRecycler::onDestroy(); +template void CommandBufferRecycler::onDestroy(); +template void CommandBufferRecycler::onDestroy(); -template -angle::Result CommandBufferRecycler::getCommandBufferHelper( +template +angle::Result CommandBufferRecycler::getCommandBufferHelper( Context *context, - CommandPool *commandPool, + SecondaryCommandPool *commandPool, SecondaryCommandMemoryAllocator *commandsAllocator, CommandBufferHelperT **commandBufferHelperOut) { @@ -2652,7 +2800,7 @@ angle::Result CommandBufferRecycler::getCo { CommandBufferHelperT *commandBuffer = new CommandBufferHelperT(); *commandBufferHelperOut = commandBuffer; - ANGLE_TRY(commandBuffer->initialize(context, commandPool)); + ANGLE_TRY(commandBuffer->initialize(context)); } else { @@ -2661,6 +2809,8 @@ angle::Result CommandBufferRecycler::getCo *commandBufferHelperOut = commandBuffer; } + ANGLE_TRY((*commandBufferHelperOut)->attachCommandPool(context, commandPool)); + // Attach functions are only used for ring buffer allocators. (*commandBufferHelperOut)->attachAllocator(commandsAllocator); @@ -2668,43 +2818,61 @@ angle::Result CommandBufferRecycler::getCo } template angle::Result -CommandBufferRecycler:: - getCommandBufferHelper(Context *, - CommandPool *, - SecondaryCommandMemoryAllocator *, - OutsideRenderPassCommandBufferHelper **); -template angle::Result CommandBufferRecycler< - RenderPassCommandBuffer, - RenderPassCommandBufferHelper>::getCommandBufferHelper(Context *, - CommandPool *, - SecondaryCommandMemoryAllocator *, - RenderPassCommandBufferHelper **); - -template -void CommandBufferRecycler::recycleCommandBufferHelper( - VkDevice device, +CommandBufferRecycler::getCommandBufferHelper( + Context *, + SecondaryCommandPool *, + SecondaryCommandMemoryAllocator *, + OutsideRenderPassCommandBufferHelper **); +template angle::Result CommandBufferRecycler::getCommandBufferHelper( + Context *, + SecondaryCommandPool *, + SecondaryCommandMemoryAllocator *, + RenderPassCommandBufferHelper **); + +template +void CommandBufferRecycler::recycleCommandBufferHelper( CommandBufferHelperT **commandBuffer) { - std::unique_lock lock(mMutex); - ASSERT((*commandBuffer)->empty() && !(*commandBuffer)->hasAllocatorLinks()); + (*commandBuffer)->assertCanBeRecycled(); (*commandBuffer)->markOpen(); - RecycleCommandBufferHelper(device, &mCommandBufferHelperFreeList, commandBuffer, - &(*commandBuffer)->getCommandBuffer()); + { + std::unique_lock lock(mMutex); + mCommandBufferHelperFreeList.push_back(*commandBuffer); + } + + *commandBuffer = nullptr; } template void -CommandBufferRecycler:: - recycleCommandBufferHelper(VkDevice, OutsideRenderPassCommandBufferHelper **); -template void CommandBufferRecycler:: - recycleCommandBufferHelper(VkDevice, RenderPassCommandBufferHelper **); +CommandBufferRecycler::recycleCommandBufferHelper( + OutsideRenderPassCommandBufferHelper **); +template void CommandBufferRecycler::recycleCommandBufferHelper( + RenderPassCommandBufferHelper **); -template -void CommandBufferRecycler::resetCommandBuffer( - CommandBufferT &&commandBuffer) +// SecondaryCommandBufferCollector implementation. +void SecondaryCommandBufferCollector::collectCommandBuffer( + priv::SecondaryCommandBuffer &&commandBuffer) { - std::unique_lock lock(mMutex); - ResetSecondaryCommandBuffer(&mSecondaryCommandBuffersToReset, std::move(commandBuffer)); + commandBuffer.reset(); +} + +void SecondaryCommandBufferCollector::collectCommandBuffer( + VulkanSecondaryCommandBuffer &&commandBuffer) +{ + ASSERT(commandBuffer.valid()); + mCollectedCommandBuffers.emplace_back(std::move(commandBuffer)); +} + +void SecondaryCommandBufferCollector::retireCommandBuffers() +{ + // Note: we currently free the command buffers individually, but we could potentially reset the + // entire command pool. https://issuetracker.google.com/issues/166793850 + for (VulkanSecondaryCommandBuffer &commandBuffer : mCollectedCommandBuffers) + { + commandBuffer.destroy(); + } + mCollectedCommandBuffers.clear(); } // DynamicBuffer implementation. @@ -5292,8 +5460,14 @@ angle::Result ImageHelper::initExternal(Context *context, mYcbcrConversionDesc.reset(); - const angle::Format &actualFormat = angle::Format::Get(actualFormatID); - VkFormat actualVkFormat = GetVkFormatFromFormatID(actualFormatID); + const angle::Format &actualFormat = angle::Format::Get(actualFormatID); + const angle::Format &intendedFormat = angle::Format::Get(intendedFormatID); + VkFormat actualVkFormat = GetVkFormatFromFormatID(actualFormatID); + + ANGLE_TRACE_EVENT_INSTANT("gpu.angle.texture_metrics", "ImageHelper::initExternal", + "intended_format", intendedFormat.glInternalFormat, "actual_format", + actualFormat.glInternalFormat, "width", extents.width, "height", + extents.height); if (actualFormat.isYUV) { @@ -5354,7 +5528,10 @@ angle::Result ImageHelper::initExternal(Context *context, imageInfo.pQueueFamilyIndices = nullptr; imageInfo.initialLayout = ConvertImageLayoutToVkImageLayout(context, initialLayout); - mCurrentLayout = initialLayout; + mCurrentLayout = initialLayout; + mCurrentQueueFamilyIndex = std::numeric_limits::max(); + mLastNonShaderReadOnlyLayout = ImageLayout::Undefined; + mCurrentShaderReadStageMask = 0; ANGLE_VK_TRY(context, mImage.init(context->getDevice(), imageInfo)); @@ -5431,6 +5608,9 @@ void ImageHelper::deriveImageViewFormatFromCreateInfoPNext(VkImageCreateInfo &im pNextChain = pNextChain->pNext; } + // Clear formatOut in case it has leftovers from previous VkImage in the case of releaseImage + // followed by initExternal. + std::fill(formatOut.begin(), formatOut.begin() + formatOut.max_size(), VK_FORMAT_UNDEFINED); if (pNextChain != nullptr) { const VkImageFormatListCreateInfoKHR *imageFormatCreateInfo = diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.h index c99e3f5beb30..17febc95fa38 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.h @@ -1095,8 +1095,6 @@ constexpr uint32_t kInfiniteCmdCount = 0xFFFFFFFF; class CommandBufferHelperCommon : angle::NonCopyable { public: - CommandPool *getCommandPool() { return mCommandPool; } - void bufferWrite(ContextVk *contextVk, VkAccessFlags writeAccessType, PipelineStage writeStage, @@ -1136,8 +1134,6 @@ class CommandBufferHelperCommon : angle::NonCopyable const QueueSerial &getQueueSerial() const { return mQueueSerial; } - bool hasAllocatorLinks() const { return mCommandAllocator.hasAllocatorLinks(); } - // Dumping the command stream is disabled by default. static constexpr bool kEnableCommandStreamDiagnostics = false; @@ -1145,10 +1141,25 @@ class CommandBufferHelperCommon : angle::NonCopyable CommandBufferHelperCommon(); ~CommandBufferHelperCommon(); - void initializeImpl(CommandPool *commandPool); + void initializeImpl(); void resetImpl(); + template + angle::Result attachCommandPoolImpl(Context *context, SecondaryCommandPool *commandPool); + template + angle::Result detachCommandPoolImpl(Context *context, SecondaryCommandPool **commandPoolOut); + template + void releaseCommandPoolImpl(); + + template + void attachAllocatorImpl(SecondaryCommandMemoryAllocator *allocator); + template + SecondaryCommandMemoryAllocator *detachAllocatorImpl(); + + template + void assertCanBeRecycledImpl(); + void imageReadImpl(ContextVk *contextVk, VkImageAspectFlags aspectFlags, ImageLayout imageLayout, @@ -1177,7 +1188,7 @@ class CommandBufferHelperCommon : angle::NonCopyable // The command pool *CommandBufferHelper::mCommandBuffer is allocated from. Only used with // Vulkan secondary command buffers (as opposed to ANGLE's SecondaryCommandBuffer). - CommandPool *mCommandPool; + SecondaryCommandPool *mCommandPool; // Whether the command buffers contains any draw/dispatch calls that possibly output data // through storage buffers and images. This is used to determine whether glMemoryBarrier* @@ -1192,23 +1203,36 @@ class CommandBufferHelperCommon : angle::NonCopyable QueueSerial mQueueSerial; }; +class SecondaryCommandBufferCollector; + class OutsideRenderPassCommandBufferHelper final : public CommandBufferHelperCommon { public: OutsideRenderPassCommandBufferHelper(); ~OutsideRenderPassCommandBufferHelper(); - angle::Result initialize(Context *context, CommandPool *commandPool); + angle::Result initialize(Context *context); - angle::Result reset(Context *context); + angle::Result reset(Context *context, SecondaryCommandBufferCollector *commandBufferCollector); + + static constexpr bool ExecutesInline() + { + return OutsideRenderPassCommandBuffer::ExecutesInline(); + } OutsideRenderPassCommandBuffer &getCommandBuffer() { return mCommandBuffer; } bool empty() const { return mCommandBuffer.empty(); } + angle::Result attachCommandPool(Context *context, SecondaryCommandPool *commandPool); + angle::Result detachCommandPool(Context *context, SecondaryCommandPool **commandPoolOut); + void releaseCommandPool(); + void attachAllocator(SecondaryCommandMemoryAllocator *allocator); SecondaryCommandMemoryAllocator *detachAllocator(); + void assertCanBeRecycled(); + #if defined(ANGLE_ENABLE_ASSERTS) void markOpen() { mCommandBuffer.open(); } void markClosed() { mCommandBuffer.close(); } @@ -1231,7 +1255,9 @@ class OutsideRenderPassCommandBufferHelper final : public CommandBufferHelperCom ImageLayout imageLayout, ImageHelper *image); - angle::Result flushToPrimary(Context *context, PrimaryCommandBuffer *primary); + angle::Result flushToPrimary(Context *context, + PrimaryCommandBuffer *primary, + SecondaryCommandBufferCollector *commandBufferCollector); void setGLMemoryBarrierIssued() { @@ -1250,8 +1276,12 @@ class OutsideRenderPassCommandBufferHelper final : public CommandBufferHelperCom private: angle::Result initializeCommandBuffer(Context *context); + angle::Result endCommandBuffer(Context *context); OutsideRenderPassCommandBuffer mCommandBuffer; + bool mIsCommandBufferEnded = false; + + friend class CommandBufferHelperCommon; }; enum class ImagelessStatus @@ -1301,9 +1331,11 @@ class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon RenderPassCommandBufferHelper(); ~RenderPassCommandBufferHelper(); - angle::Result initialize(Context *context, CommandPool *commandPool); + angle::Result initialize(Context *context); + + angle::Result reset(Context *context, SecondaryCommandBufferCollector *commandBufferCollector); - angle::Result reset(Context *context); + static constexpr bool ExecutesInline() { return RenderPassCommandBuffer::ExecutesInline(); } RenderPassCommandBuffer &getCommandBuffer() { @@ -1312,9 +1344,15 @@ class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon bool empty() const { return !started(); } + angle::Result attachCommandPool(Context *context, SecondaryCommandPool *commandPool); + void detachCommandPool(SecondaryCommandPool **commandPoolOut); + void releaseCommandPool(); + void attachAllocator(SecondaryCommandMemoryAllocator *allocator); SecondaryCommandMemoryAllocator *detachAllocator(); + void assertCanBeRecycled(); + #if defined(ANGLE_ENABLE_ASSERTS) void markOpen() { getCommandBuffer().open(); } void markClosed() { getCommandBuffer().close(); } @@ -1356,7 +1394,8 @@ class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon angle::Result flushToPrimary(Context *context, PrimaryCommandBuffer *primary, - const RenderPass *renderPass); + const RenderPass *renderPass, + SecondaryCommandBufferCollector *commandBufferCollector); bool started() const { return mRenderPassStarted; } @@ -1549,11 +1588,13 @@ class RenderPassCommandBufferHelper final : public CommandBufferHelperCommon // This is last renderpass before present and this is the image will be presented. We can use // final layout of the renderpass to transition it to the presentable layout ImageHelper *mImageOptimizeForPresent; + + friend class CommandBufferHelperCommon; }; // The following class helps support both Vulkan and ANGLE secondary command buffers by // encapsulating their differences. -template +template class CommandBufferRecycler { public: @@ -1563,24 +1604,35 @@ class CommandBufferRecycler void onDestroy(); angle::Result getCommandBufferHelper(Context *context, - CommandPool *commandPool, + SecondaryCommandPool *commandPool, SecondaryCommandMemoryAllocator *commandsAllocator, CommandBufferHelperT **commandBufferHelperOut); - void recycleCommandBufferHelper(VkDevice device, CommandBufferHelperT **commandBuffer); - - void resetCommandBuffer(CommandBufferT &&commandBuffer); - - void releaseCommandBuffersToReset(std::vector *vectorOut) - { - std::unique_lock lock(mMutex); - (*vectorOut) = std::move(mSecondaryCommandBuffersToReset); - } + void recycleCommandBufferHelper(CommandBufferHelperT **commandBuffer); private: std::mutex mMutex; std::vector mCommandBufferHelperFreeList; - std::vector mSecondaryCommandBuffersToReset; +}; + +class SecondaryCommandBufferCollector final +{ + public: + SecondaryCommandBufferCollector() = default; + SecondaryCommandBufferCollector(const SecondaryCommandBufferCollector &) = delete; + SecondaryCommandBufferCollector(SecondaryCommandBufferCollector &&) = default; + void operator=(const SecondaryCommandBufferCollector &) = delete; + SecondaryCommandBufferCollector &operator=(SecondaryCommandBufferCollector &&) = default; + ~SecondaryCommandBufferCollector() { ASSERT(empty()); } + + void collectCommandBuffer(priv::SecondaryCommandBuffer &&commandBuffer); + void collectCommandBuffer(VulkanSecondaryCommandBuffer &&commandBuffer); + void retireCommandBuffers(); + + bool empty() const { return mCollectedCommandBuffers.empty(); } + + private: + std::vector mCollectedCommandBuffers; }; // Imagine an image going through a few layout transitions: diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.cpp index 4de33b12b172..21a4a6496c9d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.cpp @@ -890,9 +890,7 @@ void ClearValuesArray::storeNoDepthStencil(uint32_t index, const VkClearValue &c gl::DrawBufferMask ClearValuesArray::getColorMask() const { - constexpr uint32_t kColorBuffersMask = - angle::BitMask(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); - return gl::DrawBufferMask(mEnabled.bits() & kColorBuffersMask); + return gl::DrawBufferMask(mEnabled.bits() & kUnpackedColorBuffersMask); } // ResourceSerialFactory implementation. diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.h index d1c2c1d24cd3..c9b925849575 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.h @@ -25,6 +25,7 @@ #include "libANGLE/angletypes.h" #include "libANGLE/renderer/serial_utils.h" #include "libANGLE/renderer/vulkan/SecondaryCommandBuffer.h" +#include "libANGLE/renderer/vulkan/SecondaryCommandPool.h" #include "libANGLE/renderer/vulkan/VulkanSecondaryCommandBuffer.h" #include "libANGLE/renderer/vulkan/vk_wrapper.h" #include "platform/FeaturesVk_autogen.h" @@ -311,16 +312,10 @@ using RenderPassCommandBuffer = priv::SecondaryCommandBuffer; using RenderPassCommandBuffer = VulkanSecondaryCommandBuffer; #endif -struct SecondaryCommandBufferList -{ - std::vector outsideRenderPassCommandBuffers; - std::vector renderPassCommandBuffers; -}; - struct SecondaryCommandPools { - CommandPool outsideRenderPassPool; - CommandPool renderPassPool; + SecondaryCommandPool outsideRenderPassPool; + SecondaryCommandPool renderPassPool; }; VkImageAspectFlags GetDepthStencilAspectFlags(const angle::Format &format); @@ -910,6 +905,8 @@ void MakeDebugUtilsLabel(GLenum source, const char *marker, VkDebugUtilsLabelEXT constexpr size_t kUnpackedDepthIndex = gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; constexpr size_t kUnpackedStencilIndex = gl::IMPLEMENTATION_MAX_DRAW_BUFFERS + 1; +constexpr uint32_t kUnpackedColorBuffersMask = + angle::BitMask(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); class ClearValuesArray final { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vulkan_backend.gni b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vulkan_backend.gni index 8372fa303623..93c5a9747945 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vulkan_backend.gni +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vulkan_backend.gni @@ -57,6 +57,8 @@ vulkan_backend_sources = [ "SamplerVk.h", "SecondaryCommandBuffer.cpp", "SecondaryCommandBuffer.h", + "SecondaryCommandPool.cpp", + "SecondaryCommandPool.h", "SemaphoreVk.cpp", "SemaphoreVk.h", "ShaderInterfaceVariableInfoMap.cpp", diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/trace.h b/Source/ThirdParty/ANGLE/src/libANGLE/trace.h index d4600adbfc64..5d9a6350781d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/trace.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/trace.h @@ -13,14 +13,27 @@ #include "common/base/anglebase/trace_event/trace_event.h" // TODO: Pass platform directly to these methods. http://anglebug.com/1892 -#define ANGLE_TRACE_EVENT_BEGIN0(CATEGORY, EVENT) \ - TRACE_EVENT_BEGIN0(ANGLEPlatformCurrent(), CATEGORY, EVENT) -#define ANGLE_TRACE_EVENT_END0(CATEGORY, EVENT) \ - TRACE_EVENT_END0(ANGLEPlatformCurrent(), CATEGORY, EVENT) -#define ANGLE_TRACE_EVENT_INSTANT0(CATEGORY, EVENT) \ - TRACE_EVENT_INSTANT0(ANGLEPlatformCurrent(), CATEGORY, EVENT) -#define ANGLE_TRACE_EVENT0(CATEGORY, EVENT) TRACE_EVENT0(ANGLEPlatformCurrent(), CATEGORY, EVENT) -#define ANGLE_TRACE_EVENT1(CATEGORY, EVENT, NAME, PARAM) \ - TRACE_EVENT1(ANGLEPlatformCurrent(), CATEGORY, EVENT, NAME, PARAM) +#define ANGLE_TRACE_EVENT_BEGIN(CATEGORY, EVENT, ...) \ + TRACE_EVENT_BEGIN(ANGLEPlatformCurrent(), CATEGORY, EVENT, ##__VA_ARGS__) + +#define ANGLE_TRACE_EVENT_END(CATEGORY, EVENT, ...) \ + TRACE_EVENT_END(ANGLEPlatformCurrent(), CATEGORY, EVENT, ##__VA_ARGS__) + +#define ANGLE_TRACE_EVENT_INSTANT(CATEGORY, EVENT, ...) \ + TRACE_EVENT_INSTANT(ANGLEPlatformCurrent(), CATEGORY, EVENT, ##__VA_ARGS__) + +#define ANGLE_TRACE_EVENT(CATEGORY, EVENT, ...) \ + TRACE_EVENT(ANGLEPlatformCurrent(), CATEGORY, EVENT, ##__VA_ARGS__) + +// Deprecated, use ANGLE_TRACE_EVENT_BEGIN +#define ANGLE_TRACE_EVENT_BEGIN0(CATEGORY, EVENT) ANGLE_TRACE_EVENT_BEGIN(CATEGORY, EVENT) +// Deprecated, use ANGLE_TRACE_EVENT_END +#define ANGLE_TRACE_EVENT_END0(CATEGORY, EVENT) ANGLE_TRACE_EVENT_END(CATEGORY, EVENT) +// Deprecated, use ANGLE_TRACE_EVENT_INSTANT +#define ANGLE_TRACE_EVENT_INSTANT0(CATEGORY, EVENT) ANGLE_TRACE_EVENT_INSTANT(CATEGORY, EVENT) +// Deprecated, use ANGLE_TRACE_EVENT +#define ANGLE_TRACE_EVENT0(CATEGORY, EVENT) ANGLE_TRACE_EVENT(CATEGORY, EVENT) +// Deprecated, use ANGLE_TRACE_EVENT +#define ANGLE_TRACE_EVENT1(CATEGORY, EVENT, NAME, VAL) ANGLE_TRACE_EVENT(CATEGORY, EVENT, NAME, VAL) #endif // LIBANGLE_TRACE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp index c6f9fc097e62..abacdafe6f3e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp @@ -613,6 +613,9 @@ bool ValidCap(const Context *context, GLenum cap, bool queryOnly) case GL_DITHER: return true; + case GL_DEPTH_CLAMP_EXT: + return context->getExtensions().depthClampEXT; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: case GL_RASTERIZER_DISCARD: return (context->getClientMajorVersion() >= 3); @@ -2094,19 +2097,13 @@ bool ValidateGetDebugMessageLogKHR(const Context *context, return true; } -bool ValidatePushDebugGroupKHR(const Context *context, - angle::EntryPoint entryPoint, - GLenum source, - GLuint id, - GLsizei length, - const GLchar *message) +bool ValidatePushDebugGroupBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message) { - if (!context->getExtensions().debugKHR) - { - context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); - return false; - } - if (!ValidDebugSource(source, true)) { context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource); @@ -2130,7 +2127,24 @@ bool ValidatePushDebugGroupKHR(const Context *context, return true; } -bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoint) +bool ValidatePopDebugGroupBase(const Context *context, angle::EntryPoint entryPoint) +{ + size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); + if (currentStackSize <= 1) + { + context->validationError(entryPoint, GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup); + return false; + } + + return true; +} + +bool ValidatePushDebugGroupKHR(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message) { if (!context->getExtensions().debugKHR) { @@ -2138,14 +2152,18 @@ bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoi return false; } - size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); - if (currentStackSize <= 1) + return ValidatePushDebugGroupBase(context, entryPoint, source, id, length, message); +} + +bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoint) +{ + if (!context->getExtensions().debugKHR) { - context->validationError(entryPoint, GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup); + context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); return false; } - return true; + return ValidatePopDebugGroupBase(context, entryPoint); } static bool ValidateObjectIdentifierAndName(const Context *context, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h index 399779aa7cfd..199e8cb9d0ec 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h @@ -202,6 +202,15 @@ bool ValidateES2TexStorageParametersBase(const Context *context, GLsizei width, GLsizei height); +// Validation of [Push,Pop]DebugGroup +bool ValidatePushDebugGroupBase(const Context *context, + angle::EntryPoint entryPoint, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); +bool ValidatePopDebugGroupBase(const Context *context, angle::EntryPoint entryPoint); + } // namespace gl #endif // LIBANGLE_VALIDATION_ES2_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES32.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationES32.cpp index f1b71d4aef35..69df0e793b85 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES32.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES32.cpp @@ -13,7 +13,7 @@ #include "libANGLE/Framebuffer.h" #include "libANGLE/VertexArray.h" #include "libANGLE/validationES.h" -#include "libANGLE/validationES2_autogen.h" +#include "libANGLE/validationES2.h" #include "libANGLE/validationES3.h" #include "libANGLE/validationES31.h" #include "libANGLE/validationES31_autogen.h" @@ -538,7 +538,7 @@ bool ValidatePatchParameteri(const Context *context, bool ValidatePopDebugGroup(const Context *context, angle::EntryPoint entryPoint) { - return true; + return ValidatePopDebugGroupBase(context, entryPoint); } bool ValidatePrimitiveBoundingBox(const Context *context, @@ -562,7 +562,7 @@ bool ValidatePushDebugGroup(const Context *context, GLsizei length, const GLchar *message) { - return true; + return ValidatePushDebugGroupBase(context, entryPoint, source, id, length, message); } bool ValidateReadnPixels(const Context *context, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT.cpp index b737d1abf98e..4db2a73a9063 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT.cpp @@ -1612,6 +1612,28 @@ bool ValidatePLSCommon(const Context *context, return false; } + Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + if (expectedStatus != PLSExpectedStatus::Active) + { + // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is + // bound to DRAW_FRAMEBUFFER. + if (framebuffer->id().value == 0) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kPLSDefaultFramebufferBound); + return false; + } + } + + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // in an interrupted state. + const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage(); + if (pls != nullptr && pls->interruptCount() != 0) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterrupted); + return false; + } + if (expectedStatus == PLSExpectedStatus::Active) { // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero. @@ -1624,19 +1646,8 @@ bool ValidatePLSCommon(const Context *context, else { // PLSExpectedStatus::Inactive is validated by the allow list. - if (expectedStatus == PLSExpectedStatus::Inactive) - { - ASSERT(context->getState().getPixelLocalStorageActivePlanes() == 0); - } - - // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is - // bound to DRAW_FRAMEBUFFER. - if (context->getState().getDrawFramebuffer()->id().value == 0) - { - context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, - kPLSDefaultFramebufferBound); - return false; - } + ASSERT(expectedStatus != PLSExpectedStatus::Inactive || + context->getState().getPixelLocalStorageActivePlanes() == 0); } return true; @@ -2137,6 +2148,59 @@ bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryP return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active); } +bool ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context *context, + angle::EntryPoint entryPoint) +{ + // Check that the pixel local storage extension is enabled at all. + if (!context->getExtensions().shaderPixelLocalStorageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSExtensionNotEnabled); + return false; + } + + // INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt count on the draw + // framebuffer is greater than or equal to 255. + const PixelLocalStorage *pls = + context->getState().getDrawFramebuffer()->peekPixelLocalStorage(); + if (pls != nullptr && pls->interruptCount() >= 255) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, + kPLSInterruptOverflow); + return false; + } + + return true; +} + +bool ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context *context, + angle::EntryPoint entryPoint) +{ + // Check that the pixel local storage extension is enabled at all. + if (!context->getExtensions().shaderPixelLocalStorageANGLE) + { + context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSExtensionNotEnabled); + return false; + } + + // This command is ignored when the default framebuffer object name 0 is bound. + const Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + if (context->getState().getDrawFramebuffer()->id().value == 0) + { + return true; + } + + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // not in an interrupted state. + const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage(); + if (pls == nullptr || pls->interruptCount() == 0) + { + context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, kPLSNotInterrupted); + return false; + } + + return true; +} + bool ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context *context, angle::EntryPoint entryPoint, GLint plane, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT_autogen.h b/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT_autogen.h index 70f7614e433a..91114f924850 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT_autogen.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT_autogen.h @@ -884,6 +884,10 @@ bool ValidateEndPixelLocalStorageANGLE(const Context *context, GLsizei n, const GLenum *storeops); bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint); +bool ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context *context, + angle::EntryPoint entryPoint); +bool ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context *context, + angle::EntryPoint entryPoint); bool ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context *context, angle::EntryPoint entryPoint, GLint plane, diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/egl_ext_stubs.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/egl_ext_stubs.cpp index dab72aa20bae..fe6c87a35e7d 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/egl_ext_stubs.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/egl_ext_stubs.cpp @@ -640,13 +640,13 @@ EGLBoolean SwapBuffersWithDamageKHR(Thread *thread, EGLBoolean PrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface) { - ANGLE_SCOPED_GLOBAL_SURFACE_LOCK(); - - egl::Display *dpyPacked = PackParam(dpy); - SurfaceID surfacePacked = PackParam(surface); - Thread *thread = egl::GetCurrentThread(); - Surface *surfacePtr = nullptr; + egl::Display *dpyPacked = PackParam(dpy); + SurfaceID surfacePacked = PackParam(surface); + Thread *thread = egl::GetCurrentThread(); + Surface *surfacePtr = nullptr; + const egl::Surface *eglSurface = nullptr; { + ANGLE_SCOPED_GLOBAL_SURFACE_LOCK(); ANGLE_SCOPED_GLOBAL_LOCK(); EGL_EVENT(PrepareSwapBuffersANGLE, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR "", @@ -659,9 +659,10 @@ EGLBoolean PrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface) GetDisplayIfValid(dpyPacked), EGL_FALSE); surfacePtr = dpyPacked->getSurface(surfacePacked); + eglSurface = GetSurfaceIfValid(dpyPacked, surfacePacked); } ANGLE_EGL_TRY_RETURN(thread, surfacePtr->prepareSwap(thread->getContext()), "prepareSwap", - GetSurfaceIfValid(dpyPacked, surfacePacked), EGL_FALSE); + eglSurface, EGL_FALSE); thread->setSuccess(); return EGL_TRUE; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.cpp index 15828e0d6bc5..9706609775e6 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.cpp @@ -4016,6 +4016,56 @@ void GL_APIENTRY GL_PixelLocalStorageBarrierANGLE() } } +void GL_APIENTRY GL_FramebufferPixelLocalStorageInterruptANGLE() +{ + Context *context = GetValidGlobalContext(); + EVENT(context, GLFramebufferPixelLocalStorageInterruptANGLE, "context = %d", CID(context)); + + if (context) + { + SCOPED_SHARE_CONTEXT_LOCK(context); + bool isCallValid = + (context->skipValidation() || + ValidateFramebufferPixelLocalStorageInterruptANGLE( + context, angle::EntryPoint::GLFramebufferPixelLocalStorageInterruptANGLE)); + if (isCallValid) + { + context->framebufferPixelLocalStorageInterrupt(); + } + ANGLE_CAPTURE_GL(FramebufferPixelLocalStorageInterruptANGLE, isCallValid, context); + } + else + { + GenerateContextLostErrorOnCurrentGlobalContext(); + } +} + +void GL_APIENTRY GL_FramebufferPixelLocalStorageRestoreANGLE() +{ + Context *context = GetValidGlobalContext(); + EVENT(context, GLFramebufferPixelLocalStorageRestoreANGLE, "context = %d", CID(context)); + + if (context) + { + SCOPED_SHARE_CONTEXT_LOCK(context); + bool isCallValid = + (context->skipValidation() || + (ValidatePixelLocalStorageInactive( + context, angle::EntryPoint::GLFramebufferPixelLocalStorageRestoreANGLE) && + ValidateFramebufferPixelLocalStorageRestoreANGLE( + context, angle::EntryPoint::GLFramebufferPixelLocalStorageRestoreANGLE))); + if (isCallValid) + { + context->framebufferPixelLocalStorageRestore(); + } + ANGLE_CAPTURE_GL(FramebufferPixelLocalStorageRestoreANGLE, isCallValid, context); + } + else + { + GenerateContextLostErrorOnCurrentGlobalContext(); + } +} + void GL_APIENTRY GL_GetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLfloat *params) diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.h b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.h index 4a4afb0521ac..141169f144ff 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.h @@ -659,6 +659,8 @@ ANGLE_EXPORT void GL_APIENTRY GL_FramebufferPixelLocalClearValueuivANGLE(GLint p ANGLE_EXPORT void GL_APIENTRY GL_BeginPixelLocalStorageANGLE(GLsizei n, const GLenum *loadops); ANGLE_EXPORT void GL_APIENTRY GL_EndPixelLocalStorageANGLE(GLsizei n, const GLenum *storeops); ANGLE_EXPORT void GL_APIENTRY GL_PixelLocalStorageBarrierANGLE(); +ANGLE_EXPORT void GL_APIENTRY GL_FramebufferPixelLocalStorageInterruptANGLE(); +ANGLE_EXPORT void GL_APIENTRY GL_FramebufferPixelLocalStorageRestoreANGLE(); ANGLE_EXPORT void GL_APIENTRY GL_GetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLfloat *params); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.cpp index 089e7b62c158..12bbf5cddb99 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.cpp @@ -3814,6 +3814,16 @@ void GL_APIENTRY glPixelLocalStorageBarrierANGLE() return GL_PixelLocalStorageBarrierANGLE(); } +void GL_APIENTRY glFramebufferPixelLocalStorageInterruptANGLE() +{ + return GL_FramebufferPixelLocalStorageInterruptANGLE(); +} + +void GL_APIENTRY glFramebufferPixelLocalStorageRestoreANGLE() +{ + return GL_FramebufferPixelLocalStorageRestoreANGLE(); +} + void GL_APIENTRY glGetFramebufferPixelLocalStorageParameterfvANGLE(GLint plane, GLenum pname, GLfloat *params) diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.def index 78d981b5d2de..7f4afe2be034 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.def @@ -616,6 +616,8 @@ EXPORTS glFramebufferPixelLocalClearValuefvANGLE glFramebufferPixelLocalClearValueivANGLE glFramebufferPixelLocalClearValueuivANGLE + glFramebufferPixelLocalStorageInterruptANGLE + glFramebufferPixelLocalStorageRestoreANGLE glFramebufferTexturePixelLocalStorageANGLE glGetFramebufferPixelLocalStorageParameterfvANGLE glGetFramebufferPixelLocalStorageParameterfvRobustANGLE diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_no_capture_autogen.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_no_capture_autogen.def index 0ea1bbb43871..40cb88321fb3 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_no_capture_autogen.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_no_capture_autogen.def @@ -616,6 +616,8 @@ EXPORTS glFramebufferPixelLocalClearValuefvANGLE glFramebufferPixelLocalClearValueivANGLE glFramebufferPixelLocalClearValueuivANGLE + glFramebufferPixelLocalStorageInterruptANGLE + glFramebufferPixelLocalStorageRestoreANGLE glFramebufferTexturePixelLocalStorageANGLE glGetFramebufferPixelLocalStorageParameterfvANGLE glGetFramebufferPixelLocalStorageParameterfvRobustANGLE diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_vulkan_secondaries_autogen.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_vulkan_secondaries_autogen.def index faf3b9ca3c89..ba748414fc7b 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_vulkan_secondaries_autogen.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_vulkan_secondaries_autogen.def @@ -616,6 +616,8 @@ EXPORTS glFramebufferPixelLocalClearValuefvANGLE glFramebufferPixelLocalClearValueivANGLE glFramebufferPixelLocalClearValueuivANGLE + glFramebufferPixelLocalStorageInterruptANGLE + glFramebufferPixelLocalStorageRestoreANGLE glFramebufferTexturePixelLocalStorageANGLE glGetFramebufferPixelLocalStorageParameterfvANGLE glGetFramebufferPixelLocalStorageParameterfvRobustANGLE diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_with_capture_autogen.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_with_capture_autogen.def index 4f570808978c..1d2c78de83ac 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_with_capture_autogen.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_with_capture_autogen.def @@ -616,6 +616,8 @@ EXPORTS glFramebufferPixelLocalClearValuefvANGLE glFramebufferPixelLocalClearValueivANGLE glFramebufferPixelLocalClearValueuivANGLE + glFramebufferPixelLocalStorageInterruptANGLE + glFramebufferPixelLocalStorageRestoreANGLE glFramebufferTexturePixelLocalStorageANGLE glGetFramebufferPixelLocalStorageParameterfvANGLE glGetFramebufferPixelLocalStorageParameterfvRobustANGLE diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_autogen.def b/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_autogen.def index 33b44aa5402b..d4137557d8dd 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_autogen.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_autogen.def @@ -616,6 +616,8 @@ EXPORTS glFramebufferPixelLocalClearValuefvANGLE glFramebufferPixelLocalClearValueivANGLE glFramebufferPixelLocalClearValueuivANGLE + glFramebufferPixelLocalStorageInterruptANGLE + glFramebufferPixelLocalStorageRestoreANGLE glFramebufferTexturePixelLocalStorageANGLE glGetFramebufferPixelLocalStorageParameterfvANGLE glGetFramebufferPixelLocalStorageParameterfvRobustANGLE diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_with_wgl_autogen.def b/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_with_wgl_autogen.def index 4da9d2305d22..6ce33cd6d0f9 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_with_wgl_autogen.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/opengl32_with_wgl_autogen.def @@ -616,6 +616,8 @@ EXPORTS glFramebufferPixelLocalClearValuefvANGLE glFramebufferPixelLocalClearValueivANGLE glFramebufferPixelLocalClearValueuivANGLE + glFramebufferPixelLocalStorageInterruptANGLE + glFramebufferPixelLocalStorageRestoreANGLE glFramebufferTexturePixelLocalStorageANGLE glGetFramebufferPixelLocalStorageParameterfvANGLE glGetFramebufferPixelLocalStorageParameterfvRobustANGLE diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_egl_autogen.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_egl_autogen.cpp index d8165c24019f..b5ca18634b77 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_egl_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_egl_autogen.cpp @@ -516,6 +516,8 @@ const ProcEntry g_procTable[] = { {"glFramebufferPixelLocalClearValuefvANGLE", P(GL_FramebufferPixelLocalClearValuefvANGLE)}, {"glFramebufferPixelLocalClearValueivANGLE", P(GL_FramebufferPixelLocalClearValueivANGLE)}, {"glFramebufferPixelLocalClearValueuivANGLE", P(GL_FramebufferPixelLocalClearValueuivANGLE)}, + {"glFramebufferPixelLocalStorageInterruptANGLE", P(GL_FramebufferPixelLocalStorageInterruptANGLE)}, + {"glFramebufferPixelLocalStorageRestoreANGLE", P(GL_FramebufferPixelLocalStorageRestoreANGLE)}, {"glFramebufferRenderbuffer", P(GL_FramebufferRenderbuffer)}, {"glFramebufferRenderbufferOES", P(GL_FramebufferRenderbufferOES)}, {"glFramebufferTexture", P(GL_FramebufferTexture)}, diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_glx_autogen.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_glx_autogen.cpp index 76d6c25c180b..e77c38aeb4dd 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_glx_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_glx_autogen.cpp @@ -396,6 +396,8 @@ const ProcEntry g_procTable[] = { {"glFramebufferPixelLocalClearValuefvANGLE", P(GL_FramebufferPixelLocalClearValuefvANGLE)}, {"glFramebufferPixelLocalClearValueivANGLE", P(GL_FramebufferPixelLocalClearValueivANGLE)}, {"glFramebufferPixelLocalClearValueuivANGLE", P(GL_FramebufferPixelLocalClearValueuivANGLE)}, + {"glFramebufferPixelLocalStorageInterruptANGLE", P(GL_FramebufferPixelLocalStorageInterruptANGLE)}, + {"glFramebufferPixelLocalStorageRestoreANGLE", P(GL_FramebufferPixelLocalStorageRestoreANGLE)}, {"glFramebufferRenderbuffer", P(GL_FramebufferRenderbuffer)}, {"glFramebufferRenderbufferOES", P(GL_FramebufferRenderbufferOES)}, {"glFramebufferTexture", P(GL_FramebufferTexture)}, diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_wgl_autogen.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_wgl_autogen.cpp index 436e49a8c0e2..929ea1599894 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_wgl_autogen.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/proc_table_wgl_autogen.cpp @@ -396,6 +396,8 @@ const ProcEntry g_procTable[] = { {"glFramebufferPixelLocalClearValuefvANGLE", P(GL_FramebufferPixelLocalClearValuefvANGLE)}, {"glFramebufferPixelLocalClearValueivANGLE", P(GL_FramebufferPixelLocalClearValueivANGLE)}, {"glFramebufferPixelLocalClearValueuivANGLE", P(GL_FramebufferPixelLocalClearValueuivANGLE)}, + {"glFramebufferPixelLocalStorageInterruptANGLE", P(GL_FramebufferPixelLocalStorageInterruptANGLE)}, + {"glFramebufferPixelLocalStorageRestoreANGLE", P(GL_FramebufferPixelLocalStorageRestoreANGLE)}, {"glFramebufferRenderbuffer", P(GL_FramebufferRenderbuffer)}, {"glFramebufferRenderbufferOES", P(GL_FramebufferRenderbufferOES)}, {"glFramebufferTexture", P(GL_FramebufferTexture)}, diff --git a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni index d229d0af7e8b..81eb874a056d 100644 --- a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni +++ b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni @@ -62,6 +62,7 @@ angle_end2end_tests_sources = [ "gl_tests/DebugTest.cpp", "gl_tests/DepthStencilFormatsTest.cpp", "gl_tests/DepthStencilTest.cpp", + "gl_tests/DepthWriteTest.cpp", "gl_tests/DesktopGLSLTest.cpp", "gl_tests/DifferentStencilMasksTest.cpp", "gl_tests/DiscardFramebufferEXTTest.cpp", diff --git a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt index 99f6a053022b..c32a519b87ed 100644 --- a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt +++ b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt @@ -356,6 +356,29 @@ 7451 MAC METAL INTEL : PointSpritesTest.PointSizeAboveMaxIsClamped/ES2_Metal = SKIP +// New failures on MacBook Pro 2019 macOS 13.2.1 +8091 MAC METAL AMD : ClearTest.ClearStencilMask/* = SKIP +8091 MAC METAL AMD : ClearTestES3.ClearBufferivStencilMask/* = SKIP +8091 MAC METAL AMD : ClearTestES3.RepeatedStencilClear/* = SKIP +8091 MAC METAL AMD : DepthWriteTest.Test/* = SKIP +8091 MAC METAL AMD : MaskedScissoredClearTest.Test/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.Coherency/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.ForgetBarrier/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.FragmentReject_viewport/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.FunctionArguments/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.Interrupt/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.LoadAfterStore/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.LoadOnly/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.LoadOps/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.MaxCombinedDrawBuffersAndPLSPlanes/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.MemorylessStorage/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.MipMapLevels/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.PLSWithSamplers/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.ProgramCache/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.R32/* = SKIP +8091 MAC METAL AMD : PixelLocalStorageTest.RGBA8/* = SKIP +8091 MAC METAL AMD : StateChangeTestES3.StencilReferenceAndCompareMask/* = SKIP + // D3D 6432 WIN D3D9 : GLSLTest.HandleExcessiveLoopBug/* = SKIP @@ -381,6 +404,7 @@ 7294 WIN D3D11 : StateChangeTestES3.StencilWriteMask/* = SKIP 7316 WIN D3D11 : StateChangeTestES3.StencilTestAndFunc/* = SKIP 7329 WIN D3D11 : StateChangeTestES3.PrimitiveRestart/* = SKIP +8100 WIN D3D11 : WebGL2GLSLTest.InitOutputParams/* = SKIP // Android 6095 ANDROID GLES : GLSLTest_ES3.InitGlobalComplexConstant/* = SKIP @@ -484,6 +508,7 @@ 7414 PIXEL4ORXL GLES : EGLMultiContextTest.ThreadB*BeforeThreadASync* = SKIP 7703 PIXEL4ORXL GLES : FramebufferFetchES31.ProgramPipeline* = SKIP 7703 PIXEL4ORXL GLES : FramebufferFetchES31.DrawNonFetchDrawFetchInStorageBuffer* = SKIP +2046 PIXEL4ORXL GLES : WebGL2GLSLTest.InitOutputParams/* = SKIP 3423 PIXEL4ORXL VULKAN : ClearTestES3.MaskedClearBufferBug/* = SKIP 3423 PIXEL4ORXL VULKAN : DrawBuffersWebGL2Test.TwoProgramsWithDifferentOutputsAndClear/* = SKIP @@ -810,6 +835,8 @@ 7994 IOS METAL : PixelLocalStorageTest.FragmentReject_viewport/ES3_Metal_EmulatePixelLocalStorage_DisableRasterOrderGroups = SKIP 7994 IOS METAL : PixelLocalStorageTest.FunctionArguments/ES3_Metal_EmulatePixelLocalStorage = SKIP 7994 IOS METAL : PixelLocalStorageTest.FunctionArguments/ES3_Metal_EmulatePixelLocalStorage_DisableRasterOrderGroups = SKIP +7994 IOS METAL : PixelLocalStorageTest.Interrupt/ES3_Metal_EmulatePixelLocalStorage = SKIP +7994 IOS METAL : PixelLocalStorageTest.Interrupt/ES3_Metal_EmulatePixelLocalStorage_DisableRasterOrderGroups = SKIP 7994 IOS METAL : PixelLocalStorageTest.LoadAfterStore/ES3_Metal_EmulatePixelLocalStorage = SKIP 7994 IOS METAL : PixelLocalStorageTest.LoadAfterStore/ES3_Metal_EmulatePixelLocalStorage_DisableRasterOrderGroups = SKIP 7994 IOS METAL : PixelLocalStorageTest.LoadOnly/ES3_Metal_EmulatePixelLocalStorage = SKIP @@ -1092,6 +1119,47 @@ 8048 NVIDIA OPENGL : FramebufferTest_ES3.RenderSnorm16* = SKIP 8048 NVIDIA GLES : FramebufferTest_ES3.RenderSnorm16* = SKIP +// D3D needs a workaround to follow OpenGL rules +8077 D3D9 : DepthWriteTest.Test/ES2_D3D9__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenZeroAndNearPlane_* = SKIP +8077 D3D9 : DepthWriteTest.Test/ES2_D3D9__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenFarPlaneAndOne_* = SKIP +8077 D3D9 : DepthWriteTest.Test/ES2_D3D9__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthNegative_* = SKIP +8077 D3D9 : DepthWriteTest.Test/ES2_D3D9__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthGreaterThanOne_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES2_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenZeroAndNearPlane_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES2_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenFarPlaneAndOne_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES2_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthNegative_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES2_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthGreaterThanOne_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES3_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenZeroAndNearPlane_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES3_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenFarPlaneAndOne_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES3_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthNegative_* = SKIP +8077 D3D11 : DepthWriteTest.Test/ES3_D3D11__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthGreaterThanOne_* = SKIP + +// Vulkan needs a workaround and/or extensions usage to avoid undefined behavior +8077 VULKAN : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenZeroAndNearPlane_* = SKIP +8077 VULKAN : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenFarPlaneAndOne_* = SKIP +8077 VULKAN : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthNegative_* = SKIP +8077 VULKAN : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthGreaterThanOne_* = SKIP + +// Driver bugs +8077 WIN INTEL OPENGL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenZeroAndNearPlane_* = SKIP +8077 WIN INTEL OPENGL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenFarPlaneAndOne_* = SKIP +8077 WIN INTEL OPENGL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthNegative_* = SKIP +8077 WIN INTEL OPENGL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthGreaterThanOne_* = SKIP +8077 MAC INTEL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenZeroAndNearPlane_* = SKIP +8077 MAC INTEL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenFarPlaneAndOne_* = SKIP +8077 MAC INTEL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthNegative_* = SKIP +8077 MAC INTEL : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthGreaterThanOne_* = SKIP +8077 IOS : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenZeroAndNearPlane_* = SKIP +8077 IOS : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthBetweenFarPlaneAndOne_* = SKIP +8077 IOS : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthNegative_* = SKIP +8077 IOS : DepthWriteTest.Test/*__DepthRangeReduced_Clipped_VertexDepthInsideClipVolume_FragmentDepthGreaterThanOne_* = SKIP + +// gl_PointCoord origin is flipped for non-default framebuffers +8066 WIN INTEL OPENGL : ClipControlTest.OriginPointCoord/* = SKIP + +// Sample coverage must not affect single sample render targets +8102 D3D11 : SimpleOperationTest.DrawSingleSampleWithCoverage/* = SKIP +8102 VULKAN : SimpleOperationTest.DrawSingleSampleWithCoverage/* = SKIP + // bits 24..31 from glClearValueuiv value don't work on Intel Metal. 7794 MAC INTEL METAL : PixelLocalStorageTest.ClearValues_r32/* = SKIP @@ -1107,3 +1175,7 @@ 6261 : MultithreadingTest* = TIMEOUT // Please do not add expectations below this line, // so that TIMEOUT expectations above don't override more precise SKIP expectations + +// SSBO Alias Overwrite +5990 PIXEL4ORXL VULKAN : ComputeShaderTest.SSBOAliasOverWrite/* = SKIP +266235549 D3D11 : ComputeShaderTest.SSBOAliasOverWrite/* = SKIP diff --git a/Source/ThirdParty/ANGLE/src/tests/capture_replay_tests/capture_replay_expectations.txt b/Source/ThirdParty/ANGLE/src/tests/capture_replay_tests/capture_replay_expectations.txt index 3c40b59e9b39..d40dc6af1dc9 100644 --- a/Source/ThirdParty/ANGLE/src/tests/capture_replay_tests/capture_replay_expectations.txt +++ b/Source/ThirdParty/ANGLE/src/tests/capture_replay_tests/capture_replay_expectations.txt @@ -125,6 +125,8 @@ 7291 : BlitFramebufferTest.Blit3D/* = SKIP_FOR_CAPTURE 7291 : BlitFramebufferTest.Blit3DTo2DArray/* = SKIP_FOR_CAPTURE 7291 : BlitFramebufferTest.Blit2DArrayTo3D/* = SKIP_FOR_CAPTURE +7291 : BlitFramebufferTest.drawBlitAndDrawAgain/* = SKIP_FOR_CAPTURE +7291 : BlitFramebufferTest.scissorDrawBlitAndDrawAgain/* = SKIP_FOR_CAPTURE 7357 : FramebufferTest_ES3.FramebufferConditionalFeedbackLoop/* = SKIP_FOR_CAPTURE 7499 : Texture2DTest.TextureMaxSize/* = SKIP_FOR_CAPTURE @@ -199,3 +201,6 @@ # Fails if run after DifferentStencilMasksTest.DrawWithSameEffectiveMask 8079 : DiscardFramebufferEXTTest.ClearDepthThenDrawWithoutDepthTestThenDiscard/* = SKIP_FOR_CAPTURE + +# Sample coverage must not affect single sample render targets +8102 : SimpleOperationTest.DrawSingleSampleWithCoverage/* = SKIP_FOR_CAPTURE diff --git a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_egl_test_expectations.txt b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_egl_test_expectations.txt index 1683a8e532a6..a863e518437b 100644 --- a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_egl_test_expectations.txt +++ b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_egl_test_expectations.txt @@ -92,13 +92,16 @@ 5753 LINUX VULKAN : dEQP-EGL.functional.resize.surface_size.* = FAIL // Mac failures + +// New crash on MacBook Pro 2019 macOS 13.2.1, must come before the wildcard native_window.* FAIL below +8091 MAC METAL AMD : dEQP-EGL.functional.native_color_mapping.native_window.rgba8888_depth_no_stencil_render = SKIP + 2546 MAC : dEQP-EGL.functional.native_color_mapping.native_window.* = FAIL 2546 MAC : dEQP-EGL.functional.native_coord_mapping.native_window.* = FAIL 2546 MAC : dEQP-EGL.functional.negative_api.copy_buffers = FAIL 2546 MAC : dEQP-EGL.functional.negative_api.swap_interval = FAIL 2546 MAC OPENGL : dEQP-EGL.functional.query_surface.simple.pbuffer.rgba8888_depth_stencil = FAIL 2546 MAC : dEQP-EGL.functional.thread_cleanup.* = SKIP -1347817 MAC : dEQP-EGL.functional.image.api.create_image_gles2_android_native_* = SKIP // Android GLES-only failues 2567 ANDROID GLES : dEQP-EGL.functional.image.api.create_image_gles2_tex2d_red = FAIL diff --git a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles2_test_expectations.txt b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles2_test_expectations.txt index cc6475880ca5..5b687a29ac24 100644 --- a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles2_test_expectations.txt +++ b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles2_test_expectations.txt @@ -288,6 +288,10 @@ 6297 MAC METAL : dEQP-GLES2.functional.attribute_location.bind_aliasing.cond* = FAIL +// New failures on MacBook Pro 2019 macOS 13.2.1 +8091 MAC METAL AMD : dEQP-GLES2.functional.shaders.function.global_variable_aliasing_fragment = FAIL +8091 MAC METAL AMD : dEQP-GLES2.functional.shaders.function.global_variable_aliasing_vertex = FAIL + // Test bug - fails in ASAN. 6678 ASAN : dEQP-GLES2.functional.negative_api.texture.compressedtexsubimage2d* = SKIP diff --git a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles3_test_expectations.txt b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles3_test_expectations.txt index 5d1427522ed2..30d8e29db002 100644 --- a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles3_test_expectations.txt +++ b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp_gles3_test_expectations.txt @@ -25,9 +25,6 @@ 6214 : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uvec4_vertex = FAIL 6214 : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uvec4_vertex = FAIL -// New tests in VK-GL-CTS roll 2022-08-19, fail on all backends -7592 : dEQP-GLES3.functional.shaders.keywords.allowed_keywords.* = FAIL - // Failures related to using a depth/stencil enabled backbuffer on Windows / NVIDIA. 2428 WIN D3D11 NVIDIA : dEQP-GLES3.functional.shaders.invariance.highp.common_subexpression_1 = FAIL 2428 WIN D3D11 NVIDIA : dEQP-GLES3.functional.shaders.invariance.mediump.common_subexpression_1 = FAIL @@ -363,6 +360,18 @@ 6222 MAC OPENGL AMD : dEQP-GLES3.functional.texture.specification.teximage3d_pbo.rg8* = FAIL 6222 MAC OPENGL AMD : dEQP-GLES3.functional.texture.specification.teximage3d_pbo.r16* = FAIL +// New failures on MacBook Pro 2019 macOS 13.2.1 +8091 MAC OPENGL AMD : dEQP-GLES3.functional.fbo.msaa.renderbuffer_resize.ms_to_nonms = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.fbo.msaa.renderbuffer_resize.nonms_to_nonms = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.rgb5_a1_clears = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.rgb5_a1_triangles = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.rgba4_clears = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.rgba4_triangles = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.rgba8_clears = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.rgba8_triangles = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.srgb8_alpha8_clears = FAIL +8091 MAC OPENGL AMD : dEQP-GLES3.functional.pbo.renderbuffer.srgb8_alpha8_triangles = FAIL + // Mac Intel crashes 2137 MAC OPENGL INTEL : dEQP-GLES3.functional.shaders.discard.function_static_loop_never = SKIP 2137 MAC OPENGL INTEL : dEQP-GLES3.functional.shaders.discard.dynamic_loop_never = SKIP @@ -680,6 +689,12 @@ 5666 MAC METAL AMD : dEQP-GLES3.functional.texture.filtering.2d_array.formats.rgb9_e5_linear_mipmap_linear = FAIL 5666 MAC METAL AMD : dEQP-GLES3.functional.texture.filtering.2d_array.formats.rgb9_e5_nearest_mipmap_linear = FAIL +// New failures on MacBook Pro 2019 macOS 13.2.1 +8091 MAC METAL AMD : dEQP-GLES3.functional.shaders.builtin_functions.pack_unpack.unpacksnorm2x16_vertex = FAIL +8091 MAC METAL AMD : dEQP-GLES3.functional.shaders.builtin_functions.pack_unpack.unpackunorm2x16_vertex = FAIL +8091 MAC METAL AMD : dEQP-GLES3.functional.shaders.function.global_variable_aliasing_fragment = FAIL +8091 MAC METAL AMD : dEQP-GLES3.functional.shaders.function.global_variable_aliasing_vertex = FAIL + // Test failures introduced by Apple's changes (anglebug.com/5505) 6467 MAC METAL : dEQP-GLES3.functional.fbo.invalidate.sub.unbind_blit_msaa_color = FAIL 6467 MAC METAL : dEQP-GLES3.functional.fbo.invalidate.sub.unbind_blit_msaa_stencil = FAIL diff --git a/Source/ThirdParty/ANGLE/src/tests/egl_tests/EGLContextCompatibilityTest.cpp b/Source/ThirdParty/ANGLE/src/tests/egl_tests/EGLContextCompatibilityTest.cpp index c8d5d4531555..64a37c473c99 100644 --- a/Source/ThirdParty/ANGLE/src/tests/egl_tests/EGLContextCompatibilityTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/egl_tests/EGLContextCompatibilityTest.cpp @@ -71,10 +71,6 @@ bool ShouldSkipConfig(EGLDisplay display, EGLConfig config, bool windowSurfaceTe return windowSurfaceTest; } - // Linux failures: http://anglebug.com/4990 - if (IsLinux()) - return true; - return false; } @@ -83,12 +79,12 @@ std::vector GetConfigs(EGLDisplay display) int nConfigs = 0; if (eglGetConfigs(display, nullptr, 0, &nConfigs) != EGL_TRUE) { - std::cerr << "EGLContextCompatiblityTest: eglGetConfigs error\n"; + std::cerr << "EGLContextCompatibilityTest: eglGetConfigs error\n"; return {}; } if (nConfigs == 0) { - std::cerr << "EGLContextCompatiblityTest: no configs\n"; + std::cerr << "EGLContextCompatibilityTest: no configs\n"; return {}; } @@ -98,12 +94,12 @@ std::vector GetConfigs(EGLDisplay display) configs.resize(nConfigs); if (eglGetConfigs(display, configs.data(), nConfigs, &nReturnedConfigs) != EGL_TRUE) { - std::cerr << "EGLContextCompatiblityTest: eglGetConfigs error\n"; + std::cerr << "EGLContextCompatibilityTest: eglGetConfigs error\n"; return {}; } if (nConfigs != nReturnedConfigs) { - std::cerr << "EGLContextCompatiblityTest: eglGetConfigs returned wrong count\n"; + std::cerr << "EGLContextCompatibilityTest: eglGetConfigs returned wrong count\n"; return {}; } @@ -181,7 +177,7 @@ class EGLContextCompatibilityTest : public ANGLETestBase, public testing::Test EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, mRenderer, EGL_NONE}; mDisplay = eglGetPlatformDisplayEXT( - EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast(EGL_DEFAULT_DISPLAY), dispattrs); + EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast(EGL_DEFAULT_DISPLAY), dispattrs); ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY); ASSERT_TRUE(eglInitialize(mDisplay, nullptr, nullptr) == EGL_TRUE); @@ -475,6 +471,14 @@ class EGLContextCompatibilityTest_PbufferDifferentConfig : public EGLContextComp void RegisterContextCompatibilityTests() { + // Linux failures: http://anglebug.com/4990 + // Also wrong drivers loaded under xvfb due to egl* calls: https://anglebug.com/8083 + if (IsLinux()) + { + std::cerr << "EGLContextCompatibilityTest: skipped on Linux\n"; + return; + } + std::vector renderers = {{ EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, @@ -487,7 +491,7 @@ void RegisterContextCompatibilityTests() if (eglGetPlatformDisplayEXT == nullptr) { - std::cerr << "EGLContextCompatiblityTest: missing eglGetPlatformDisplayEXT\n"; + std::cerr << "EGLContextCompatibilityTest: missing eglGetPlatformDisplayEXT\n"; return; } @@ -502,13 +506,13 @@ void RegisterContextCompatibilityTests() EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast(EGL_DEFAULT_DISPLAY), dispattrs); if (display == EGL_NO_DISPLAY) { - std::cerr << "EGLContextCompatiblityTest: eglGetPlatformDisplayEXT error\n"; + std::cerr << "EGLContextCompatibilityTest: eglGetPlatformDisplayEXT error\n"; return; } if (eglInitialize(display, nullptr, nullptr) != EGL_TRUE) { - std::cerr << "EGLContextCompatiblityTest: eglInitialize error\n"; + std::cerr << "EGLContextCompatibilityTest: eglInitialize error\n"; return; } @@ -628,7 +632,7 @@ void RegisterContextCompatibilityTests() if (eglTerminate(display) == EGL_FALSE) { - std::cerr << "EGLContextCompatiblityTest: eglTerminate error\n"; + std::cerr << "EGLContextCompatibilityTest: eglTerminate error\n"; return; } } diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/BlitFramebufferANGLETest.cpp index 4245ed3a41b1..c18eb7a61409 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/BlitFramebufferANGLETest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/BlitFramebufferANGLETest.cpp @@ -1652,6 +1652,57 @@ class BlitFramebufferTest : public ANGLETest<> } } } + + void initFBOWithProgramAndDepth(GLFramebuffer *fbo, + GLRenderbuffer *colorRenderBuffer, + GLenum colorFormat, + GLRenderbuffer *depthRenderBuffer, + GLenum depthFormat, + GLsizei width, + GLsizei height, + GLuint program, + float depthValue) + { + if (fbo != nullptr) + { + // Create renderbuffer + glBindRenderbuffer(GL_RENDERBUFFER, *colorRenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height); + glBindRenderbuffer(GL_RENDERBUFFER, *depthRenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, width, height); + + // Create fbo + glBindFramebuffer(GL_FRAMEBUFFER, *fbo); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + *colorRenderBuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + *depthRenderBuffer); + } + else + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + // draw with program + glUseProgram(program); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepthf(1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + drawQuad(program, essl1_shaders::PositionAttrib(), depthValue); + } + + void drawWithDepthValue(std::array &quadVertices, float depth) + { + for (Vector3 &vertice : quadVertices) + { + vertice[2] = depth; + } + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(quadVertices[0]) * quadVertices.size(), + quadVertices.data()); + glDrawArrays(GL_TRIANGLES, 0, 6); + } }; class BlitFramebufferTestES31 : public BlitFramebufferTest @@ -2872,6 +2923,116 @@ TEST_P(BlitFramebufferTest, useAndDestroyProgramThenBlit) EXPECT_GL_NO_ERROR(); } +// This test is to ensure the draw after blit without any state change works properly +TEST_P(BlitFramebufferTest, drawBlitAndDrawAgain) +{ + constexpr const GLsizei kWidth = 256; + constexpr const GLsizei kHeight = 256; + + GLRenderbuffer srcColorRB, srcDepthRB; + GLFramebuffer srcFBO; + + ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red()); + ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green()); + ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue()); + + // Initialize source FBO with red color and depth==0.8f + initFBOWithProgramAndDepth(&srcFBO, &srcColorRB, GL_RGBA8, &srcDepthRB, GL_DEPTH24_STENCIL8_OES, + kWidth, kHeight, drawRed, 0.8f); + EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red); + + // Initialize destination FBO and initialize to green and depth==0.7 + initFBOWithProgramAndDepth(nullptr, nullptr, 0, nullptr, 0, kWidth, kHeight, drawGreen, 0.7f); + EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green); + + // Setup for draw-blit-draw use pattern + glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + std::array quadVertices = GetQuadVertices(); + constexpr size_t kBufferSize = sizeof(quadVertices[0]) * quadVertices.size(); + GLBuffer vertexBuffer; + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW); + glUseProgram(drawBlue); + const GLint positionLocation = glGetAttribLocation(drawBlue, essl1_shaders::PositionAttrib()); + ASSERT_NE(-1, positionLocation); + glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(positionLocation); + + // Draw with depth=0.75, should fail depth test + drawWithDepthValue(quadVertices, 0.75f); + // Now blit depth buffer from source FBO to the right half of destination FBO, so left half has + // depth 0.7f and right half has 0.8f + glBlitFramebuffer(kWidth / 2, 0, kWidth, kHeight, kWidth / 2, 0, kWidth, kHeight, + GL_DEPTH_BUFFER_BIT, GL_NEAREST); + // Continue draw without state change and depth==0.75f, now it should pass depth test on right + // half + glDrawArrays(GL_TRIANGLES, 0, 6); + + // Now verify dstFBO + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, 1, GLColor::blue); + EXPECT_GL_NO_ERROR(); +} + +// This test is to ensure the scissored draw after blit without any state change works properly +TEST_P(BlitFramebufferTest, scissorDrawBlitAndDrawAgain) +{ + constexpr const GLsizei kWidth = 256; + constexpr const GLsizei kHeight = 256; + + GLRenderbuffer srcColorRB, srcDepthRB; + GLFramebuffer srcFBO; + + ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red()); + ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green()); + ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue()); + + // Initialize source FBO with red color and depth==0.8f + initFBOWithProgramAndDepth(&srcFBO, &srcColorRB, GL_RGBA8, &srcDepthRB, GL_DEPTH24_STENCIL8_OES, + kWidth, kHeight, drawRed, 0.8f); + EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red); + + // Initialize destination FBO and initialize to green and depth==0.7 + initFBOWithProgramAndDepth(nullptr, nullptr, 0, nullptr, 0, kWidth, kHeight, drawGreen, 0.7f); + EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green); + + // Setup for draw-blit-draw use pattern + glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + std::array quadVertices = GetQuadVertices(); + constexpr size_t kBufferSize = sizeof(quadVertices[0]) * quadVertices.size(); + GLBuffer vertexBuffer; + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW); + glUseProgram(drawBlue); + const GLint positionLocation = glGetAttribLocation(drawBlue, essl1_shaders::PositionAttrib()); + ASSERT_NE(-1, positionLocation); + glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(positionLocation); + + // Scissored draw with depth=0.75, should fail depth test + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, kWidth, kHeight / 2); + drawWithDepthValue(quadVertices, 0.75f); + // Now blit depth buffer from source FBO to the right half of destination FBO, so left half has + // depth 0.7f and right half has 0.8f + glBlitFramebuffer(kWidth / 2, 0, kWidth, kHeight, kWidth / 2, 0, kWidth, kHeight, + GL_DEPTH_BUFFER_BIT, GL_NEAREST); + // Continue draw without state change and depth==0.75f, now it should pass depth test on right + // half + glDrawArrays(GL_TRIANGLES, 0, 6); + + // Now verify dstFBO + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, 1, GLColor::blue); + EXPECT_PIXEL_COLOR_EQ(1, kHeight - 1, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight - 1, GLColor::green); + EXPECT_GL_NO_ERROR(); +} + // Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. We do validation for // overflows also in non-WebGL mode to avoid triggering driver bugs. TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow) @@ -3687,6 +3848,7 @@ ANGLE_INSTANTIATE_TEST_ES3_AND(BlitFramebufferTest, ES3_VULKAN() .disable(Feature::SupportsExtendedDynamicState2) .disable(Feature::SupportsLogicOpDynamicState), + ES3_VULKAN().enable(Feature::DisableFlippingBlitWithCommand), ES3_METAL().disable(Feature::HasShaderStencilOutput)); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTestES31); diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClipControlTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClipControlTest.cpp index 19f13a63c198..a62d83b7caeb 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClipControlTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClipControlTest.cpp @@ -175,4 +175,426 @@ TEST_P(ClipControlTest, OriginScissorClear) test("User framebuffer", getClientMajorVersion() > 2); } +// Test that changing clip origin state does not affect location of scissor area +TEST_P(ClipControlTest, OriginScissorDraw) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_clip_control")); + + constexpr char kVS[] = R"( +attribute vec2 a_position; +void main() +{ + // Square at (0.25, 0.25) -> (0.75, 0.75) + gl_Position = vec4(a_position * 0.25 + 0.5, 0.0, 1.0); +})"; + + ANGLE_GL_PROGRAM(program, kVS, essl1_shaders::fs::Blue()); + glUseProgram(program); + ASSERT_GL_NO_ERROR(); + + auto test = [&](std::string name) { + glClipControlEXT(GL_LOWER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + + glDisable(GL_SCISSOR_TEST); + glClear(GL_COLOR_BUFFER_BIT); + + // Draw only to the lower half + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, w, h / 2); + + // Draw blue quad in the upper-right part of the framebuffer; scissor test must fail + drawQuad(program, "a_position", 0); + ASSERT_GL_NO_ERROR(); + + // Switch the clip origin and draw again; scissor test must pass + glClipControlEXT(GL_UPPER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + drawQuad(program, "a_position", 0); + ASSERT_GL_NO_ERROR(); + + // Reads are unaffected by clip origin + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.25 * h, GLColor::blue) << name; + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.75 * h, GLColor::transparentBlack) << name; + }; + + test("Default framebuffer"); + + GLFramebuffer fb; + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + test("User framebuffer"); +} + +// Test that changing clip origin state does not affect copyTexImage +TEST_P(ClipControlTest, OriginCopyTexImage) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_clip_control")); + + auto test = [&](std::string name) { + glClipControlEXT(GL_LOWER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + + // Clear to red + glDisable(GL_SCISSOR_TEST); + glClearColor(1.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + // Clear lower half-space to green + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, w, h / 2); + glClearColor(0.0, 1.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + // Switch clip origin state, it must have no effect on the next commands + glClipControlEXT(GL_UPPER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, w / 4, h / 4, 0); + ASSERT_GL_NO_ERROR(); + + GLFramebuffer readFb; + glBindFramebuffer(GL_FRAMEBUFFER, readFb); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + // Copied texture must contain values from the lower half-space + EXPECT_PIXEL_COLOR_EQ(w / 8, h / 8, GLColor::green) << name; + }; + + test("Default framebuffer"); + + GLFramebuffer fb; + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + test("User framebuffer"); +} + +// Test that changing clip origin state does not affect copyTexImage +// with Luma format that may use draw calls internally +TEST_P(ClipControlTest, OriginCopyTexImageLuma) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_clip_control")); + + glClipControlEXT(GL_LOWER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + + // Clear to zero + glClear(GL_COLOR_BUFFER_BIT); + + // Clear lower half-space to one + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, w, h / 2); + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); + + // Switch clip origin state, it must have no effect on the next commands + glClipControlEXT(GL_UPPER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 0, 0, w, h, 0); + ASSERT_GL_NO_ERROR(); + + glClearColor(1.0, 0.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta); + + // Draw the luma texture + glClipControlEXT(GL_LOWER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); + drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.0f); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_EQ(w / 2, h * 1 / 4, GLColor::white); + EXPECT_PIXEL_COLOR_EQ(w / 2, h * 3 / 4, GLColor::black); +} + +// Test that clip origin does not affect gl_FragCoord +TEST_P(ClipControlTest, OriginFragCoord) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_clip_control")); + + const char kFS[] = R"(precision mediump float; +void main() +{ + gl_FragColor = vec4(sign(gl_FragCoord.xy / 64.0 - 0.5), 0.0, 1.0); +})"; + + ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS); + + glClearColor(1.0, 0.0, 1.0, 1.0); + + for (GLenum origin : {GL_LOWER_LEFT_EXT, GL_UPPER_LEFT_EXT}) + { + glClipControlEXT(origin, GL_NEGATIVE_ONE_TO_ONE_EXT); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); + EXPECT_PIXEL_COLOR_EQ(w - 1, 0, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(0, h - 1, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(w - 1, h - 1, GLColor::yellow); + + GLFramebuffer fb; + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); + EXPECT_PIXEL_COLOR_EQ(w - 1, 0, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(0, h - 1, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(w - 1, h - 1, GLColor::yellow); + } +} + +// Test that clip origin does not affect gl_PointCoord +TEST_P(ClipControlTest, OriginPointCoord) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_clip_control")); + + float pointSizeRange[2] = {}; + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); + ANGLE_SKIP_TEST_IF(pointSizeRange[1] < 32); + + const char kVS[] = R"(precision mediump float; +void main() +{ + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + gl_PointSize = 32.0; +})"; + + const char kFS[] = R"(precision mediump float; +void main() +{ + gl_FragColor = vec4(sign(gl_PointCoord.xy - 0.5), 0.0, 1.0); +})"; + + ANGLE_GL_PROGRAM(program, kVS, kFS); + glUseProgram(program); + ASSERT_GL_NO_ERROR(); + + glClearColor(1.0, 0.0, 1.0, 1.0); + + for (GLenum origin : {GL_LOWER_LEFT_EXT, GL_UPPER_LEFT_EXT}) + { + glClipControlEXT(origin, GL_NEGATIVE_ONE_TO_ONE_EXT); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_POINTS, 0, 1); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_EQ(w / 2 - 15, h / 2 + 15, GLColor::black); + EXPECT_PIXEL_COLOR_EQ(w / 2 + 15, h / 2 + 15, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(w / 2 - 15, h / 2 - 15, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(w / 2 + 15, h / 2 - 15, GLColor::yellow); + + GLFramebuffer fb; + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_POINTS, 0, 1); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_EQ(w / 2 - 15, h / 2 + 15, GLColor::black); + EXPECT_PIXEL_COLOR_EQ(w / 2 + 15, h / 2 + 15, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(w / 2 - 15, h / 2 - 15, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(w / 2 + 15, h / 2 - 15, GLColor::yellow); + } +} + +// Test that clip origin does not affect gl_FrontFacing +TEST_P(ClipControlTest, OriginFrontFacing) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_clip_control")); + + const char kFS[] = R"(precision mediump float; +void main() +{ + gl_FragColor = vec4(gl_FrontFacing ? vec2(1.0, 0.0) : vec2(0.0, 1.0), 0.0, 1.0); +})"; + + ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS); + + for (GLenum origin : {GL_LOWER_LEFT_EXT, GL_UPPER_LEFT_EXT}) + { + glClipControlEXT(origin, GL_NEGATIVE_ONE_TO_ONE_EXT); + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + glFrontFace(GL_CCW); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + + glFrontFace(GL_CW); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + GLFramebuffer fb; + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + glFrontFace(GL_CCW); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + + glFrontFace(GL_CW); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + } +} + +class ClipControlTestES3 : public ClipControlTest +{}; + +// Test that clip origin state does not affect framebuffer blits +TEST_P(ClipControlTestES3, OriginBlit) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_clip_control")); + + constexpr char kFS[] = R"( +precision mediump float; +varying vec4 v_position; +void main() +{ + gl_FragColor = vec4(sign(v_position.xy), 0.0, 1.0); +})"; + + ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), kFS); + glUseProgram(program); + ASSERT_GL_NO_ERROR(); + + // Blit default to custom + { + GLFramebuffer fb; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, w, h); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glClipControlEXT(GL_LOWER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + drawQuad(program, "a_position", 0); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb); + glClipControlEXT(GL_UPPER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fb); + EXPECT_PIXEL_COLOR_EQ(0.25 * w, 0.25 * h, GLColor::black); + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.25 * h, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(0.25 * w, 0.75 * h, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.75 * h, GLColor::yellow); + } + + // Blit custom to default + { + GLFramebuffer fb; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, w, h); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb); + glClipControlEXT(GL_LOWER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + drawQuad(program, "a_position", 0); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fb); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glClipControlEXT(GL_UPPER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + EXPECT_PIXEL_COLOR_EQ(0.25 * w, 0.25 * h, GLColor::black); + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.25 * h, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(0.25 * w, 0.75 * h, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.75 * h, GLColor::yellow); + } + + // Blit custom to custom + { + GLFramebuffer fb1; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb1); + + GLRenderbuffer rb1; + glBindRenderbuffer(GL_RENDERBUFFER, rb1); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, w, h); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb1); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER); + + GLFramebuffer fb2; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb2); + + GLRenderbuffer rb2; + glBindRenderbuffer(GL_RENDERBUFFER, rb2); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, w, h); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb2); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb1); + glClipControlEXT(GL_LOWER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + drawQuad(program, "a_position", 0); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fb1); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb2); + glClipControlEXT(GL_UPPER_LEFT_EXT, GL_NEGATIVE_ONE_TO_ONE_EXT); + glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fb2); + EXPECT_PIXEL_COLOR_EQ(0.25 * w, 0.25 * h, GLColor::black); + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.25 * h, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(0.25 * w, 0.75 * h, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(0.75 * w, 0.75 * h, GLColor::yellow); + } +} + ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ClipControlTest); +ANGLE_INSTANTIATE_TEST_ES3(ClipControlTestES3); diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/ComputeShaderTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/ComputeShaderTest.cpp index d451c3182889..d93d063ea8a6 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/ComputeShaderTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/ComputeShaderTest.cpp @@ -5209,6 +5209,132 @@ void main() } } +// Replicate the dEQP test dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite +TEST_P(ComputeShaderTest, SSBOAliasOverWrite) +{ + constexpr char kCSSource[] = R"(#version 310 es + layout (local_size_x=16, local_size_y=8) in; + layout(binding=0, std430) buffer Output { + highp int values[]; + } sb_result; + layout(binding=1, std430) coherent buffer Storage0 + { + highp int values[]; + } sb_store0; + layout(binding=2, std430) coherent buffer Storage1 + { + highp int values[]; + } sb_store1; + + highp int getIndex(in highp uvec2 localID, in highp int element) + { + highp uint groupNdx = gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x; + return int((localID.y * gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupSize.x) + (groupNdx * gl_WorkGroupSize.x) + localID.x) * 8 + element; + } + + void main (void) + { + int resultNdx = int(gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x + gl_GlobalInvocationID.x); + int groupNdx = int(gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x); + bool allOk = true; + + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 0)] = 456; + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 1)] = 456; + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 2)] = 456; + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 3)] = 456; + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 4)] = 456; + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 5)] = 456; + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 6)] = 456; + sb_store0.values[getIndex(gl_LocalInvocationID.xy, 7)] = 456; + + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 0)] = groupNdx; + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 1)] = groupNdx; + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 2)] = groupNdx; + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 3)] = groupNdx; + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 4)] = groupNdx; + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 5)] = groupNdx; + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 6)] = groupNdx; + sb_store1.values[getIndex(gl_LocalInvocationID.xy, 7)] = groupNdx; + + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 0)] == groupNdx); + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 1)] == groupNdx); + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 2)] == groupNdx); + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 3)] == groupNdx); + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 4)] == groupNdx); + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 5)] == groupNdx); + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 6)] == groupNdx); + allOk = allOk && (sb_store0.values[getIndex(gl_LocalInvocationID.xy, 7)] == groupNdx); + + sb_result.values[resultNdx] = allOk ? (1) : (2); + + })"; + + const int totalWorkWidth = 256; + const int totalWorkHeight = 256; + const int elementsPerInvocation = 8; + + // define compute shader input storage buffer + const int inputSSBOBufferSizeInBytes = + totalWorkWidth * totalWorkHeight * elementsPerInvocation * sizeof(uint32_t); + const int inputSSBOBufferElementsCount = + totalWorkWidth * totalWorkHeight * elementsPerInvocation; + std::vector zeros(inputSSBOBufferElementsCount, 0); + GLBuffer ssbo; + glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); + glBufferData(GL_SHADER_STORAGE_BUFFER, inputSSBOBufferSizeInBytes, zeros.data(), + GL_STATIC_DRAW); + ASSERT_GL_NO_ERROR(); + + // define compute shader output buffer + const int outputBufferSizeInBytes = totalWorkWidth * totalWorkHeight * sizeof(int32_t); + const int outputBufferElementsCount = totalWorkWidth * totalWorkHeight; + std::vector minusOnes(outputBufferElementsCount, -1); + GLBuffer resultBuffer; + glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, outputBufferSizeInBytes, &minusOnes[0], GL_STATIC_DRAW); + ASSERT_GL_NO_ERROR(); + + // dispatch compute shader + const int localWidth = 16; + const int localHeight = 8; + ASSERT(totalWorkWidth % localWidth == 0); + ASSERT(totalWorkHeight % localHeight == 0); + const int numGroupDimX = totalWorkWidth / localWidth; + const int numGroupDimY = totalWorkHeight / localHeight; + + ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource); + glUseProgram(csProgram); + ASSERT_GL_NO_ERROR(); + + // Bind storage buffer to compute shader binding locations + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, resultBuffer); + + glDispatchCompute(numGroupDimX, numGroupDimY, 1); + ASSERT_GL_NO_ERROR(); + + // verify the result + glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultBuffer); + glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); + void *mappedResults = + glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, outputBufferSizeInBytes, GL_MAP_READ_BIT); + std::vector results(outputBufferElementsCount); + memcpy(results.data(), mappedResults, outputBufferSizeInBytes); + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + ASSERT_GL_NO_ERROR(); + + bool error = false; + for (int index = 0; index < static_cast(results.size()); ++index) + { + if (results[index] != 1) + { + error = true; + } + } + EXPECT_EQ(false, error); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ComputeShaderTest); ANGLE_INSTANTIATE_TEST_ES31(ComputeShaderTest); diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/DebugTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/DebugTest.cpp index 72c827943f4d..af826e32a963 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/DebugTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/DebugTest.cpp @@ -189,6 +189,11 @@ TEST_P(DebugTest, ObjectLabelsEXT) class DebugTestES3 : public DebugTest {}; +class DebugTestES32 : public DebugTestES3 +{ + void testSetUp() override { ; } +}; + struct Message { GLenum source; @@ -642,6 +647,24 @@ TEST_P(DebugTestES3, Rendering) ASSERT_GL_NO_ERROR(); } +// Simple test for gl[Push, Pop]DebugGroup using ES32 core APIs +TEST_P(DebugTestES32, DebugGroup) +{ + const std::string testDrawGroup = "Test Draw Group"; + + // Pop without a push should generate GL_STACK_UNDERFLOW error + glPopDebugGroup(); + EXPECT_GL_ERROR(GL_STACK_UNDERFLOW); + + // Push a test debug group and expect no error + glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 0, -1, testDrawGroup.c_str()); + ASSERT_GL_NO_ERROR(); + + // Pop the test debug group and expect no error + glPopDebugGroup(); + ASSERT_GL_NO_ERROR(); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DebugTestES3); ANGLE_INSTANTIATE_TEST_ES3(DebugTestES3); @@ -650,4 +673,7 @@ ANGLE_INSTANTIATE_TEST(DebugTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ANGLE_ALL_TEST_PLATFORMS_ES3, ANGLE_ALL_TEST_PLATFORMS_ES31); + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DebugTestES32); +ANGLE_INSTANTIATE_TEST_ES32(DebugTestES32); } // namespace angle diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/DepthWriteTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/DepthWriteTest.cpp new file mode 100644 index 000000000000..b8c559198420 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/DepthWriteTest.cpp @@ -0,0 +1,409 @@ +// +// Copyright 2023 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. +// +// The tests assert OpenGL behavior for all combinations of the following states +// - Depth Range +// - Full (0, 1) +// - Reduced +// - Depth Clamp +// - Enabled (if supported) +// - Disabled +// - Vertex Depth +// - Inside clip volume +// - Less than -1 +// - Greater than +1 +// - gl_FragDepth +// - Unused +// - Passthrough (gl_FragCoord.z) +// - Within the depth range +// - Between 0 and near clipping plane +// - Between 1 and far clipping plane +// - Negative +// - Greater than 1 +// - Depth buffer format +// - DEPTH_COMPONENT16 +// - DEPTH_COMPONENT32F (ES 3.x only) + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +using namespace angle; + +namespace +{ + +enum class DepthRange +{ + Full, + Reduced, +}; + +enum class VertexDepth +{ + InsideClipVolume, + LessThanMinusOne, + GreaterThanOne, +}; + +enum class FragmentDepth +{ + Unused, + Passthrough, + WithinDepthRange, + BetweenZeroAndNearPlane, + BetweenFarPlaneAndOne, + Negative, + GreaterThanOne, +}; + +// Variations corresponding to enums above. +using DepthWriteVariationsTestParams = + std::tuple; + +std::ostream &operator<<(std::ostream &out, DepthRange depthRange) +{ + switch (depthRange) + { + case DepthRange::Full: + out << "Full"; + break; + case DepthRange::Reduced: + out << "Reduced"; + break; + } + + return out; +} + +std::ostream &operator<<(std::ostream &out, VertexDepth vertexDepth) +{ + switch (vertexDepth) + { + case VertexDepth::InsideClipVolume: + out << "InsideClipVolume"; + break; + case VertexDepth::LessThanMinusOne: + out << "LessThanMinusOne"; + break; + case VertexDepth::GreaterThanOne: + out << "GreaterThanOne"; + break; + } + + return out; +} + +std::ostream &operator<<(std::ostream &out, FragmentDepth fragmentDepth) +{ + switch (fragmentDepth) + { + case FragmentDepth::Unused: + out << "Unused"; + break; + case FragmentDepth::Passthrough: + out << "Passthrough"; + break; + case FragmentDepth::WithinDepthRange: + out << "WithinDepthRange"; + break; + case FragmentDepth::BetweenZeroAndNearPlane: + out << "BetweenZeroAndNearPlane"; + break; + case FragmentDepth::BetweenFarPlaneAndOne: + out << "BetweenFarPlaneAndOne"; + break; + case FragmentDepth::Negative: + out << "Negative"; + break; + case FragmentDepth::GreaterThanOne: + out << "GreaterThanOne"; + break; + } + + return out; +} + +std::string BufferFormatToString(GLenum format) +{ + switch (format) + { + case GL_DEPTH_COMPONENT16: + return "Depth16Unorm"; + case GL_DEPTH_COMPONENT32F: + return "Depth32Float"; + default: + return nullptr; + } +} + +void ParseDepthWriteVariationsTestParams(const DepthWriteVariationsTestParams ¶ms, + DepthRange *depthRangeOut, + bool *depthClampEnabledOut, + VertexDepth *vertexDepthOut, + FragmentDepth *fragmentDepthOut, + GLenum *depthBufferFormatOut) +{ + *depthRangeOut = std::get<1>(params); + *depthClampEnabledOut = std::get<2>(params); + *vertexDepthOut = std::get<3>(params); + *fragmentDepthOut = std::get<4>(params); + *depthBufferFormatOut = std::get<5>(params); +} + +std::string DepthWriteVariationsTestPrint( + const ::testing::TestParamInfo ¶msInfo) +{ + const DepthWriteVariationsTestParams ¶ms = paramsInfo.param; + std::ostringstream out; + + out << std::get<0>(params); + + DepthRange depthRange; + bool depthClampEnabled; + VertexDepth vertexDepth; + FragmentDepth fragmentDepth; + GLenum depthBufferFormat; + ParseDepthWriteVariationsTestParams(params, &depthRange, &depthClampEnabled, &vertexDepth, + &fragmentDepth, &depthBufferFormat); + + out << "__" + << "DepthRange" << depthRange << "_" << (depthClampEnabled ? "Clamped" : "Clipped") << "_" + << "VertexDepth" << vertexDepth << "_" + << "FragmentDepth" << fragmentDepth << "_" << BufferFormatToString(depthBufferFormat); + return out.str(); +} + +class DepthWriteTest : public ANGLETest +{}; + +// Test correctness of depth writes +TEST_P(DepthWriteTest, Test) +{ + if (getClientMajorVersion() < 3) + { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture")); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float")); + } + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float") && + !IsGLExtensionEnabled("GL_EXT_color_buffer_float")); + + DepthRange depthRange; + bool depthClampEnabled; + VertexDepth vertexDepth; + FragmentDepth fragmentDepth; + GLenum depthBufferFormat; + ParseDepthWriteVariationsTestParams(GetParam(), &depthRange, &depthClampEnabled, &vertexDepth, + &fragmentDepth, &depthBufferFormat); + + if (getClientMajorVersion() < 3) + { + ANGLE_SKIP_TEST_IF(fragmentDepth != FragmentDepth::Unused && + !IsGLExtensionEnabled("GL_EXT_frag_depth")); + ANGLE_SKIP_TEST_IF(depthBufferFormat == GL_DEPTH_COMPONENT32F); + } + ANGLE_SKIP_TEST_IF(depthClampEnabled && !IsGLExtensionEnabled("GL_EXT_depth_clamp")); + + const float near = depthRange == DepthRange::Full ? 0.0 : 0.25; + const float far = depthRange == DepthRange::Full ? 1.0 : 0.75; + glDepthRangef(near, far); + + if (depthClampEnabled) + { + glEnable(GL_DEPTH_CLAMP_EXT); + } + + float vertexDepthValue = 0.0; + switch (vertexDepth) + { + case VertexDepth::InsideClipVolume: + vertexDepthValue = 0.25; // maps to 0.625 + break; + case VertexDepth::LessThanMinusOne: + vertexDepthValue = -1.5; + break; + case VertexDepth::GreaterThanOne: + vertexDepthValue = 1.5; + break; + } + + float fragmentDepthValue = 0.0; + switch (fragmentDepth) + { + case FragmentDepth::Unused: + case FragmentDepth::Passthrough: + break; + case FragmentDepth::WithinDepthRange: + fragmentDepthValue = 0.375; + break; + case FragmentDepth::BetweenZeroAndNearPlane: + fragmentDepthValue = depthRange == DepthRange::Reduced ? 0.125 : 0.0; + break; + case FragmentDepth::BetweenFarPlaneAndOne: + fragmentDepthValue = depthRange == DepthRange::Reduced ? 0.875 : 1.0; + break; + case FragmentDepth::Negative: + fragmentDepthValue = -0.25; + break; + case FragmentDepth::GreaterThanOne: + fragmentDepthValue = 1.25; + break; + } + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + + const int w = getWindowWidth(); + const int h = getWindowHeight(); + + const bool es2 = getClientMajorVersion() < 3; + const bool fragCoord = fragmentDepth == FragmentDepth::Passthrough; + std::stringstream fragmentSource; + fragmentSource << (es2 ? "#extension GL_EXT_frag_depth : require\n" : "#version 300 es\n") + << (es2 ? "" : "out mediump vec4 fragColor;\n") + << (fragCoord ? "" : "uniform mediump float u_depth;\n") << "void main()\n" + << "{\n" + << (es2 ? " gl_FragColor" : " fragColor") + << " = vec4(1.0, 0.0, 0.0, 1.0);\n" + << " gl_FragDepth" << (es2 ? "EXT" : "") + << (fragCoord ? " = gl_FragCoord.z;\n" : " = u_depth;\n") << "}"; + + ANGLE_GL_PROGRAM(program, es2 ? essl1_shaders::vs::Simple() : essl3_shaders::vs::Simple(), + fragmentDepth == FragmentDepth::Unused + ? (es2 ? essl1_shaders::fs::Red() : essl3_shaders::fs::Red()) + : fragmentSource.str().c_str()); + glUseProgram(program); + if (fragmentDepth != FragmentDepth::Unused && fragmentDepth != FragmentDepth::Passthrough) + { + glUniform1f(glGetUniformLocation(program, "u_depth"), fragmentDepthValue); + } + ASSERT_GL_NO_ERROR(); + + GLFramebuffer fb; + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); + + GLTexture texDepth; + glBindTexture(GL_TEXTURE_2D, texDepth); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D( + GL_TEXTURE_2D, 0, + depthBufferFormat == GL_DEPTH_COMPONENT32F ? GL_DEPTH_COMPONENT32F : GL_DEPTH_COMPONENT, w, + h, 0, GL_DEPTH_COMPONENT, + depthBufferFormat == GL_DEPTH_COMPONENT32F ? GL_FLOAT : GL_UNSIGNED_SHORT, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texDepth, 0); + + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + + glClearDepthf(0.33333333); + glClear(GL_DEPTH_BUFFER_BIT); + + drawQuad(program, essl1_shaders::PositionAttrib(), vertexDepthValue); + ASSERT_GL_NO_ERROR(); + + auto getExpectedValue = [&]() { + auto clamp = [](float x, float min, float max) { + return x < min ? min : (x > max ? max : x); + }; + + if (depthClampEnabled) + { + if (fragmentDepth != FragmentDepth::Unused && + fragmentDepth != FragmentDepth::Passthrough) + { + // Fragment value clamped to the depth range + return clamp(fragmentDepthValue, near, far); + } + else + { + // Vertex value transformed to window coordinates and clamped to the depth range + return clamp(0.5f * ((far - near) * vertexDepthValue + (far + near)), near, far); + } + } + else if (vertexDepthValue >= -1.0f && vertexDepthValue <= 1.0f) + { + if (fragmentDepth != FragmentDepth::Unused && + fragmentDepth != FragmentDepth::Passthrough) + { + // Fragment value clamped to [0, 1] + return clamp(fragmentDepthValue, 0.0f, 1.0f); + } + else + { + // Vertex value transformed to window coordinates + return 0.5f * ((far - near) * vertexDepthValue + (far + near)); + } + } + return 0.33333333f; + }; + + // Second pass to read written depth value + ANGLE_GL_PROGRAM(readProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); + glUseProgram(readProgram); + glUniform1i(glGetUniformLocation(readProgram, essl1_shaders::Texture2DUniform()), 0); + ASSERT_GL_NO_ERROR(); + + GLFramebuffer readFb; + glBindFramebuffer(GL_FRAMEBUFFER, readFb); + + GLRenderbuffer readRb; + glBindRenderbuffer(GL_RENDERBUFFER, readRb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA16F, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, readRb); + + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(readProgram, essl1_shaders::PositionAttrib(), 0.0f); + + float writtenValue[4] = {std::numeric_limits::quiet_NaN()}; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, writtenValue); + ASSERT_GL_NO_ERROR(); + + EXPECT_NEAR(getExpectedValue(), writtenValue[0], 0.001); +} + +constexpr DepthRange kDepthRanges[] = { + DepthRange::Full, + DepthRange::Reduced, +}; +constexpr VertexDepth kVertexDepths[] = { + VertexDepth::InsideClipVolume, + VertexDepth::LessThanMinusOne, + VertexDepth::GreaterThanOne, +}; +constexpr FragmentDepth kFragmentDepths[] = { + FragmentDepth::Unused, + FragmentDepth::Passthrough, + FragmentDepth::WithinDepthRange, + FragmentDepth::BetweenZeroAndNearPlane, + FragmentDepth::BetweenFarPlaneAndOne, + FragmentDepth::Negative, + FragmentDepth::GreaterThanOne, +}; +constexpr GLenum kDepthBufferFormats[] = { + GL_DEPTH_COMPONENT16, + GL_DEPTH_COMPONENT32F, +}; + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthWriteTest); +ANGLE_INSTANTIATE_TEST_COMBINE_5(DepthWriteTest, + DepthWriteVariationsTestPrint, + testing::ValuesIn(kDepthRanges), + testing::Bool(), + testing::ValuesIn(kVertexDepths), + testing::ValuesIn(kFragmentDepths), + testing::ValuesIn(kDepthBufferFormats), + ANGLE_ALL_TEST_PLATFORMS_ES2, + ANGLE_ALL_TEST_PLATFORMS_ES3); + +} // anonymous namespace diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/FormatPrintTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/FormatPrintTest.cpp index acae1e7296f0..f993073ed414 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/FormatPrintTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/FormatPrintTest.cpp @@ -113,6 +113,3 @@ ANGLE_INSTANTIATE_TEST(FormatPrintTest, ES2_VULKAN(), ES3_VULKAN()); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FormatPrintTest); } // anonymous namespace - -// Included here to fix a compile error due to white box tests using angle_end2end_tests_main. -void RegisterContextCompatibilityTests() {} diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/FragDepthTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/FragDepthTest.cpp index 0a6d6933381c..9ef716126644 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/FragDepthTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/FragDepthTest.cpp @@ -164,5 +164,128 @@ TEST_P(FragDepthTest, SwitchToNoDepthFramebuffer) EXPECT_GL_NO_ERROR(); } +class FragDepthRedeclarationTest : public ANGLETest<> +{}; + +// Test gl_FragDepth redeclared as vertex output +TEST_P(FragDepthRedeclarationTest, VSOutput) +{ + constexpr char kVS[] = R"(#version 300 es +#extension GL_EXT_conservative_depth: enable +out highp float gl_FragDepth; +void main() { + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + gl_FragDepth = 1.0; +})"; + + GLProgram prg; + prg.makeRaster(kVS, essl3_shaders::fs::Red()); + EXPECT_FALSE(prg.valid()); +} + +// Test gl_FragDepth redeclared as fragment input +TEST_P(FragDepthRedeclarationTest, FSInput) +{ + constexpr char kFS[] = R"(#version 300 es +#extension GL_EXT_conservative_depth: enable +out highp vec4 color; +in highp float gl_FragDepth; +void main() { + color = vec4(gl_FragDepth, 0.0, 0.0, 1.0); +})"; + + GLProgram prg; + prg.makeRaster(essl3_shaders::vs::Simple(), kFS); + EXPECT_FALSE(prg.valid()); +} + +// Test gl_FragDepth redeclaration with no layout qualifier +TEST_P(FragDepthRedeclarationTest, NoLayout) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth")); + + constexpr char kFS[] = R"(#version 300 es +#extension GL_EXT_conservative_depth: require +out highp vec4 color; +out highp float gl_FragDepth; +void main() { + color = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragDepth = 1.0; +})"; + + ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS); +} + +// Test gl_FragDepth redeclaration with depth_any layout qualifier +TEST_P(FragDepthRedeclarationTest, Any) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth")); + + constexpr char kFS[] = R"(#version 300 es +#extension GL_EXT_conservative_depth: require +out highp vec4 color; +layout (depth_any) out highp float gl_FragDepth; +void main() { + color = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragDepth = 1.0; +})"; + + ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS); +} + +// Test gl_FragDepth redeclaration with depth_greater layout qualifier +TEST_P(FragDepthRedeclarationTest, Greater) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth")); + + constexpr char kFS[] = R"(#version 300 es +#extension GL_EXT_conservative_depth: require +out highp vec4 color; +layout (depth_greater) out highp float gl_FragDepth; +void main() { + color = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragDepth = 1.0; +})"; + + ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS); +} + +// Test gl_FragDepth redeclaration with depth_less layout qualifier +TEST_P(FragDepthRedeclarationTest, Less) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth")); + + constexpr char kFS[] = R"(#version 300 es +#extension GL_EXT_conservative_depth: require +out highp vec4 color; +layout (depth_less) out highp float gl_FragDepth; +void main() { + color = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragDepth = 1.0; +})"; + + ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS); +} + +// Test gl_FragDepth redeclaration with depth_unchanged layout qualifier +TEST_P(FragDepthRedeclarationTest, Unchanged) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth")); + + constexpr char kFS[] = R"(#version 300 es +#extension GL_EXT_conservative_depth: require +out highp vec4 color; +layout (depth_unchanged) out highp float gl_FragDepth; +void main() { + color = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragDepth = 1.0; +})"; + + ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FragDepthTest); ANGLE_INSTANTIATE_TEST_ES3(FragDepthTest); + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FragDepthRedeclarationTest); +ANGLE_INSTANTIATE_TEST_ES3(FragDepthRedeclarationTest); diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/GLSLTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/GLSLTest.cpp index 017dcf9404b9..f639bbd415b6 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/GLSLTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/GLSLTest.cpp @@ -6485,6 +6485,50 @@ TEST_P(WebGLGLSLTest, UninitializedNamelessStructInGlobalScope) EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); } +// Test that uninitialized output arguments are initialized to 0. +TEST_P(WebGL2GLSLTest, InitOutputParams) +{ + constexpr char kFS[] = R"(#version 300 es +precision mediump float; + +struct S { float a; }; + +out vec4 color; + +float f(out vec2 o1, out S o2[2], out float o3[3]) +{ + float uninitialized_local; + + // leave o1 uninitialized + // leave o2 partially uninitialized + o2[0].a = 1.0; + + // leave o3 partially uninitialized + o3[1] = 0.5; + + return uninitialized_local; +} + +void main() +{ + vec2 v1 = vec2(123., 234.); + S v2[2] = S[2](S(-1111.), S(55.)); + float v3[3] = float[3](20., 30., 40.); + float v4 = f(v1, v2, v3); + + // Everything should be 0 now except for v2[0].a and v3[1] which should be 1.0 and 0.5 + // respectively. + color = vec4(v1.x + v2[0].a + v3[0], // 1.0 + v1.y + v2[1].a + v3[1], // 0.5 + v3[2] + v4, // 0 + 1.0); +})"; + + ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS); + drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true); + EXPECT_PIXEL_NEAR(0, 0, 255, 127, 0, 255, 1); +} + // Tests nameless struct uniforms. TEST_P(GLSLTest, EmbeddedStructUniform) { @@ -6976,6 +7020,102 @@ TEST_P(GLSLTest_ES31, VaryingTessellationSampleInAndOut) ASSERT_GL_NO_ERROR(); } +// Test that `smooth sample` and `flat sample` pass the validation. +TEST_P(GLSLTest_ES3, AliasedSampleQualifiers) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_shader_multisample_interpolation")); + + constexpr char kVS[] = + R"(#version 300 es + #extension GL_OES_shader_multisample_interpolation : require + + smooth sample out mediump float f; + flat sample out mediump int i; + void main() + { + f = 1.0; + i = 1; + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + })"; + + constexpr char kFS[] = + R"(#version 300 es + #extension GL_OES_shader_multisample_interpolation : require + + smooth sample in mediump float f; + flat sample in mediump int i; + out mediump vec4 color; + void main() + { + color = vec4(f, float(i), 0, 1); + })"; + + ANGLE_GL_PROGRAM(program, kVS, kFS); +} + +// Test that `noperspective centroid` passes the validation and compiles. +TEST_P(GLSLTest_ES3, NoPerspectiveCentroid) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_shader_noperspective_interpolation")); + + constexpr char kVS[] = + R"(#version 300 es + #extension GL_NV_shader_noperspective_interpolation : require + + noperspective centroid out mediump float f; + void main() + { + f = 1.0; + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + })"; + + constexpr char kFS[] = + R"(#version 300 es + #extension GL_NV_shader_noperspective_interpolation : require + + noperspective centroid in mediump float f; + out mediump vec4 color; + void main() + { + color = vec4(f, 0.0, 0.0, 1.0); + })"; + + ANGLE_GL_PROGRAM(program, kVS, kFS); +} + +// Test that `noperspective sample` passes the validation and compiles. +TEST_P(GLSLTest_ES3, NoPerspectiveSample) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_shader_multisample_interpolation")); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_shader_noperspective_interpolation")); + + constexpr char kVS[] = + R"(#version 300 es + #extension GL_OES_shader_multisample_interpolation : require + #extension GL_NV_shader_noperspective_interpolation : require + + noperspective sample out mediump float f; + void main() + { + f = 1.0; + gl_Position = vec4(f, 0.0, 0.0, 1.0); + })"; + + constexpr char kFS[] = + R"(#version 300 es + #extension GL_OES_shader_multisample_interpolation : require + #extension GL_NV_shader_noperspective_interpolation : require + + noperspective sample in mediump float f; + out mediump vec4 color; + void main() + { + color = vec4(f, 0.0, 0.0, 1.0); + })"; + + ANGLE_GL_PROGRAM(program, kVS, kFS); +} + // Test that a shader with sample in / sample out can be used successfully when the varying // precision is different between VS and FS. TEST_P(GLSLTest_ES31, VaryingSampleInAndOutDifferentPrecision) @@ -16169,6 +16309,24 @@ void main() ANGLE_GL_PROGRAM(testProgram, kVS, kFS); } +// Test that sample variables compile. +TEST_P(GLSLTest_ES3, SampleVariables) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_sample_variables")); + + const char kFS[] = R"(#version 300 es +#extension GL_OES_sample_variables : require +precision highp float; +out vec4 color; +void main() +{ + gl_SampleMask[0] = gl_SampleMaskIn[0] & 0x55555555; + color = vec4(gl_SamplePosition.yx, float(gl_SampleID), float(gl_MaxSamples + gl_NumSamples)); +})"; + + ANGLE_GL_PROGRAM(testProgram, essl3_shaders::vs::Simple(), kFS); +} + // Test that shader caching maintains uniforms across compute shader compilations. TEST_P(GLSLTest_ES31, ShaderCacheComputeWithUniform) { diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/InstancingTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/InstancingTest.cpp index 3c97958456c2..c01ca4dedd70 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/InstancingTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/InstancingTest.cpp @@ -804,6 +804,45 @@ TEST_P(InstancingTestES3, LargestDivisor) << "Vertex attrib divisor read was not the same that was passed in."; } +// Regression test for D3D11 streaming of GL_DYNAMIC_DRAW buffers not taking into account instanced +// attributes for buffer size calculations. http://crbug.com/1425606 +TEST_P(InstancingTestES3, D3D11StreamingInstancedData) +{ + constexpr char kVS[] = R"(#version 300 es +in float scale; +void main() +{ + gl_Position = vec4(vec2(gl_VertexID % 2, gl_VertexID % 3) * scale, 0, 1); +})"; + + constexpr char kFS[] = R"(#version 300 es +precision mediump float; +out vec4 color; +void main() +{ + color = vec4(1, 0, 0, 1); +})"; + + ANGLE_GL_PROGRAM(program, kVS, kFS); + glUseProgram(program); + + GLBuffer buffer; + float data = 0.5f; + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(data), &data, GL_DYNAMIC_DRAW); + + GLint loc = glGetAttribLocation(program, "scale"); + glEnableVertexAttribArray(loc); + glVertexAttribPointer(loc, 1, GL_FLOAT, false, 0, 0); + glVertexAttribDivisor(loc, 1); + + // Both of these should succeed + glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); + EXPECT_GL_NO_ERROR(); + glDrawArrays(GL_TRIANGLES, 0, 3); + EXPECT_GL_NO_ERROR(); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InstancingTestES3); ANGLE_INSTANTIATE_TEST_ES3(InstancingTestES3); diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultisampleTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultisampleTest.cpp index e86056d802c0..e045f11893b7 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultisampleTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultisampleTest.cpp @@ -1002,9 +1002,11 @@ ANGLE_INSTANTIATE_TEST_ES3_AND_ES31_AND(MultisampleTestES3, ES3_VULKAN().enable(Feature::EmulatedPrerotation180), ES3_VULKAN().enable(Feature::EmulatedPrerotation270)); -ANGLE_INSTANTIATE_TEST_ES3_AND(MultisampleResolveTest, - ES3_VULKAN().enable(Feature::EmulatedPrerotation90), - ES3_VULKAN().enable(Feature::EmulatedPrerotation180), - ES3_VULKAN().enable(Feature::EmulatedPrerotation270)); +ANGLE_INSTANTIATE_TEST_ES3_AND( + MultisampleResolveTest, + ES3_VULKAN().enable(Feature::EmulatedPrerotation90), + ES3_VULKAN().enable(Feature::EmulatedPrerotation180), + ES3_VULKAN().enable(Feature::EmulatedPrerotation270), + ES3_VULKAN().enable(Feature::PreferDrawClearOverVkCmdClearAttachments)); } // anonymous namespace diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultithreadingTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultithreadingTest.cpp index 15392a9dd67a..ca82e37d5d13 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultithreadingTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/MultithreadingTest.cpp @@ -1941,6 +1941,12 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority) { ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading()); + constexpr size_t kIterationCountMax = 10; + + const bool reduceLoad = isSwiftshader(); + const size_t iterationCount = reduceLoad ? 3 : kIterationCountMax; + const size_t heavyDrawCount = reduceLoad ? 25 : 100; + // Initialize contexts EGLWindow *window = getEGLWindow(); EGLDisplay dpy = window->getDisplay(); @@ -1987,8 +1993,6 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority) std::mutex mutex; std::condition_variable condVar; - constexpr size_t kIterationCount = 10; - enum class Step { Start, @@ -1996,7 +2000,7 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority) Thread1Init, Thread0Draw, Thread1Draw, - Finish = Thread0Draw + kIterationCount * 2, + Finish = Thread0Draw + kIterationCountMax * 2, Abort, }; Step currentStep = Step::Start; @@ -2040,11 +2044,11 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority) threadSynchronization.nextStep(Step::Thread0Init); ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Init)); - for (size_t i = 0; i < kIterationCount; ++i) + for (size_t i = 0; i < iterationCount; ++i) { // Simulate heavy work... glUniform4f(colorLocation, 0.0f, 0.0f, 0.0f, 0.0f); - for (int j = 0; j < 100; ++j) + for (size_t j = 0; j < heavyDrawCount; ++j) { drawQuad(colorProgram, essl1_shaders::PositionAttrib(), 0.5f); } @@ -2060,7 +2064,7 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority) // Notify second thread that draw is finished. threadSynchronization.nextStep(makeStep(Step::Thread0Draw, i)); ASSERT_TRUE(threadSynchronization.waitForStep( - (i == kIterationCount - 1) ? Step::Finish : makeStep(Step::Thread1Draw, i))); + (i == iterationCount - 1) ? Step::Finish : makeStep(Step::Thread1Draw, i))); } EXPECT_GL_NO_ERROR(); @@ -2089,7 +2093,7 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority) // Wait for first thread to draw using the shared texture. threadSynchronization.nextStep(Step::Thread1Init); - for (size_t i = 0; i < kIterationCount; ++i) + for (size_t i = 0; i < iterationCount; ++i) { ASSERT_TRUE(threadSynchronization.waitForStep(makeStep(Step::Thread0Draw, i))); @@ -2112,7 +2116,7 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority) thread0DrawSyncObj = nullptr; threadSynchronization.nextStep( - (i == kIterationCount - 1) ? Step::Finish : makeStep(Step::Thread1Draw, i)); + (i == iterationCount - 1) ? Step::Finish : makeStep(Step::Thread1Draw, i)); } EXPECT_GL_NO_ERROR(); @@ -2140,6 +2144,9 @@ TEST_P(MultithreadingTestES3, RenderThenSampleInNewContextWithDifferentPriority) ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading()); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_disjoint_timer_query")); + const bool reduceLoad = isSwiftshader(); + const size_t heavyDrawCount = reduceLoad ? 75 : 1000; + // Initialize contexts EGLWindow *window = getEGLWindow(); EGLDisplay dpy = window->getDisplay(); @@ -2246,7 +2253,7 @@ TEST_P(MultithreadingTestES3, RenderThenSampleInNewContextWithDifferentPriority) // Simulate heavy work... glUseProgram(redProgram); - for (int j = 0; j < 1000; ++j) + for (size_t j = 0; j < heavyDrawCount; ++j) { // Draw with Red color. drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f); @@ -2340,6 +2347,10 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriorityUsingEGLIm ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading()); ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension()); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image")); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_disjoint_timer_query")); + + const bool reduceLoad = isSwiftshader(); + const size_t heavyDrawCount = reduceLoad ? 75 : 1000; // Initialize contexts EGLWindow *window = getEGLWindow(); @@ -2427,21 +2438,40 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriorityUsingEGLIm ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green()); + ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue()); + + // Wait for second thread to finish initializing. + ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Init)); + + // Enable additive blend + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + + GLuint query; + glGenQueries(1, &query); + glBeginQuery(GL_TIME_ELAPSED_EXT, query); + ASSERT_GL_NO_ERROR(); // Simulate heavy work... glUseProgram(redProgram); - for (int j = 0; j < 1000; ++j) + for (size_t j = 0; j < heavyDrawCount; ++j) { + // Draw with Red color. drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f); } - // Draw with test color. + // Draw with Green color. glUseProgram(greenProgram); drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f); + + // This should force "flushToPrimary()" + glEndQuery(GL_TIME_ELAPSED_EXT); + glDeleteQueries(1, &query); ASSERT_GL_NO_ERROR(); - // Wait for second thread to finish initializing. - ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Init)); + // Continue draw with Blue color after flush... + glUseProgram(blueProgram); + drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f); sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr); EXPECT_NE(sync, EGL_NO_SYNC_KHR); @@ -2496,7 +2526,7 @@ TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriorityUsingEGLIm ASSERT_GL_NO_ERROR(); // Check test color in four corners. - GLColor color = GLColor::green; + GLColor color = GLColor::white; EXPECT_PIXEL_EQ(0, 0, color.R, color.G, color.B, color.A); EXPECT_PIXEL_EQ(0, kTexSize - 1, color.R, color.G, color.B, color.A); EXPECT_PIXEL_EQ(kTexSize - 1, 0, color.R, color.G, color.B, color.A); @@ -2534,6 +2564,12 @@ TEST_P(MultithreadingTestES3, ContextPriorityMixing) ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading()); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_disjoint_timer_query")); + constexpr size_t kIterationCountMax = 10; + + const bool reduceLoad = isSwiftshader(); + const size_t iterationCount = reduceLoad ? 3 : kIterationCountMax; + const size_t heavyDrawCount = reduceLoad ? 25 : 100; + // Initialize contexts EGLWindow *window = getEGLWindow(); EGLDisplay dpy = window->getDisplay(); @@ -2581,14 +2617,12 @@ TEST_P(MultithreadingTestES3, ContextPriorityMixing) std::mutex mutex; std::condition_variable condVar; - constexpr size_t kIterationCount = 10; - enum class Step { Start, Thread1DrawColor, Thread0Iterate, - Finish = Thread1DrawColor + kIterationCount * 2, + Finish = Thread1DrawColor + kIterationCountMax * 2, Abort, }; Step currentStep = Step::Start; @@ -2606,7 +2640,7 @@ TEST_P(MultithreadingTestES3, ContextPriorityMixing) ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); - for (size_t i = 0; i < kIterationCount; ++i) + for (size_t i = 0; i < iterationCount; ++i) { ASSERT_TRUE(threadSynchronization.waitForStep(makeStep(Step::Thread1DrawColor, i))); @@ -2661,7 +2695,7 @@ TEST_P(MultithreadingTestES3, ContextPriorityMixing) ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); - for (size_t i = 0; i < kIterationCount; ++i) + for (size_t i = 0; i < iterationCount; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glUseProgram(colorProgram); @@ -2673,7 +2707,7 @@ TEST_P(MultithreadingTestES3, ContextPriorityMixing) // Simulate heavy work... glUniform4f(colorLocation, 0.0f, 0.0f, 0.0f, 0.0f); - for (int j = 0; j < 100; ++j) + for (size_t j = 0; j < heavyDrawCount; ++j) { drawQuad(colorProgram, essl1_shaders::PositionAttrib(), 0.5f); } @@ -2727,6 +2761,232 @@ TEST_P(MultithreadingTestES3, ContextPriorityMixing) } } +// Test that it is possible to upload textures in one thread and use them in another with +// synchronization. +TEST_P(MultithreadingTestES3, MultithreadedTextureUploadAndDraw) +{ + ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading()); + + constexpr size_t kTexSize = 4; + GLTexture texture1; + GLTexture texture2; + std::vector textureColors1(kTexSize * kTexSize, GLColor::red); + std::vector textureColors2(kTexSize * kTexSize, GLColor::green); + + // Sync primitives + GLsync sync = nullptr; + std::mutex mutex; + std::condition_variable condVar; + + enum class Step + { + Start, + Thread0UploadFinish, + Finish, + Abort, + }; + Step currentStep = Step::Start; + + // Threads to upload and draw with textures. + auto thread0Upload = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) { + ThreadSynchronization threadSynchronization(¤tStep, &mutex, &condVar); + ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start)); + + EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context)); + + // Two mipmap textures are defined here. They are used for drawing in the other thread. + glBindTexture(GL_TEXTURE_2D, texture1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, + textureColors1.data()); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors1.data()); + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kTexSize / 4, kTexSize / 4, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors1.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, texture2); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, + textureColors2.data()); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors2.data()); + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kTexSize / 4, kTexSize / 4, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors2.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + // Create a sync object to be used for the draw thread. + sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + ASSERT_NE(sync, nullptr); + + threadSynchronization.nextStep(Step::Thread0UploadFinish); + ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish)); + }; + + auto thread1Draw = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) { + ThreadSynchronization threadSynchronization(¤tStep, &mutex, &condVar); + ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0UploadFinish)); + + EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context)); + + // Wait for the sync object to be signaled. + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + ASSERT_GL_NO_ERROR(); + + // Draw using the textures from the texture upload thread. + ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(), + essl1_shaders::fs::Texture2D()); + glUseProgram(textureProgram); + + glBindTexture(GL_TEXTURE_2D, texture1); + drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f); + glFlush(); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::red); + + glBindTexture(GL_TEXTURE_2D, texture2); + drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f); + glFlush(); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::green); + + threadSynchronization.nextStep(Step::Finish); + }; + + std::array threadFuncs = { + std::move(thread0Upload), + std::move(thread1Draw), + }; + + RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data()); + + ASSERT_NE(currentStep, Step::Abort); +} + +// Test that it is possible to create a new context after uploading mutable mipmap textures in the +// previous context, and use them in the new context. +TEST_P(MultithreadingTestES3, CreateNewContextAfterTextureUploadOnNewThread) +{ + ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading()); + + constexpr size_t kTexSize = 4; + GLTexture texture1; + GLTexture texture2; + std::vector textureColors1(kTexSize * kTexSize, GLColor::red); + std::vector textureColors2(kTexSize * kTexSize, GLColor::green); + + EGLWindow *window = getEGLWindow(); + EGLDisplay dpy = window->getDisplay(); + + std::thread thread = std::thread([&]() { + // Create a context and upload the textures. + EGLContext ctx1 = createMultithreadedContext(window, EGL_NO_CONTEXT); + EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx1)); + + glBindTexture(GL_TEXTURE_2D, texture1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, + textureColors1.data()); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors1.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, texture2); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, + textureColors2.data()); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors2.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + // Create a new context and use the uploaded textures. + EGLContext ctx2 = createMultithreadedContext(window, ctx1); + EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx2)); + + GLFramebuffer fbo; + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0); + EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::red); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0); + EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::green); + + // Destroy the contexts. + EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx2)); + EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx1)); + }); + + thread.join(); +} + +// Test that it is possible to create a new context after uploading mutable mipmap textures in the +// main thread, and use them in the new context. +TEST_P(MultithreadingTestES3, CreateNewContextAfterTextureUploadOnMainThread) +{ + ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading()); + + EGLWindow *window = getEGLWindow(); + EGLDisplay dpy = window->getDisplay(); + + // Upload the textures. + constexpr size_t kTexSize = 4; + GLTexture texture1; + GLTexture texture2; + std::vector textureColors1(kTexSize * kTexSize, GLColor::red); + std::vector textureColors2(kTexSize * kTexSize, GLColor::green); + + glBindTexture(GL_TEXTURE_2D, texture1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, + textureColors1.data()); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors1.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, texture2); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, + textureColors2.data()); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA, + GL_UNSIGNED_BYTE, textureColors2.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + std::thread thread = std::thread([&]() { + // Create a context. + EGLContext ctx1 = createMultithreadedContext(window, window->getContext()); + EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx1)); + + // Wait for the sync object to be signaled. + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + ASSERT_GL_NO_ERROR(); + + // Use the uploaded textures in the main thread. + GLFramebuffer fbo; + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0); + EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::red); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0); + EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::green); + + // Destroy the context. + EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx1)); + }); + + thread.join(); +} + ANGLE_INSTANTIATE_TEST( MultithreadingTest, ES2_OPENGL(), diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/PixelLocalStorageTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/PixelLocalStorageTest.cpp index 6bb5092a12e8..7e44dfe08514 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/PixelLocalStorageTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/PixelLocalStorageTest.cpp @@ -2469,6 +2469,104 @@ TEST_P(PixelLocalStorageTest, PLSWithSamplers) ASSERT_GL_NO_ERROR(); } +// Check the PLS interruption mechanism. +TEST_P(PixelLocalStorageTest, Interrupt) +{ + ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage")); + + PLSTestTexture t(GL_RGBA8); + PLSTestTexture u0(GL_R32UI); + PLSTestTexture u1(GL_R32UI); + PLSTestTexture u2(GL_R32UI); + + GLFramebuffer f; + glBindFramebuffer(GL_FRAMEBUFFER, f); + glFramebufferTexturePixelLocalStorageANGLE(0, t, 0, 0); + + GLFramebuffer g; + glBindFramebuffer(GL_FRAMEBUFFER, g); + glFramebufferTexturePixelLocalStorageANGLE(0, u0, 0, 0); + glFramebufferTexturePixelLocalStorageANGLE(1, u1, 0, 0); + glFramebufferTexturePixelLocalStorageANGLE(2, u2, 0, 0); + + glViewport(0, 0, W, H); + glDrawBuffers(0, nullptr); + + PLSProgram p; + p.compile(R"( + layout(binding=0, rgba8) uniform highp pixelLocalANGLE t; + void main() + { + pixelLocalStoreANGLE(t, color + pixelLocalLoadANGLE(t)); + })"); + + PLSProgram q; + q.compile(R"( + layout(binding=0, r32ui) uniform highp upixelLocalANGLE u0; + layout(binding=1, r32ui) uniform highp upixelLocalANGLE u1; + layout(binding=2, r32ui) uniform highp upixelLocalANGLE u2; + void main() + { + pixelLocalStoreANGLE(u0, (pixelLocalLoadANGLE(u1) << 8) | 0xau); + pixelLocalStoreANGLE(u1, (pixelLocalLoadANGLE(u2) << 8) | 0xbu); + pixelLocalStoreANGLE(u2, (pixelLocalLoadANGLE(u0) << 8) | 0xcu); + })"); + + // Interleave 2 PLS rendering passes. + glBindFramebuffer(GL_FRAMEBUFFER, f); + glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE})); + p.bind(); + p.drawBoxes({{{FULLSCREEN}, {1, 0, 0, 0}}}); + glFramebufferPixelLocalStorageInterruptANGLE(); + + glBindFramebuffer(GL_FRAMEBUFFER, g); + q.bind(); + glBeginPixelLocalStorageANGLE( + 3, GLenumArray({GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE, GL_LOAD_OP_ZERO_ANGLE})); + q.drawBoxes({{{FULLSCREEN}}}); + glFramebufferPixelLocalStorageInterruptANGLE(); + + p.bind(); + glBindFramebuffer(GL_FRAMEBUFFER, f); + glFramebufferPixelLocalStorageRestoreANGLE(); + p.drawBoxes({{{FULLSCREEN}, {0, 0, 0, 1}}}); + glFramebufferPixelLocalStorageInterruptANGLE(); + + glBindFramebuffer(GL_FRAMEBUFFER, g); + glFramebufferPixelLocalStorageRestoreANGLE(); + q.bind(); + q.drawBoxes({{{FULLSCREEN}}}); + glFramebufferPixelLocalStorageInterruptANGLE(); + + glBindFramebuffer(GL_FRAMEBUFFER, f); + glFramebufferPixelLocalStorageRestoreANGLE(); + p.bind(); + p.drawBoxes({{{FULLSCREEN}, {0, 0, 1, 0}}}); + glEndPixelLocalStorageANGLE(1, GLenumArray({GL_STORE_OP_STORE_ANGLE})); + + q.bind(); + glBindFramebuffer(GL_FRAMEBUFFER, g); + glFramebufferPixelLocalStorageRestoreANGLE(); + q.drawBoxes({{{FULLSCREEN}}}); + glEndPixelLocalStorageANGLE(3, GLenumArray({GL_STORE_OP_STORE_ANGLE, GL_STORE_OP_STORE_ANGLE, + GL_STORE_OP_STORE_ANGLE})); + + attachTextureToScratchFBO(t); + EXPECT_PIXEL_RECT_EQ(0, 0, W, H, GLColor(255, 0, 255, 255)); + ASSERT_GL_NO_ERROR(); + + attachTextureToScratchFBO(u0); + EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0x0a0c0b0a, 0, 0, 1)); + + attachTextureToScratchFBO(u1); + EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0x0b0a0c0b, 0, 0, 1)); + + attachTextureToScratchFBO(u2); + EXPECT_PIXEL_RECT32UI_EQ(0, 0, W, H, GLColor32UI(0x0c0b0a0c, 0, 0, 1)); + + ASSERT_GL_NO_ERROR(); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelLocalStorageTest); #define PLATFORM(API, BACKEND) API##_##BACKEND() #define PLS_INSTANTIATE_RENDERING_TEST_AND(TEST, API, ...) \ @@ -3019,6 +3117,16 @@ TEST_P(PixelLocalStorageValidationTest, FramebufferMemorylessPixelLocalStorageAN glBindFramebuffer(GL_FRAMEBUFFER, fbo); EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8I); + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // in an interrupted state. + EXPECT_GL_NO_ERROR(); + glFramebufferPixelLocalStorageInterruptANGLE(); + glFramebufferMemorylessPixelLocalStorageANGLE(0, GL_R32UI); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glFramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_FORMAT_ANGLE, GL_RGBA8I); + // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero. { PLSTestTexture tmp(GL_RGBA8); @@ -3141,6 +3249,17 @@ TEST_P(PixelLocalStorageValidationTest, FramebufferTexturePixelLocalStorageANGLE "Default framebuffer object name 0 does not support pixel local storage."); glBindFramebuffer(GL_FRAMEBUFFER, fbo); + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // in an interrupted state. + EXPECT_GL_NO_ERROR(); + glFramebufferTexturePixelLocalStorageANGLE(1, tex, 1, 0); + glFramebufferPixelLocalStorageInterruptANGLE(); + glFramebufferTexturePixelLocalStorageANGLE(1, 0, 0, 0); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glFramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, tex); + // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero. { PLSTestTexture tmp(GL_RGBA8); @@ -3326,6 +3445,29 @@ TEST_P(PixelLocalStorageValidationTest, glFramebufferPixelLocalClearValuesANGLE) GLFramebuffer fbo; glBindFramebuffer(GL_FRAMEBUFFER, fbo); + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // in an interrupted state. + glFramebufferPixelLocalStorageInterruptANGLE(); + + glFramebufferPixelLocalClearValuefvANGLE(0, ClearF(1, 1, 1, 1)); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + + glFramebufferPixelLocalClearValueivANGLE(1, ClearI(1, 1, 1, 1)); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + + glFramebufferPixelLocalClearValueuivANGLE(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, + ClearUI(1, 1, 1, 1)); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + + glFramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(0, ({0, 0, 0, 0})); + EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(1, ({0, 0, 0, 0})); + EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(MAX_PIXEL_LOCAL_STORAGE_PLANES - 1, ({0, 0, 0, 0})); + ASSERT_GL_NO_ERROR(); + // INVALID_VALUE is generated if < 0 or >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE. glFramebufferPixelLocalClearValuefvANGLE(-1, ClearF(0, 0, 0, 0)); EXPECT_GL_SINGLE_ERROR(GL_INVALID_VALUE); @@ -3395,6 +3537,17 @@ TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_context_stat GLFramebuffer fbo; glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // in an interrupted state. + glFramebufferPixelLocalStorageInterruptANGLE(); + glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE})); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glFramebufferPixelLocalStorageRestoreANGLE(); + ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0); + ASSERT_GL_NO_ERROR(); + PLSTestTexture pls0(GL_RGBA8, 100, 100); glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0); glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_LOAD_OP_ZERO_ANGLE})); @@ -3749,7 +3902,19 @@ TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_pls_planes) // Check that glEndPixelLocalStorageANGLE and glPixelLocalStorageBarrierANGLE validate as specified. TEST_P(PixelLocalStorageValidationTest, EndAndBarrierANGLE) { + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // in an interrupted state. + GLFramebuffer fbo; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + glFramebufferPixelLocalStorageInterruptANGLE(); + glEndPixelLocalStorageANGLE(0, nullptr); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glFramebufferPixelLocalStorageRestoreANGLE(); + ASSERT_GL_NO_ERROR(); + // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glEndPixelLocalStorageANGLE(0, nullptr); EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION); EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active."); @@ -3760,7 +3925,6 @@ TEST_P(PixelLocalStorageValidationTest, EndAndBarrierANGLE) EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage is not active."); ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0); - GLFramebuffer fbo; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); ASSERT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0); @@ -3862,6 +4026,71 @@ TEST_P(PixelLocalStorageValidationTest, EndAndBarrierANGLE) ASSERT_GL_NO_ERROR(); } +// Check that FramebufferPixelLocalStorageInterruptANGLE validates as specified. +TEST_P(PixelLocalStorageValidationTest, InterruptMechanism) +{ + // These commands are ignored when the default framebuffer object name 0 is bound. + glFramebufferPixelLocalStorageRestoreANGLE(); + glFramebufferPixelLocalStorageInterruptANGLE(); + glFramebufferPixelLocalStorageInterruptANGLE(); + glFramebufferPixelLocalStorageInterruptANGLE(); + glFramebufferPixelLocalStorageRestoreANGLE(); + glFramebufferPixelLocalStorageRestoreANGLE(); + glFramebufferPixelLocalStorageRestoreANGLE(); + glFramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_GL_NO_ERROR(); + + for (size_t i = 0; i < 256; ++i) + { + glFramebufferPixelLocalStorageInterruptANGLE(); + } + EXPECT_GL_NO_ERROR(); + + GLFramebuffer fbo; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // not in an interrupted state. + glFramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is not interrupted."); + + for (size_t i = 0; i < 255; ++i) + { + glFramebufferPixelLocalStorageInterruptANGLE(); + } + EXPECT_GL_NO_ERROR(); + + // INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt count on the draw + // framebuffer is greater than or equal to 255. + glFramebufferPixelLocalStorageInterruptANGLE(); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG( + "Pixel local storage does not support more than 255 nested interruptions."); + + for (size_t i = 0; i < 255; ++i) + { + glFramebufferPixelLocalStorageRestoreANGLE(); + } + EXPECT_GL_NO_ERROR(); + + glFramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is not interrupted."); + + glFramebufferPixelLocalStorageInterruptANGLE(); + glFramebufferPixelLocalStorageInterruptANGLE(); + ASSERT_GL_NO_ERROR(); + + glFramebufferPixelLocalStorageRestoreANGLE(); + glFramebufferPixelLocalStorageRestoreANGLE(); + ASSERT_GL_NO_ERROR(); + + glFramebufferPixelLocalStorageRestoreANGLE(); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is not interrupted."); +} + // Check that glGetFramebufferPixelLocalStorageParameter(f|i|ui)(Robust)?ANGLE validate as // specified. TEST_P(PixelLocalStorageValidationTest, GetFramebufferPixelLocalStorageParametersANGLE) @@ -3902,6 +4131,27 @@ TEST_P(PixelLocalStorageValidationTest, GetFramebufferPixelLocalStorageParameter GLFramebuffer fbo; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is + // in an interrupted state. + glFramebufferPixelLocalStorageInterruptANGLE(); + glGetFramebufferPixelLocalStorageParameterfvRobustANGLE( + 0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, &length, floats); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glGetFramebufferPixelLocalStorageParameterfvANGLE(0, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, + floats); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glGetFramebufferPixelLocalStorageParameterivRobustANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, 4, + &length, ints); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glGetFramebufferPixelLocalStorageParameterivANGLE(1, GL_PIXEL_LOCAL_FORMAT_ANGLE, ints); + EXPECT_GL_SINGLE_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); + EXPECT_GL_SINGLE_ERROR_MSG("Pixel local storage on the draw framebuffer is interrupted."); + glFramebufferPixelLocalStorageRestoreANGLE(); + ASSERT_GL_NO_ERROR(); + // INVALID_VALUE is generated if < 0 or >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE. glGetFramebufferPixelLocalStorageParameterfvRobustANGLE( -1, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, &length, floats); diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/SimpleOperationTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/SimpleOperationTest.cpp index 7ebdecf2c7ba..0fca35d80133 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/SimpleOperationTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/SimpleOperationTest.cpp @@ -1350,6 +1350,66 @@ TEST_P(SimpleOperationTest, DrawElementsZeroInstanceCountIsNoOp) } } +// Test that sample coverage does not affect single sample rendering +TEST_P(SimpleOperationTest, DrawSingleSampleWithCoverage) +{ + GLint sampleBuffers = -1; + glGetIntegerv(GL_SAMPLE_BUFFERS, &sampleBuffers); + ASSERT_EQ(sampleBuffers, 0); + + GLint samples = -1; + glGetIntegerv(GL_SAMPLES, &samples); + ASSERT_EQ(samples, 0); + + glClearColor(1.0, 0.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_SAMPLE_COVERAGE); + glSampleCoverage(0.0f, false); + + ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green()); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that sample coverage affects multi sample rendering with only one sample +TEST_P(SimpleOperationTest, DrawSingleMultiSampleWithCoverage) +{ + ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3); + + GLFramebuffer fbo; + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + GLRenderbuffer rbo; + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); + ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + + GLint samples = -1; + glGetIntegerv(GL_SAMPLES, &samples); + ASSERT_GT(samples, 0); + ANGLE_SKIP_TEST_IF(samples != 1); + + glClearColor(0.0, 0.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_SAMPLE_COVERAGE); + glSampleCoverage(0.0f, false); + + ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green()); + drawQuad(program, essl1_shaders::PositionAttrib(), 0.0); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); +} + // Use this to select which configurations (e.g. which renderer, which GLES major version) these // tests should be run against. ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND( diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/StateChangeTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/StateChangeTest.cpp index df2b32deb427..dac352ab859a 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/StateChangeTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/StateChangeTest.cpp @@ -10257,7 +10257,8 @@ ANGLE_INSTANTIATE_TEST_ES3_AND(StateChangeTestES3, ES3_VULKAN() .disable(Feature::SupportsExtendedDynamicState2) .disable(Feature::SupportsLogicOpDynamicState), - ES3_VULKAN().enable(Feature::ForceStaticVertexStrideState)); + ES3_VULKAN().enable(Feature::ForceStaticVertexStrideState), + ES3_VULKAN().enable(Feature::ForceStaticPrimitiveRestartState)); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StateChangeTestWebGL2); ANGLE_INSTANTIATE_TEST_COMBINE_1(StateChangeTestWebGL2, diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/TextureTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/TextureTest.cpp index 63ecde19249f..37ba5870a425 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/TextureTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/TextureTest.cpp @@ -2499,18 +2499,6 @@ TEST_P(Texture2DTest, TexStorage) // initialized the image with a default color. TEST_P(Texture2DTest, TexStorageWithPBO) { - // http://anglebug.com/4126 - ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL()); - - // http://anglebug.com/5081 - ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsOpenGL()); - - // http://anglebug.com/5651 - ANGLE_SKIP_TEST_IF(IsLinux() && IsNVIDIA() && IsOpenGL()); - - // http://anglebug.com/5097 - ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL() && IsTSan()); - if (getClientMajorVersion() < 3) { ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage")); @@ -2561,8 +2549,7 @@ TEST_P(Texture2DTest, TexStorageWithPBO) drawQuad(mProgram, "position", 0.5f); glDeleteBuffers(1, &pbo); EXPECT_GL_NO_ERROR(); - EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255); - EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255); + EXPECT_PIXEL_RECT_EQ(0, 0, width / 2, height / 2, GLColor(255, 0, 0, 255)); } // Test that glTexSubImage2D combined with a PBO works properly after deleting the PBO diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp index 3c90f5a28b82..91e94162d5e4 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp @@ -7196,6 +7196,37 @@ TEST_P(VulkanPerformanceCounterTest, FBOChangeAndBackDoesNotBreakRenderPass) EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); } +// Verify that changing framebuffer and issue a (nop or deferred) clear and change framebuffer back +// doesn't break the render pass. +TEST_P(VulkanPerformanceCounterTest, FBOChangeAndClearAndBackDoesNotBreakRenderPass) +{ + // switch to FBO and issue clear on fbo and then switch back to default framebuffer + GLFramebuffer framebuffer; + GLTexture texture; + setupForColorOpsTest(&framebuffer, &texture); + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // clear to green + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red()); + drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0); + + // switch to FBO and issue a deferred clear on fbo and then switch back to default framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glClear(GL_COLOR_BUFFER_BIT); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0); + + // Verify render pass count. + EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); +} + // This is test for optimization in vulkan backend. efootball_pes_2021 usage shows this usage // pattern and we expect implementation to reuse the storage for performance. TEST_P(VulkanPerformanceCounterTest, diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/WebGLCompatibilityTest.cpp index 0c2bc12ec911..e62c8fbe837c 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/WebGLCompatibilityTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/WebGLCompatibilityTest.cpp @@ -5283,8 +5283,8 @@ void main() constexpr char kVSArrayTooLarge[] = R"(varying vec4 color; -// 2 GB / 32 aligned bytes per mat2 = 67108864 -const int array_size = 67108865; +// 1 MB / 32 aligned bytes per mat2 = 32768 +const int array_size = 32769; void main() { mat2 array[array_size]; @@ -5296,7 +5296,7 @@ void main() constexpr char kVSArrayMuchTooLarge[] = R"(varying vec4 color; -const int array_size = 556007917; +const int array_size = 55600; void main() { mat2 array[array_size]; @@ -5856,6 +5856,27 @@ void main() { EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(42, 0, 0, 255), 1); } +// Regression test for syncing internal state for TexImage calls while there is an incomplete +// framebuffer bound +TEST_P(WebGL2CompatibilityTest, TexImageSyncWithIncompleteFramebufferBug) +{ + glColorMask(false, true, false, false); + glClear(GL_COLOR_BUFFER_BIT); + glViewport(100, 128, 65, 65537); + + GLFramebuffer fb1; + glBindFramebuffer(GL_FRAMEBUFFER, fb1); + + GLRenderbuffer rb; + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RG8UI, 1304, 2041); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb); + + GLTexture texture; + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 8, 8, 0, GL_RED_EXT, GL_UNSIGNED_BYTE, nullptr); +} + ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WebGLCompatibilityTest); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WebGL2CompatibilityTest); diff --git a/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/ConformanceTests.cpp b/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/ConformanceTests.cpp index 2441a099caef..0262c3a49280 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/ConformanceTests.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/ConformanceTests.cpp @@ -568,6 +568,3 @@ TEST_P(GLES1ConformanceTest, MatrixPalette) ANGLE_INSTANTIATE_TEST(GLES1ConformanceTest, ES1_OPENGL(), ES1_VULKAN()); } // namespace angle - -// Included here to fix a compile error due to white box tests using angle_end2end_tests_main. -void RegisterContextCompatibilityTests() {} diff --git a/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/CovglTests.cpp b/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/CovglTests.cpp index a9116627bad6..54a700b4b8b5 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/CovglTests.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/CovglTests.cpp @@ -599,6 +599,3 @@ TEST_P(GLES1CovglTest, ClipPlane) ANGLE_INSTANTIATE_TEST(GLES1CovglTest, ES1_OPENGL(), ES1_VULKAN()); } // namespace angle - -// Included here to fix a compile error due to white box tests using angle_end2end_tests_main. -void RegisterContextCompatibilityTests() {} diff --git a/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/PrimtestTests.cpp b/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/PrimtestTests.cpp index e11b02d6cec4..0a22bb971422 100644 --- a/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/PrimtestTests.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/gles1_conformance_tests/PrimtestTests.cpp @@ -161,6 +161,3 @@ TEST_P(GLES1PrimtestTest, Texture) ANGLE_INSTANTIATE_TEST(GLES1PrimtestTest, ES1_OPENGL(), ES1_VULKAN()); } // namespace angle - -// Included here to fix a compile error due to white box tests using angle_end2end_tests_main. -void RegisterContextCompatibilityTests() {} \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/src/tests/perf_tests/TracePerfTest.cpp b/Source/ThirdParty/ANGLE/src/tests/perf_tests/TracePerfTest.cpp index 679cd375608a..dc52b799981d 100644 --- a/Source/ThirdParty/ANGLE/src/tests/perf_tests/TracePerfTest.cpp +++ b/Source/ThirdParty/ANGLE/src/tests/perf_tests/TracePerfTest.cpp @@ -1143,7 +1143,8 @@ TracePerfTest::TracePerfTest(std::unique_ptr params) } if (traceNameIs("hill_climb_racing") || traceNameIs("dead_trigger_2") || - traceNameIs("disney_mirrorverse") || traceNameIs("cut_the_rope")) + traceNameIs("disney_mirrorverse") || traceNameIs("cut_the_rope") || + traceNameIs("geometry_dash")) { if (IsAndroid() && (IsPixel4() || IsPixel4XL()) && !mParams->isANGLE()) { diff --git a/Source/ThirdParty/ANGLE/src/tests/restricted_traces/README.md b/Source/ThirdParty/ANGLE/src/tests/restricted_traces/README.md index 8032e2d8da8e..6f5359454177 100644 --- a/Source/ThirdParty/ANGLE/src/tests/restricted_traces/README.md +++ b/Source/ThirdParty/ANGLE/src/tests/restricted_traces/README.md @@ -210,25 +210,22 @@ Allow the app to run until the `*angledata.gz` file is non-zero and no longer gr should continue rendering after that: ``` $ adb shell ls -s -w 1 /sdcard/Android/data/$PACKAGE_NAME/angle_capture -30528 angry_birds_2_capture_context1.angledata.gz - 8 angry_birds_2_capture_context1.cpp - 4 angry_birds_2_capture_context1_files.txt - 768 angry_birds_2_capture_context1_frame001.cpp - 100 angry_birds_2_capture_context1_frame002.cpp - 100 angry_birds_2_capture_context1_frame003.cpp - 100 angry_birds_2_capture_context1_frame004.cpp - 100 angry_birds_2_capture_context1_frame005.cpp - 104 angry_birds_2_capture_context1_frame006.cpp - 100 angry_birds_2_capture_context1_frame007.cpp - 100 angry_birds_2_capture_context1_frame008.cpp - 100 angry_birds_2_capture_context1_frame009.cpp - 100 angry_birds_2_capture_context1_frame010.cpp - 120 angry_birds_2_capture_context1_frame011.cpp - 8 angry_birds_2_capture_context1.h -``` -Note, you may see multiple contexts captured in the output. When this happens, look at the size of -the files. The larger files should be the context you care about it. You should move or delete the -other context files. +30528 angry_birds_2.angledata.gz + 8 angry_birds_2.cpp + 4 angry_birds_2.json + 768 angry_birds_2_001.cpp + 100 angry_birds_2_002.cpp + 100 angry_birds_2_003.cpp + 100 angry_birds_2_004.cpp + 100 angry_birds_2_005.cpp + 104 angry_birds_2_006.cpp + 100 angry_birds_2_007.cpp + 100 angry_birds_2_008.cpp + 100 angry_birds_2_009.cpp + 100 angry_birds_2_010.cpp + 120 angry_birds_2_011.cpp + 8 angry_birds_2.h +``` ## Pull the trace files diff --git a/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_trace_perf.py b/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_trace_perf.py index a464c86bdea8..e840982b2a93 100644 --- a/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_trace_perf.py +++ b/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_trace_perf.py @@ -570,7 +570,10 @@ def main(): parser.add_argument('-f', '--filter', help='Trace filter. Defaults to all.', default='*') parser.add_argument('-l', '--log', help='Logging level.', default=DEFAULT_LOG_LEVEL) parser.add_argument( - '--renderer', help='Which renderer to use: native, vulkan, or both.', default='both') + '--renderer', + help='Which renderer to use: native, vulkan (via ANGLE), or default (' + + 'GLES driver selected by system). Providing no option will run twice, native and vulkan', + default='both') parser.add_argument( '--walltimeonly', help='Limit output to just wall time', @@ -701,12 +704,21 @@ def main(): run_adb_command( 'shell settings put global angle_gl_driver_selection_pkgs com.android.angle.test') run_adb_command('shell settings put global angle_gl_driver_selection_values native') - else: + elif renderer == "vulkan": # Force the settings to ANGLE run_adb_command('shell settings put global angle_debug_package org.chromium.angle') run_adb_command( 'shell settings put global angle_gl_driver_selection_pkgs com.android.angle.test') run_adb_command('shell settings put global angle_gl_driver_selection_values angle') + elif renderer == "default": + logging.info('Deleting Android settings for forcing selection of GLES driver, ' + + 'allowing system to load the default') + run_adb_command('shell settings delete global angle_debug_package') + run_adb_command('shell settings delete global angle_gl_driver_selection_pkgs') + run_adb_command('shell settings delete global angle_gl_driver_selection_values') + else: + logging.error('Unsupported renderer {}'.format(renderer)) + exit() for i in range(int(args.loop_count)): print("\nStarting run %i with %s at %s\n" % diff --git a/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_traces.json b/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_traces.json index b4ff2f85d3d7..264b6d3eef4f 100644 --- a/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_traces.json +++ b/Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_traces.json @@ -87,12 +87,14 @@ "final_fantasy 5", "final_fantasy_brave_exvius 1", "fire_emblem_heroes 1", + "fishdom 1", "five_nights_at_freddys 1", "free_fire 5", "free_fire_max 1", "gacha_club 1", "gardenscapes 5", "genshin_impact 5", + "geometry_dash 1", "goddess_of_victory_nikke 1", "google_maps 5", "grimvalor 1", @@ -131,7 +133,8 @@ "marvel_strike_force 1", "merge_dragons 1", "messenger_lite 5", - "minecraft 5", + "minecraft 7", + "minecraft_bedrock 1", "minetest 2", "mini_block_craft 1", "mini_world 5", @@ -144,6 +147,7 @@ "my_talking_tom2 5", "my_talking_tom_friends 5", "nba2k20_800 5", + "new_legend_of_the_condor_heroes 1", "ni_no_kuni 1", "nier_reincarnation 5", "octopath_traveler 1", @@ -167,6 +171,7 @@ "real_gangster_crime 5", "real_racing3 1", "respawnables 1", + "rise_of_empires 1", "rise_of_kingdoms 5", "romancing_saga 5", "rope_hero_vice_town 5", @@ -213,6 +218,7 @@ "township 5", "trex_200 5", "uber 1", + "vainglory 1", "war_planet_online 1", "wayward_souls 1", "whatsapp 5", diff --git a/Source/ThirdParty/ANGLE/util/angle_features_autogen.cpp b/Source/ThirdParty/ANGLE/util/angle_features_autogen.cpp index 95b0e1fa4b6d..59373f90d260 100644 --- a/Source/ThirdParty/ANGLE/util/angle_features_autogen.cpp +++ b/Source/ThirdParty/ANGLE/util/angle_features_autogen.cpp @@ -39,10 +39,12 @@ constexpr PackedEnumMap kFeatureNames = {{ "allowTranslateUniformBlockToStructuredBuffer"}, {Feature::AlwaysCallUseProgramAfterLink, "alwaysCallUseProgramAfterLink"}, {Feature::AlwaysUnbindFramebufferTexture2D, "alwaysUnbindFramebufferTexture2D"}, + {Feature::AppendAliasedMemoryDecorationsToSsbo, "appendAliasedMemoryDecorationsToSsbo"}, {Feature::AsyncCommandBufferReset, "asyncCommandBufferReset"}, {Feature::AsyncCommandQueue, "asyncCommandQueue"}, {Feature::Avoid1BitAlphaTextureFormats, "avoid1BitAlphaTextureFormats"}, {Feature::AvoidStencilTextureSwizzle, "avoidStencilTextureSwizzle"}, + {Feature::BindFramebufferForTimerQueries, "bindFramebufferForTimerQueries"}, {Feature::BindTransformFeedbackBufferBeforeBindBufferRange, "bindTransformFeedbackBufferBeforeBindBufferRange"}, {Feature::BorderColorSrgb, "borderColorSrgb"}, @@ -147,6 +149,7 @@ constexpr PackedEnumMap kFeatureNames = {{ {Feature::ForceNearestMipFiltering, "forceNearestMipFiltering"}, {Feature::ForceNonCSBaseMipmapGeneration, "forceNonCSBaseMipmapGeneration"}, {Feature::ForceRobustResourceInit, "forceRobustResourceInit"}, + {Feature::ForceStaticPrimitiveRestartState, "forceStaticPrimitiveRestartState"}, {Feature::ForceStaticVertexStrideState, "forceStaticVertexStrideState"}, {Feature::ForceSubmitImmutableTextureUpdates, "forceSubmitImmutableTextureUpdates"}, {Feature::ForceTextureLodOffset1, "forceTextureLodOffset1"}, diff --git a/Source/ThirdParty/ANGLE/util/angle_features_autogen.h b/Source/ThirdParty/ANGLE/util/angle_features_autogen.h index fb035bc7cc67..6daa64ec8a54 100644 --- a/Source/ThirdParty/ANGLE/util/angle_features_autogen.h +++ b/Source/ThirdParty/ANGLE/util/angle_features_autogen.h @@ -38,10 +38,12 @@ enum class Feature AllowTranslateUniformBlockToStructuredBuffer, AlwaysCallUseProgramAfterLink, AlwaysUnbindFramebufferTexture2D, + AppendAliasedMemoryDecorationsToSsbo, AsyncCommandBufferReset, AsyncCommandQueue, Avoid1BitAlphaTextureFormats, AvoidStencilTextureSwizzle, + BindFramebufferForTimerQueries, BindTransformFeedbackBufferBeforeBindBufferRange, BorderColorSrgb, BottomLeftOriginPresentRegionRectangles, @@ -140,6 +142,7 @@ enum class Feature ForceNearestMipFiltering, ForceNonCSBaseMipmapGeneration, ForceRobustResourceInit, + ForceStaticPrimitiveRestartState, ForceStaticVertexStrideState, ForceSubmitImmutableTextureUpdates, ForceTextureLodOffset1, diff --git a/Source/ThirdParty/ANGLE/util/capture/frame_capture_replay_autogen.cpp b/Source/ThirdParty/ANGLE/util/capture/frame_capture_replay_autogen.cpp index d90ca17376e4..7df0be6b694d 100644 --- a/Source/ThirdParty/ANGLE/util/capture/frame_capture_replay_autogen.cpp +++ b/Source/ThirdParty/ANGLE/util/capture/frame_capture_replay_autogen.cpp @@ -1008,6 +1008,12 @@ void ReplayTraceFunctionCall(const CallCapture &call, const TraceFunctionMap &cu glFramebufferPixelLocalClearValueuivANGLE(captures[0].value.GLintVal, captures[1].value.GLuintConstPointerVal); break; + case angle::EntryPoint::GLFramebufferPixelLocalStorageInterruptANGLE: + glFramebufferPixelLocalStorageInterruptANGLE(); + break; + case angle::EntryPoint::GLFramebufferPixelLocalStorageRestoreANGLE: + glFramebufferPixelLocalStorageRestoreANGLE(); + break; case angle::EntryPoint::GLFramebufferRenderbuffer: glFramebufferRenderbuffer(captures[0].value.GLenumVal, captures[1].value.GLenumVal, captures[2].value.GLenumVal, diff --git a/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.cpp b/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.cpp index 8339c7435464..895977994168 100644 --- a/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.cpp +++ b/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.cpp @@ -607,6 +607,10 @@ ANGLE_TRACE_LOADER_EXPORT PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEIVANGLEPROC t_glFramebufferPixelLocalClearValueivANGLE; ANGLE_TRACE_LOADER_EXPORT PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC t_glFramebufferPixelLocalClearValueuivANGLE; +ANGLE_TRACE_LOADER_EXPORT PFNGLFRAMEBUFFERPIXELLOCALSTORAGEINTERRUPTANGLEPROC + t_glFramebufferPixelLocalStorageInterruptANGLE; +ANGLE_TRACE_LOADER_EXPORT PFNGLFRAMEBUFFERPIXELLOCALSTORAGERESTOREANGLEPROC + t_glFramebufferPixelLocalStorageRestoreANGLE; ANGLE_TRACE_LOADER_EXPORT PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC t_glFramebufferTexturePixelLocalStorageANGLE; ANGLE_TRACE_LOADER_EXPORT PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC @@ -1786,6 +1790,12 @@ void LoadTraceGLES(LoadProc loadProc) t_glFramebufferPixelLocalClearValueuivANGLE = reinterpret_cast( loadProc("glFramebufferPixelLocalClearValueuivANGLE")); + t_glFramebufferPixelLocalStorageInterruptANGLE = + reinterpret_cast( + loadProc("glFramebufferPixelLocalStorageInterruptANGLE")); + t_glFramebufferPixelLocalStorageRestoreANGLE = + reinterpret_cast( + loadProc("glFramebufferPixelLocalStorageRestoreANGLE")); t_glFramebufferTexturePixelLocalStorageANGLE = reinterpret_cast( loadProc("glFramebufferTexturePixelLocalStorageANGLE")); diff --git a/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.h b/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.h index 35543acacd32..23ef1286b059 100644 --- a/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.h +++ b/Source/ThirdParty/ANGLE/util/capture/trace_gles_loader_autogen.h @@ -576,6 +576,8 @@ #define glFramebufferPixelLocalClearValuefvANGLE t_glFramebufferPixelLocalClearValuefvANGLE #define glFramebufferPixelLocalClearValueivANGLE t_glFramebufferPixelLocalClearValueivANGLE #define glFramebufferPixelLocalClearValueuivANGLE t_glFramebufferPixelLocalClearValueuivANGLE +#define glFramebufferPixelLocalStorageInterruptANGLE t_glFramebufferPixelLocalStorageInterruptANGLE +#define glFramebufferPixelLocalStorageRestoreANGLE t_glFramebufferPixelLocalStorageRestoreANGLE #define glFramebufferTexturePixelLocalStorageANGLE t_glFramebufferTexturePixelLocalStorageANGLE #define glGetFramebufferPixelLocalStorageParameterfvANGLE \ t_glGetFramebufferPixelLocalStorageParameterfvANGLE @@ -1473,6 +1475,10 @@ ANGLE_TRACE_LOADER_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEIVANGLEPROC t_glFramebufferPixelLocalClearValueivANGLE; ANGLE_TRACE_LOADER_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC t_glFramebufferPixelLocalClearValueuivANGLE; +ANGLE_TRACE_LOADER_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALSTORAGEINTERRUPTANGLEPROC + t_glFramebufferPixelLocalStorageInterruptANGLE; +ANGLE_TRACE_LOADER_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALSTORAGERESTOREANGLEPROC + t_glFramebufferPixelLocalStorageRestoreANGLE; ANGLE_TRACE_LOADER_EXPORT extern PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC t_glFramebufferTexturePixelLocalStorageANGLE; ANGLE_TRACE_LOADER_EXPORT extern PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC diff --git a/Source/ThirdParty/ANGLE/util/capture/trace_interpreter_autogen.cpp b/Source/ThirdParty/ANGLE/util/capture/trace_interpreter_autogen.cpp index 953c72d57c5b..498b33ffb9ee 100644 --- a/Source/ThirdParty/ANGLE/util/capture/trace_interpreter_autogen.cpp +++ b/Source/ThirdParty/ANGLE/util/capture/trace_interpreter_autogen.cpp @@ -2206,6 +2206,22 @@ CallCapture ParseCallCapture(const Token &nameToken, return CallCapture(EntryPoint::GLFramebufferPixelLocalClearValueuivANGLE, std::move(params)); } + if (strcmp(nameToken, "glFramebufferPixelLocalStorageInterruptANGLE") == 0) + { + ParamBuffer params = ParseParameters< + std::remove_pointer::type>( + paramTokens, strings); + return CallCapture(EntryPoint::GLFramebufferPixelLocalStorageInterruptANGLE, + std::move(params)); + } + if (strcmp(nameToken, "glFramebufferPixelLocalStorageRestoreANGLE") == 0) + { + ParamBuffer params = ParseParameters< + std::remove_pointer::type>( + paramTokens, strings); + return CallCapture(EntryPoint::GLFramebufferPixelLocalStorageRestoreANGLE, + std::move(params)); + } if (strcmp(nameToken, "glFramebufferRenderbuffer") == 0) { ParamBuffer params = diff --git a/Source/ThirdParty/ANGLE/util/gles_loader_autogen.cpp b/Source/ThirdParty/ANGLE/util/gles_loader_autogen.cpp index 9711aa9b8380..bbae8102bd10 100644 --- a/Source/ThirdParty/ANGLE/util/gles_loader_autogen.cpp +++ b/Source/ThirdParty/ANGLE/util/gles_loader_autogen.cpp @@ -585,6 +585,10 @@ ANGLE_UTIL_EXPORT PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEIVANGLEPROC l_glFramebufferPixelLocalClearValueivANGLE; ANGLE_UTIL_EXPORT PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC l_glFramebufferPixelLocalClearValueuivANGLE; +ANGLE_UTIL_EXPORT PFNGLFRAMEBUFFERPIXELLOCALSTORAGEINTERRUPTANGLEPROC + l_glFramebufferPixelLocalStorageInterruptANGLE; +ANGLE_UTIL_EXPORT PFNGLFRAMEBUFFERPIXELLOCALSTORAGERESTOREANGLEPROC + l_glFramebufferPixelLocalStorageRestoreANGLE; ANGLE_UTIL_EXPORT PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC l_glFramebufferTexturePixelLocalStorageANGLE; ANGLE_UTIL_EXPORT PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC @@ -1755,6 +1759,12 @@ void LoadUtilGLES(LoadProc loadProc) l_glFramebufferPixelLocalClearValueuivANGLE = reinterpret_cast( loadProc("glFramebufferPixelLocalClearValueuivANGLE")); + l_glFramebufferPixelLocalStorageInterruptANGLE = + reinterpret_cast( + loadProc("glFramebufferPixelLocalStorageInterruptANGLE")); + l_glFramebufferPixelLocalStorageRestoreANGLE = + reinterpret_cast( + loadProc("glFramebufferPixelLocalStorageRestoreANGLE")); l_glFramebufferTexturePixelLocalStorageANGLE = reinterpret_cast( loadProc("glFramebufferTexturePixelLocalStorageANGLE")); diff --git a/Source/ThirdParty/ANGLE/util/gles_loader_autogen.h b/Source/ThirdParty/ANGLE/util/gles_loader_autogen.h index 05ba33654cf0..5671c7cbe259 100644 --- a/Source/ThirdParty/ANGLE/util/gles_loader_autogen.h +++ b/Source/ThirdParty/ANGLE/util/gles_loader_autogen.h @@ -576,6 +576,8 @@ #define glFramebufferPixelLocalClearValuefvANGLE l_glFramebufferPixelLocalClearValuefvANGLE #define glFramebufferPixelLocalClearValueivANGLE l_glFramebufferPixelLocalClearValueivANGLE #define glFramebufferPixelLocalClearValueuivANGLE l_glFramebufferPixelLocalClearValueuivANGLE +#define glFramebufferPixelLocalStorageInterruptANGLE l_glFramebufferPixelLocalStorageInterruptANGLE +#define glFramebufferPixelLocalStorageRestoreANGLE l_glFramebufferPixelLocalStorageRestoreANGLE #define glFramebufferTexturePixelLocalStorageANGLE l_glFramebufferTexturePixelLocalStorageANGLE #define glGetFramebufferPixelLocalStorageParameterfvANGLE \ l_glGetFramebufferPixelLocalStorageParameterfvANGLE @@ -1441,6 +1443,10 @@ ANGLE_UTIL_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEIVANGLEPROC l_glFramebufferPixelLocalClearValueivANGLE; ANGLE_UTIL_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC l_glFramebufferPixelLocalClearValueuivANGLE; +ANGLE_UTIL_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALSTORAGEINTERRUPTANGLEPROC + l_glFramebufferPixelLocalStorageInterruptANGLE; +ANGLE_UTIL_EXPORT extern PFNGLFRAMEBUFFERPIXELLOCALSTORAGERESTOREANGLEPROC + l_glFramebufferPixelLocalStorageRestoreANGLE; ANGLE_UTIL_EXPORT extern PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC l_glFramebufferTexturePixelLocalStorageANGLE; ANGLE_UTIL_EXPORT extern PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC